Make Infinite Obstacles Moving to the Left in a SpriteKit Game

449 Views Asked by At

I have a SpriteKit game with a ball that can be thrown and dragged. When it is thrown, the SKCamera follows it. What I want is shown in the picture below:

How can I build this kind of obstacle?

1

There are 1 best solutions below

4
On

One approach could be that you create a function that adds SKShapeNode which is your obstacle. You could keep list of your obstacle with an array where you append all your obstacles and remove first obstacle every time it disappears from view. That way your node count will stay low and you can have an infinite amount of obstacles.

Here is a sample code which creates new obstacles when player pass the most right obstacle in the game world.

private var obstacles = [SKShapeNode]()

private func addObstacle() {
    // Create obstacle aka SKShapeNode
    let obstacle = SKShapeNode(rectOf: CGSize(width: 50, height: 50))
    obstacle.fillColor = SKColor.white

    // If this is first obstacle, position it just beyond right side of the view. If not, get rightmost obstacles position and make a little gap between it and new obstacle.
    if let lastObstacle = self.obstacles.last {
        obstacle.position = CGPoint(x: lastObstacle.frame.maxX + self.frame.width/2, y: 0)
    } else {
        obstacle.position = CGPoint(x: self.frame.width/2 + obstacle.frame.width, y: 0)
    }

    // SKShapeNode have physicsbody where you can define categorybitmask etc
    obstacle.physicsBody?.categoryBitMask = ...

    // Add obstacle to the scene
    self.addChild(obstacle)

    // Add obstacle to array so we can keep record of those
    self.obstacles.append(obstacle)
}

override func update(_ currentTime: TimeInterval) {
    // If the rightmost obstacle come visible, create new obstacle
    if let lastObstacle = self.obstacles.last {
        if lastObstacle.frame.minX < self.camera.frame.maxX {
            self.addObstacle()
        }
    }

    // If arrays first obstacle is out of view, remove it from view and array
    if (self.obstacles.first?.frame.maxX ?? 0) < self.camera.frame.minX {
        self.obstacles.first?.removeFromParent()
        self.obstacles.removeFirst()
    }
}