0
votes

I am having an issue with an SKAction sequence I set up.

The goal of this sequence is to take an array of 9 sprite nodes and display one at a time. This sequence will then show the node to the right or to the left of the current node depending on which button is pressed (right button or left button).

I am experiencing something interesting here. It seems to work as it is now, but if I press button left or button right multiple times fast, it seems like it cannot keep up and the process fails. I don't get an error, the sprite nodes just don't display or don't display correctly.

I have attached my code below. Because it is working when I cycle through slowly, I believe it is a timing issue and maybe I need to add a completion block. I tried doing this but was unsuccessful.

My question is, does anything obvious stick out that looks wrong here and do you think a completion block could possibly solve the issue?

func pressedButtonRight(){
    if currentDisplayedWorld < 8 {
        var currentWorld:SKSpriteNode = worldArray[currentDisplayedWorld] as SKSpriteNode
        var nextWorld:SKSpriteNode = worldArray[currentDisplayedWorld + 1] as SKSpriteNode
        nextWorld.position = CGPointMake(self.frame.size.width, 50)
        self.addChild(nextWorld)

        let move = SKAction.moveByX(-self.frame.size.width, y: 0,
            duration: 1.0, delay: 0,
            usingSpringWithDamping: 0.7, initialSpringVelocity: 0.5)

        //currentWorld.runAction(move)
        nextWorld.runAction(move)
        currentWorld.removeFromParent()

        currentDisplayedWorld++
    }else if currentDisplayedWorld == 8 {

    }
}

func pressedButtonLeft(){
    if currentDisplayedWorld > 0 {
        var currentWorld:SKSpriteNode = worldArray[currentDisplayedWorld] as SKSpriteNode
        var previousWorld:SKSpriteNode = worldArray[currentDisplayedWorld - 1] as SKSpriteNode
        previousWorld.position = CGPointMake(-self.frame.size.width, 50)

        self.addChild(previousWorld)

        let moveBack = SKAction.moveByX(self.frame.size.width, y: 0,
            duration: 1.0, delay: 0,
            usingSpringWithDamping: 0.7, initialSpringVelocity: 0.5)

        //currentWorld.runAction(moveBack)
        previousWorld.runAction(moveBack)
        currentWorld.removeFromParent()

        currentDisplayedWorld--
    }else if currentDisplayedWorld == 0 {

    }
}
1
have a class property boolean called moving. only move the nodes if moving is false. before you move the nodes set moving to true. run the move action on the node with a completion handler which sets moving to false again.user4233369
So the code doesn't actually stop any already-running action. If you press the button quickly, you may have several move actions running simultaneously. The behavior of that is undefined. Run the actions "with key" so that running the action automatically stops any other actions already running that have the same key.LearnCocos2D
Ok that makes sense. I will try this today and let you know if it worked out. Thanks.Andrew Mertz

1 Answers

0
votes

Worked out perfect. I posted my final code below for all to see. Thanks again for the help.

    func pressedButtonRight(){
    if currentDisplayedWorld < 8 {

        if self.moving == false {
            self.moving = true

            var currentWorld:SKSpriteNode = self.worldArray[currentDisplayedWorld] as SKSpriteNode
            var nextWorld:SKSpriteNode = self.worldArray[currentDisplayedWorld + 1] as SKSpriteNode
            nextWorld.position = CGPointMake(self.frame.size.width, 50)

            self.addChild(nextWorld)

            let move = SKAction.moveByX(-self.frame.size.width, y: 0, duration: 1.0, delay: 0,usingSpringWithDamping: 0.7, initialSpringVelocity: 0.5)

            //currentWorld.runAction(move)
            nextWorld.runAction(move, completion: {
                self.moving = false
            })
            currentWorld.removeFromParent()
            currentDisplayedWorld++
        }

    }else if currentDisplayedWorld == 8 {

    }
}

func pressedButtonLeft(){
    if currentDisplayedWorld > 0 {

        if self.moving == false {
            self.moving = true

            var currentWorld:SKSpriteNode = self.worldArray[currentDisplayedWorld] as SKSpriteNode
            var previousWorld:SKSpriteNode = self.worldArray[currentDisplayedWorld - 1] as SKSpriteNode
            previousWorld.position = CGPointMake(-self.frame.size.width, 50)

            self.addChild(previousWorld)

            let moveBack = SKAction.moveByX(self.frame.size.width, y: 0, duration: 1.0, delay: 0,
                usingSpringWithDamping: 0.7, initialSpringVelocity: 0.5)

            //currentWorld.runAction(moveBack)
            previousWorld.runAction(moveBack, completion: {
                    self.moving = false
            })
            currentWorld.removeFromParent()
            currentDisplayedWorld--
        }

    }else if currentDisplayedWorld == 0 {

    }
}