1
votes

Is there a way to load a physics body as a subclass of an SKSpriteNode? I created a subclass of an SKSpriteNode outside the scene.

class specializedNode: SKSpriteNode {
    var variable = 0
}

Inside the scene, I created a function that creates objectA and a structure for the physics categories.

struct PhysicsCategory {
    static let None : UInt32 = 0
    static let All  : UInt32 = UInt32.max
    static let A    : UInt32 = 0b1      
    static let B    : UInt32 = 0b10     
}

func spawnObjectA () {
    objectA = specializedNode()

    objectA.physicsBody = SKPhysicsBody(rectangleOfSize: objectA.size)
        objectA.physicsBody?.dynamic = true
        objectA.physicsBody?.categoryBitMask = PhysicsCategory.A
        objectA.physicsBody?.contactTestBitMask = PhysicsCategory.B
        objectA.physicsBody?.collisionBitMask = PhysicsCategory.None
        objectA.physicsBody?.usesPreciseCollisionDetection = true
    addChild(objectA)
}

Then, I called didBeginContact for when objectA collides with objectB.

func objectADidCollide(objectA:specializedNode, objectB:SKSpriteNode) {
    objectB.removeFromParent()
    ++objectA.variable
}

func didBeginContact(contact: SKPhysicsContact) {
    var firstBody: SKPhysicsBody
    var secondBody: SKPhysicsBody
    if contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask {
        firstBody = contact.bodyA
        secondBody = contact.bodyB
    } else {
        firstBody = contact.bodyB
        secondBody = contact.bodyA
    }

    if ((firstBody.categoryBitMask & PhysicsCategory.A != 0) && (secondBody.categoryBitMask & PhysicsCategory.B != 0)) {
            objectADidCollide(firstBody.node as specializedNode, objectB: secondBody.node as SKSpriteNode)
    }
}

However, when I run the code and the two objects collide, the code hits a breakpoint and the debug navigator pops up.

Line 10 (0x58e0fc: trap) turns green and displays:

"Thread: 1 EXC_BREAKPOINT (code=EXC_ARM_BREAKPOINT, subcode=0xdefe)"

libswiftCore.dylib`swift_dynamicCastClassUnconditional:
0x58e0ec:  cbz    r0, 0x58e0fc              ; swift_dynamicCastClassUnconditional + 16
0x58e0ee:  ldr    r2, [r0]
0x58e0f0:  cmp    r2, r1
0x58e0f2:  it     eq
0x58e0f4:  bxeq   lr
0x58e0f6:  ldr    r2, [r2, #0x4]
0x58e0f8:  cmp    r2, #0x0
0x58e0fa:  bne    0x58e0f0                  ; swift_dynamicCastClassUnconditional + 4
0x58e0fc:  trap   
0x58e0fe:  nop 

I do not want to load objectA as an SKSpriteNode, as I want to change an attribute of objectA that I created in its subclass. Any suggestions?

1
debug navigator? You mean the app either hits a breakpoint or crashes? If so, post the crash message and what line the crash occurs. Note that as is, the spawnObjectA method never adds the node as child so it never appears in the game.LearnCocos2D
I must have accidentally deleted the spawn line when I transferred the code over and removed the irrelevant code. There is the crash message.ETRunner
do you have any breakpoints in your project? check the breakpoint navigator pane in xcodeLearnCocos2D
No, there are not any break points in the project.ETRunner

1 Answers

1
votes

I was having an almost identical problem. I started with code from a Ray Wenderlich tutorial and started subclassing from there. Well, I'm pretty sure that the tutorial swaps the projectile and the monster in didBeginContact. Since they're the same class, and it just removes them both, it didn't matter.

In your program (and mine) that means you're trying to typecast an object into something that it isn't.

I just switched firstBody and secondBody in the call to objectADidCollide and it fixed my problems.

Looking at your code, I don't think that's exactly your problem, but I wouldn't be surprised if you're typecasting the wrong object.