如何在屏幕上添加新的SKSpriteNodes并将其动画与现有对象同步?

时间:2014-09-18 10:11:50

标签: swift sprite-kit skspritenode skaction

我正在尝试使用单个SKSpriteNode为同一类型的多个SKAction制作动画。

我想要做的是在屏幕上显示四个相同类型的SKSpriteNode。 然后在按下按钮时将它们全部设置为动画,然后将它们移动到左侧。 只要第一个SKSpriteNode离开屏幕,我就想在右侧的屏幕位置添加另一个SKSpriteNode并将其添加到此SKAction循环中。

下面的图片详细显示了我的目标。

enter image description here

到目前为止,我能够在屏幕上显示四个相同类型的SKSpriteNode并将它们添加到数组中。

    var squareBox = SKSpriteNode()

    func addSquares(size:CGSize){

    for var i = 0; i < 4; i++ {

        // Create a new sprite node from an image
        squareBox = SKSpriteNode(imageNamed: "noBox")

        // Square pysics settings
        squareBox.physicsBody = SKPhysicsBody(rectangleOfSize: self.squareBox.frame.size)
        squareBox.physicsBody!.dynamic = false
        squareBox.physicsBody!.categoryBitMask = squareBoxCategory
        squareBox.physicsBody!.contactTestBitMask = leftEdgeCategory | edgeCategory

        // SquareBox positioning on X
        var xPos = size.width/5 + squareBox.size.height/2
        var xPosInt = Int(xPos) * (i + 1)
        xPos = CGFloat(xPosInt)
        var yPos = size.height/2 + (squareBox.size.height/2)

        squareBox.position = CGPointMake(xPos - squareBox.size.height/2, yPos)

        self.addChild(squareBox)
        squareArray.append(squareBox)

    }

}

我不确定这是否是为相同类型的四个SKSpriteNode设置动画的正确方法,但是当按下按钮时,它们似乎都会根据需要向左移动。

    override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
    for touch: AnyObject in touches {
        let location = touch.locationInNode(self)
        self.nodeAtPoint(location)
        if self.nodeAtPoint(location) == self.button {

            let move = SKAction.moveByX(-size.width/5 - squareBox.size.height/2, y: 0, duration: 1)

            print("button clicked!")

            for box in squareArray {
                box.runAction(move)
            }
        }
    }
}

我在屏幕左边创建了一条不可见的1px线,用于定义第一个SKSpriteNode离开屏幕的时间。

    func addLeftEdge(size:CGSize){

    let leftEdge = SKNode()
    leftEdge.physicsBody = SKPhysicsBody(edgeFromPoint: CGPointMake(1, 1), toPoint: CGPointMake(1, size.height))
    leftEdge.physicsBody!.categoryBitMask = leftEdgeCategory

    self.addChild(leftEdge)
}

这种方法存在的问题是,当我为它们设置动画时,数组中的SKSpriteNode在触及1px线时不会在didBeginContact上做出响应。

    func didBeginContact(contact: SKPhysicsContact) {

    println("contact!")

}

最后,我希望能够将Force应用于屏幕上的所有SKSpriteNode几秒钟,然后将它们移动到左侧,然后降低力的速度,直到他们都停下来了。我的想法是创建四个相同类型的对象并将它们添加到屏幕+将它们添加到数组var squareArray = [SKSpriteNode]()。 然后,当第一个SKSpriteNode离开屏幕时,我会将其从数组中删除,然后在最后再添加它,并将其从右侧的屏幕上移开,这样它就会以无缝动画移动。

我觉得我的整个方法都是错误的。

请告知如何实现我的目标,为多个SKSpriteNode制作动画的最佳方法是什么,如上所述。我是在正确的轨道上吗?

请帮助,谢谢。

2 个答案:

答案 0 :(得分:0)

为了检测联系人,其中一个SKSpriteNodes必须具有physicsBody.Dynamic= YES;

既然你不想动态,我找到了一个快速修复:

leftEdge.physicsBody.Dynamic=YES; //This allows it to enter onContact
leftEdge.physicsBody.collisionBitMask=0; //Disables edge from being moved by collision
leftEdge.physicsBody.AffectedByGravity=NO; //Prevents any in game gravity from moving the edge

这允许你有一个动态的边缘并且可以触发onContact但是边缘仍然会像它不是动态的那样。

答案 1 :(得分:0)

我认为这个解决方案不是很干净,需要的代码比获得此效果所需的代码多得多。在update()函数中,因为只有4或5个框,为什么不简单地遍历对象并检查它们的frame的{​​{1}}是否小于0以及是否他们将它们重置为起始点,我假设它是minX,因为它完全在屏幕外。这样就没有数组操作,因为你不必删除对象并将对象追加到数组中。此外,您无需附加不需要的physicsBody。而且你不需要leftEdge