Performing actions in order (not asynchronously) on different nodes

Here is an illustration of what I'm trying to do:

enter image description here

Here is my code:

import SpriteKit

class GameScene: SKScene {
    let mySquare1 = SKShapeNode(rectOfSize:CGSize(width: 50, height: 50))
    let mySquare2 = SKShapeNode(rectOfSize:CGSize(width: 50, height: 50))

    override func didMoveToView(view: SKView) {
        mySquare1.position = CGPoint(x: 100, y:100)
        mySquare2.position = CGPoint(x: 300, y:100)

        mySquare1.fillColor = SKColor.blueColor()
        mySquare2.fillColor = SKColor.blueColor()

        self.addChild(mySquare1)
        self.addChild(mySquare2)

        let moveAction1 = SKAction.moveTo(CGPoint(x:250, y:100), duration: 1)
        mySquare1.runAction(moveAction1)

        let moveAction2 = SKAction.moveTo(CGPoint(x:300, y:350), duration: 1)
        mySquare2.runAction(moveAction2)
    }

    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {

    }

    override func update(currentTime: CFTimeInterval) {

    }
}

My problem is that I am trying to move the rectangles synchronously (not asynchronously). That is, I want my first rectangle to start moving, stop moving, stop. And then, start my second rectangle, complete its movement and stop.

What is currently happening is that when I launch my program, they both start moving at the same time.

I also found SKAction.sequencefor actions to play in order, however I can only use this for actions on the same object. Not in different objects, as in my example.

+4
source share
3

( ), completion , (apple docs):

import SpriteKit
class GameScene: SKScene {
    let mySquare1 = SKShapeNode(rectOfSize:CGSize(width: 50, height: 50))
    let mySquare2 = SKShapeNode(rectOfSize:CGSize(width: 50, height: 50))
    override func didMoveToView(view: SKView) {
        mySquare1.position = CGPoint(x: 100, y:100)
        mySquare2.position = CGPoint(x: 300, y:100)
        mySquare1.fillColor = SKColor.blueColor()
        mySquare2.fillColor = SKColor.blueColor()
        self.addChild(mySquare1)
        self.addChild(mySquare2)
        let move1 = SKAction.moveToX(250, duration: 1.0)
        let move2 = SKAction.moveToY(250, duration: 1.0)
        self.mySquare1.runAction(move1,completion: {
            self.mySquare2.runAction(move2)
        })
    }
}
+5

SKAction . .

:

func example() {
    let firstRectMove = SKAction.runBlock({
        let move1 = SKAction.moveToX(20, duration: 1.0)
        let move2 = SKAction.moveToY(20, duration: 1.0)
        rec1.runAction(SKAction.sequence([move1,move2]))
    })
    let actionWait = SKAction.waitForDuration(2.0)
    let secondRectMove = SKAction.runBlock({

        let move1 = SKAction.moveToX(20, duration: 1.0)
        let move2 = SKAction.moveToY(20, duration: 1.0)
        rec2.runAction(SKAction.sequence([move1,move2]))
    })
    //self is an SKScene or any other node really...
    self.runAction(SKAction.sequence([firstRectMove,actionWait,secondRectMove]))
}
+4

, - , . , doom, .

"" , :

func runInSequence(actions:[(node:SKNode,action:SKAction)], index:Int) {
    if index < actions.count {
        let node = actions[index].node
        let action = actions[index].action
        node.runAction(action) {
            // Avoid retain cycle
            [weak self] in
            self?.runInSequence(actions, index: index+1)
        }
    }
}

To use this, define / create an array that stores the nodes and actions that you want to perform sequentially, and call the method with the start index:

    let nodesAndActions:[(node:SKNode,action:SKAction)] = [
        (mySquare1,moveAction1),
        (mySquare2,moveAction2)
    ]
    runInSequence(nodesAndActions, index: 0)
+3
source

Source: https://habr.com/ru/post/1652778/


All Articles