2

I'm currently working on a small iOS game. In its current iteration, 20 targets spawn and move across the screen space-invaders style, and you control a little ship to shoot and destroy them. The code for my targets, the player ship's bullets, and a simple collision detection function I've written in the interim are as follows:

class Red_Target: SKSpriteNode{

    var game_scene: GameScene!
    private var ship_texture: SKTexture!

    convenience init(scale: CGFloat, game_world: GameScene){
        self.init(texture: SKTexture(imageNamed: "Proto Target"))
        self.ship_texture = SKTexture(imageNamed: "Proto Target")
        self.setScale(scale)
        game_scene = game_world
        game_scene.addChild(self)
        self.position = CGPoint(x: game_scene.view!.bounds.width/10, y: 9 * game_scene.view!.bounds.height/10)
        //self.physicsBody = SKPhysicsBody(texture: ship_texture, size: self.size)
        self.physicsBody = SKPhysicsBody(circleOfRadius: 13)
        self.physicsBody!.affectedByGravity = false
        self.physicsBody!.collisionBitMask = 0x0
        self.physicsBody!.categoryBitMask = CollisionType.Enemy.rawValue
        self.physicsBody!.contactTestBitMask = CollisionType.Player_Bullet.rawValue
    }

    func move() {
        self.run(space_invaders(scene: game_scene))
    }

}

class PC_Bullet: SKSpriteNode{

    convenience init(scale: CGFloat){
        self.init(imageNamed: "Goodbullet")
        self.setScale(scale)
        self.physicsBody = SKPhysicsBody(circleOfRadius: 3)
        self.physicsBody!.affectedByGravity = false
        self.physicsBody!.categoryBitMask = CollisionType.Player_Bullet.rawValue
        self.physicsBody!.collisionBitMask = 0x0
        self.physicsBody!.contactTestBitMask = CollisionType.Enemy.rawValue
    }


}

    func didBegin(_ contact: SKPhysicsContact) {
        contact.bodyA.node!.removeFromParent()
        contact.bodyB.node!.removeFromParent()
    }

}

This code, in its current iteration, works just fine. However, if the line defining the target's physicsbody as its texture is uncommented and the line defining physicsbody as circleOfRadius is removed, the game will consistently crash after the 5th target is destroyed, claiming that didBegin unwraps a nil value. Why does this only happen from physics bodies with textures? Is there any way I could change the code for this to work? I would love to be able to use the physics body from texture function later on, when working with more irregular shapes.

Bradley Mackey
  • 6,777
  • 5
  • 31
  • 45
Will Leet
  • 41
  • 4
  • Does this answer your question? [Receiving an error when nodes make contact](https://stackoverflow.com/questions/44895717/receiving-an-error-when-nodes-make-contact) – Knight0fDragon Feb 07 '20 at 01:00

1 Answers1

1

You are pulling a classic nooby mistake. You are removing your bodies too early. If you browse Stackoverflow you will find a plethera of ways to solve it.

The basic idea is do not remove your sprites until the end of the physics phase because your 1 sprite could have multiple contact points to handle. So come up with a way to flag sprites that need to be deleted, and remove them during the didSimulatePhysics function.

Knight0fDragon
  • 16,609
  • 2
  • 23
  • 44