有没有一种简单的方法可以在容器中存储两个不同类型的对象?

时间:2016-10-20 03:57:26

标签: swift sprite-kit

我正在尝试将SKCameraNode放置在场景中多个对象的中心。我正在考虑将所有感兴趣的对象放入某种容器中,然后计算每次更新的质心()。我有两个类,Ball和Car,继承自PhysicalObject,继承自SKSpriteNode。我想做的是像

var cameraObjects: Array<Ball, Car>!
...
var ball1 = Ball()
var car1 = Car()
cameraObjects.append(ball1)
cameraObjects.append(car1)
...
// Loop through objects and calculate centroid

但是这会在第一个追加()时崩溃。

请注意,我不想为每个类创建一个伪协议,如here所述。有一种简单的方法可以做到这一点吗?

PhysicalObject.swift

import SpriteKit

class PhysicalObject: SKSpriteNode {

    var objectMass: CGFloat!

    override init(texture: SKTexture!, color: UIColor, size: CGSize) {
        super.init(texture: texture, color: color, size: size)
        self.name = "physicalObject"

        //Physics setup
        physicsBody?.usesPreciseCollisionDetection = true
        physicsBody?.affectedByGravity = true

    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

}

Ball.swift

import SpriteKit

class Ball: PhysicalObject {

    let MAXBALLSPEED :CGFloat = 0.08

    init(spawnPosition: CGPoint) {

        /* Temporary initialization.. will have further customization for different classes */
        let ballTexture = SKTexture(imageNamed: "ball")
        let ballRadius = CGFloat(50)
        let ballSize = CGSize(width: ballRadius, height: ballRadius)

        super.init(texture: ballTexture, color: UIColor.clear, size: ballSize)

        self.position = spawnPosition

        self.name = "ball"

        //Physics Setup
        //self.physicsBody = SKPhysicsBody(edgeLoopFromRect: CGRect(origin: spawnPosition, size: carSize) )
        self.physicsBody = SKPhysicsBody(circleOfRadius: self.size.height/2)
        self.objectMass = CGFloat(0.005)
        physicsBody?.isDynamic = true // Default is true
        physicsBody?.restitution = 1.0


        self.physicsBody?.categoryBitMask = PhysicsCategory.Ball
        self.physicsBody?.contactTestBitMask = PhysicsCategory.Boards | PhysicsCategory.Car


    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

Car.swift

import SpriteKit

class Car: PhysicalObject {

    let MAXCARSPEED: CGFloat = 500
    var steering: Bool
    var diagonalLength: CGFloat

    init(spawnPosition: CGPoint) {

        /* Temporary initialization.. will have further customization for different classes of cars */
        let carTexture = SKTexture(imageNamed: "BasicCar")
        let carWidth = CGFloat(screenSize.width/20)
        let carScale = CGFloat(183.0/140.0)
        let carSize = CGSize(width: (carWidth*carScale), height: carWidth)

        // Initialize movement variables
        self.steering = false
        self.diagonalLength = hypot(carSize.width, carSize.height)

        //self.steerRight = false
        //self.steerLeft = false

        super.init(texture: carTexture, color: UIColor.clear, size: carSize)


        self.speed = CGFloat(MAXCARSPEED)
        self.position = spawnPosition
        self.name = "car"

        //Physics Setup
        //self.physicsBody = SKPhysicsBody(edgeLoopFromRect: CGRect(origin: spawnPosition, size: carSize) )
        let carPhysicsSize = CGSize(width: self.size.width, height: self.size.height)
        self.physicsBody = SKPhysicsBody(rectangleOf: carPhysicsSize)
        self.objectMass = CGFloat(2000)
        self.physicsBody?.friction = 0.5
        self.physicsBody?.angularDamping = 1.0
        self.physicsBody?.linearDamping = 1.0
        self.physicsBody?.restitution = 1.0
        physicsBody?.isDynamic = true // Default is true


        self.physicsBody?.categoryBitMask = PhysicsCategory.Car
        self.physicsBody?.contactTestBitMask = PhysicsCategory.Car | PhysicsCategory.Ball


    }


    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

3 个答案:

答案 0 :(得分:1)

您可以制作Array<PhysicalObject>(a.k.a。[PhysicalObject]),它可以存储Ball个对象和Car个对象。

答案 1 :(得分:1)

您可能会发现enumerateChildNodes SKNode方法是枚举具有特定名称的所有对象的更好方法。这样,您就不需要自己管理阵列了。

看看Apple's documentation

答案 2 :(得分:1)

您需要做的就是将您想要与摄像机相关的所有对象放入新的父SKNode中,并使用calculateAccumulatedFrame获取所有节点周围的帧,然后只使用父节点的中心帧。