Aidan
Aidan

Reputation: 51

SWIFT: How to randomly select 1 of 5 obstacles and run an action on it, and repeat this process every second?

I am trying to create a game where there are five different obstacles, one of which is selected at random every second, and moves from the top of the screen to the bottom of the screen. This should create an obstacle field for the player to navigate. I am able to have the first obstacle move down the screen, but instead of another coming down the screen a second later, I keep getting Thread 1: signal SIGABRT errors, despite trying to fix the problem.

Here is my code:

func randomize() {
    smallMiddleObstacle.size = CGSizeMake(self.frame.width - 180, obstacleHeight)
    smallMiddleObstacle.position = CGPointMake(self.frame.width / 2, self.frame.height + smallMiddleObstacle.frame.height / 4)
    smallMiddleObstacle.color = UIColor.blueColor()

    bigMiddleObstacle.size = CGSizeMake(self.frame.width - 100, obstacleHeight)
    bigMiddleObstacle.position = CGPointMake(self.frame.width / 2, self.frame.height + bigMiddleObstacle.frame.height / 4)
    bigMiddleObstacle.color = UIColor.blueColor()

    rightObstacle.size = CGSizeMake(self.frame.width * 1.4, obstacleHeight)
    rightObstacle.position = CGPointMake(self.frame.width, self.frame.height + rightObstacle.frame.height / 4)
    rightObstacle.color = UIColor.blueColor()

    leftObstacle.size = CGSizeMake(self.frame.width * 1.4, obstacleHeight)
    leftObstacle.position = CGPointMake(0, self.frame.height + leftObstacle.frame.height / 4)
    leftObstacle.color = UIColor.blueColor()

    rightObstacleInPair.size = CGSizeMake(self.frame.width * 0.7, obstacleHeight)
    rightObstacleInPair.position.x = self.frame.width
    rightObstacleInPair.color = UIColor.blueColor()

    obstaclePair.addChild(rightObstacleInPair)

    leftObstacleInPair.size = CGSizeMake(self.frame.width * 0.7, obstacleHeight)
    leftObstacleInPair.position.x = 0
    leftObstacleInPair.color = UIColor.blueColor()

    obstaclePair.addChild(leftObstacleInPair)

    obstaclePair.position.y = self.frame.height + obstaclePair.frame.height / 4

    let distance = CGFloat(self.frame.height + obstacleHeight)
    let move = SKAction.moveByX(0, y: -distance, duration: NSTimeInterval(0.005 * distance))
    let remove = SKAction.removeFromParent()
    moveAndRemove = SKAction.sequence([move, remove])

    let random = Int(arc4random_uniform(4))

    if random == 0 {
        addChild(smallMiddleObstacle)
        smallMiddleObstacle.runAction(moveAndRemove)
    } else if random == 1 {
        addChild(bigMiddleObstacle)
        bigMiddleObstacle.runAction(moveAndRemove)
    } else if random == 2 {
        addChild(rightObstacle)
        rightObstacle.runAction(moveAndRemove)
    } else if random == 3 {
        addChild(leftObstacle)
        leftObstacle.runAction(moveAndRemove)
    } else {
        addChild(obstaclePair)
        obstaclePair.runAction(moveAndRemove)
    }

}



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

    if !isGameStarted {

        isGameStarted = true


        let spawn = SKAction.runBlock({
        () in

            self.randomize()

    })

        let delay = SKAction.waitForDuration(1.5)
        let spawnDelay = SKAction.sequence([spawn, delay])
        let spawnDelayForever = SKAction.repeatActionForever(spawnDelay)

        self.runAction(spawnDelayForever)



    }



}

Thanks

Upvotes: 1

Views: 75

Answers (1)

Alessandro Ornano
Alessandro Ornano

Reputation: 35402

You forgot to removeFromParent the already addChild's so, the second time you call randomizemethod your have an "Attemped to add a SKNode which already has a parent:"

First of all give a name to your nodes if you have not already done.

Everytime before you make an addChild, you must be sure you don't already have added it, to know you can do:

For example:

if let child = self.childNodeWithName(smallMiddleObstacle.name) {
     child.removeFromParent()
}

Upvotes: 1

Related Questions