Gradually increasing background scroll speed in SpriteKit

I am making a simple game in SpriteKit and I have a scrollable background. What just happens is that when the game scene loads, several background images are placed next to each other, and then the image moves horizontally when it scrolls from the screen. Here is the code for this, from my game scene didMoveToView.

// self.gameSpeed is 1.0 and gradually increases during the game

let backgroundTexture = SKTexture(imageNamed: "Background")
var moveBackground = SKAction.moveByX(-self.frame.size.width, y: 0, duration: (20 / self.gameSpeed))
var replaceBackground = SKAction.moveByX(self.frame.size.width, y: 0, duration: 0)
var moveBackgroundForever = SKAction.repeatActionForever(SKAction.sequence([moveBackground, replaceBackground]))

for var i:CGFloat = 0; i < 2; i++ {
    var background = SKSpriteNode(texture: backgroundTexture)
    background.position = CGPoint(x: self.frame.size.width / 2 + self.frame.size.width * i, y: CGRectGetMidY(self.frame))
    background.size = self.frame.size
    background.zPosition = -100
    background.runAction(moveBackgroundForever)

    self.addChild(background)
}

Now I want to increase the speed of background scrolling at certain points in the game. You can see that the background horizontal scroll duration is set to (20 / self.gameSpeed). Obviously, this does not work, because this code is run only once, and therefore the movement speed is never updated to take into account the new value of the variable self.gameSpeed.

, : ( ) self.gameSpeed?

!

+4
2

gameSpeed, . , -, ( , ):

class GameScene: SKScene {
    lazy var backgroundPieces: [SKSpriteNode] = [SKSpriteNode(imageNamed: "Background"), 
                                                 SKSpriteNode(imageNamed: "Background")]

    // ... 
}

gameSpeed:

var gameSpeed: CGFloat = 0.0 {
    // Using a property observer means you can easily update the speed of the 
    // background just by setting gameSpeed.
    didSet {
        for background in backgroundPieces {
            // Minus, because the background is moving from left to right.
            background.physicsBody!.velocity.dx = -gameSpeed
        }
    }
}

didMoveToView. , , .

override func didMoveToView(view: SKView) {
    for (index, background) in enumerate(backgroundPieces) {
        // Setup the position, zPosition, size, etc...

        background.physicsBody = SKPhysicsBody(rectangleOfSize: background.size)
        background.physicsBody!.affectedByGravity = false
        background.physicsBody!.linearDamping = 0
        background.physicsBody!.friction = 0

        self.addChild(background)
    }

    // If you wanted to give the background and initial speed,
    // here the place to do it.
    gameSpeed = 1.0
}

gameSpeed update, , gameSpeed += 0.5.

, update , (). , :

override func update(currentTime: CFTimeInterval) {
    for background in backgroundPieces {
        if background.frame.maxX <= 0 {
            let maxX = maxElement(backgroundPieces.map { $0.frame.maxX })

            // I'm assuming the anchor of the background is (0.5, 0.5)
            background.position.x = maxX + background.size.width / 2
        }
    }
}
+2

-

SKAction.waitforDuration(a certain amount of period to check for the updated values) 

SKAction.repeatActionForever(the action above)
runAction(your action)
{ // this is the completion block, do whatever you want here, check the values and adjust them accordly
}
0

All Articles