0
votes

I'm having trouble adding new nodes into a scene where existing nodes are. When I add them I set the .position property to be the same, but they appear at the origin of the scene not at the position of the existing node.

I am building a very simple Asteroids-like game in SpriteKit. I have a method on my GameScene that adds asteroids:

// MARK: - Asteroids
func insertAsteroids(count: Int, size: AsteroidSize, newPosition: CGPoint?) {
    for i in 0 ..< initialAsteroidCount {
        let asteroid = Asteroid(size: size)

        if let position = newPosition {
            asteroid.position = position
        } else {
            asteroid.position = randomPositionOnScene()
        }
        self.addChild(asteroid)
    }
}

and in my GameScene I call it like insertAsteroids(initialAsteroidCount, size: AsteroidSize.Big, newPosition: nil) with the newPosition set to nil so they go to a random place.

When I shoot an asteroid I have a contact handler that calls the same method, but slightly differently:

func didBeginContact(contact: SKPhysicsContact) {

    [...]

    //make new asteroids
    if let newSize = oldAsteroid.smallerAsteroidSize() {
        let newAsteroidCount = Int(arc4random_uniform(2)) + 2

        self.insertAsteroids(newAsteroidCount, size: newSize, newPosition: oldAsteroid.position)
    }

    [...]

}

The crucial thing is oldAsteroid.position. I can println() the positions straight away after insertAsteroids() and see that they are the same but when they are displayed they appear in the lower left-hand corner of the scene (the origin).

Even if I force them into a known position they still appear at the origin:

self.insertAsteroids(newAsteroidCount, size: newSize, newPosition: CGPoint(x: 40, y: 50))

Have I made a mistake with the co-ordinate system, or is this to do with adding new nodes to a scene inside SKPhysicsContactDelegate methods?

1

1 Answers

0
votes

I've found the answer.

Paweł Białecki and Donn found it. You can't modify a tree while it is being simulated. That is, you can't modify a tree inside the didBeginContact() method, but you can set a flag and modify the tree in didSimulatePhysics().