Search code examples
iosswiftsprite-kitpositionnodes

Sprite Kit - Creating node from didBeginContact()


I am using a custom brick class:

import SpriteKit
class Brick: SKSpriteNode {

    enum type { case Normal }

    convenience init (type: Brick.type) {
        self.init(color: .greenColor(), size: CGSizeMake(75, 25))

        physicsBody.SKPhysicsBody(rectangleOfSize: size)
        physicsBody!.mass = 9999
        physicsBody!.affectedByGravity = false

        position = CGPointMake(100, 50)

        // Category and collision bitmasks ...
        // Action to move the brick upwards ...
    }

    // Stuff
}

In my scene, I'm creating one initial brick, and everything works just fine. However, when I try to add a brick in the didBeginContact() function, I get unexpected results.

I have a SKNode at 1/5 height of the screen. So everytime a brick reaches that height, it will make contact with this invisible node and create a new brick:

// Inside SKScene
func didBeginContact(contact: SKPhysicsContact) {

    // I set physics body A and B ...

    if a.categoryBitMask == Category.brick && b.categoryBitMask == Category.brickSpawner {
        addChild(Brick(type: .Normal))
    }
}

So the problem is: when I create a new brick inside this function, the position is set to (0, 0) instead of (100, 50) as defined in the Brick class. Actually, if I go ahead and use println(brick.position) I get (100, 50), but in the screen it looks positioned at (0, 0).

If I create a brick anywhere else in the code, for example in the touchesBegan() or update() functions, the position is set correctly. This problem only happens when creating the node from didBeginContact().


Solution

  • This should help, it explains the steps in a single frame.

    https://developer.apple.com/library/ios/documentation/GraphicsAnimation/Conceptual/SpriteKit_PG/Introduction/Introduction.html

    You are creating it at the wrong time, so one of the steps behind the scenes is resetting it due to a few steps being missing. Queue that process up for the didFinishUpdate command. ( I would just create the object in the did contact, then throw it into an array, then on didFinishUpdate, go through the array and add them to the scene, and clear the array)