Swift: Physics Body Collision Bad 指令错误

Swift: Physics Body Collision Bad Instruction Error

当我 运行 这段代码时,第一行 CollisionWithplayer 给我一个错误的指令错误。错误不会每次都出现,只是偶尔出现一次,没有类似的情况来确定导致错误的原因。

func didBeginContact(contact: SKPhysicsContact) {
    let firstBody : SKPhysicsBody = contact.bodyA
    let secondBody : SKPhysicsBody = contact.bodyB


    if ((firstBody.categoryBitMask == PhysicsCategory.Goblin) && (secondBody.categoryBitMask == PhysicsCategory.Bullet) ||
        (firstBody.categoryBitMask == PhysicsCategory.Bullet) && (secondBody.categoryBitMask == PhysicsCategory.Goblin))
    {

       CollisionWithBullet(firstBody.node as! SKSpriteNode, Bullet: secondBody.node as! SKSpriteNode)
    }
        else  if ((firstBody.categoryBitMask == PhysicsCategory.Goblin) && (secondBody.categoryBitMask == PhysicsCategory.player) ||
        (firstBody.categoryBitMask == PhysicsCategory.player) && (secondBody.categoryBitMask == PhysicsCategory.Goblin)){

        CollisionWithplayer(firstBody.node as! SKSpriteNode, player: secondBody.node as! SKSpriteNode)
            }

func CollisionWithBullet(Goblin: SKSpriteNode, Bullet:SKSpriteNode){
    Goblin.removeFromParent()
    Bullet.removeFromParent()
    score += 1
    ScoreLbl.text = "\(score)"
    var explosion = SKEmitterNode(fileNamed: "Goblin Death Animation.sks")
    explosion!.particlePosition = Goblin.position
    self.addChild(explosion!)
    var fire = SKEmitterNode(fileNamed: "Goblin Death Animation 2.sks")
    fire!.particlePosition = Goblin.position
    self.addChild(fire!)


}
func CollisionWithplayer(Goblin: SKSpriteNode, player: SKSpriteNode){
    let ScoreDefault = NSUserDefaults.standardUserDefaults()
    ScoreDefault.setValue(score, forKey: "Score")
    ScoreDefault.synchronize()


    if (score > Highscore){

        let HighscoreDefault = NSUserDefaults.standardUserDefaults()
        HighscoreDefault.setValue(score, forKey: "Highscore")

    }

    Goblin.removeFromParent()
    player.removeFromParent()
    self.view?.presentScene(EndScene())
    ScoreLbl.removeFromSuperview()
}

我假设您遇到了错误,因为您的代码没有处理 1 次碰撞导致 didBeginContact 方法多次触发的情况(碰撞发生在同一节点的 2 个点)

我会像这样重写你的代码以避免这种情况(使用可选)。此外,我稍微重写了它,这样您就不必为每次碰撞编写 2 个 if 语句。

 func didBeginContact(contact: SKPhysicsContact) {
     let firstBody: SKPhysicsBody
     let 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.Goblin) && (secondBody.categoryBitMask == PhysicsCategory.Bullet) {
          collisionWithBullet(firstBody.node as? SKSpriteNode, bullet: secondBody.node as? SKSpriteNode)
     }

     if (firstBody.categoryBitMask == PhysicsCategory.Goblin) && (secondBody.categoryBitMask == PhysicsCategory.player) {
          collisionWithPlayer(firstBody.node as? SKSpriteNode, player: secondBody.node as? SKSpriteNode)
     }
 }

func collisionWithBullet(goblin: SKSpriteNode?, bullet:SKSpriteNode?){
     guard let goblin = goblin, bullet = bullet else { return }

     goblin.removeFromParent()
     bullet.removeFromParent()
     score += 1
     scoreLbl.text = "\(score)"
     if let explosion = SKEmitterNode(fileNamed: "Goblin Death Animation.sks") {
           explosion.particlePosition = goblin.position
           self.addChild(explosion)
      }
      if let fire = SKEmitterNode(fileNamed: "Goblin Death Animation 2.sks") {
          fire.particlePosition = goblin.position
          self.addChild(fire)
      }
  }

  func collisionWithPlayer(goblin: SKSpriteNode?, player: SKSpriteNode?){
     guard let goblin = goblin, player = player else { return }

     let scoreDefault = NSUserDefaults.standardUserDefaults()
     scoreDefault.setValue(score, forKey: "Score")
      // synchronised not needed anymore


     if (score > highscore){
         let highscoreDefault = NSUserDefaults.standardUserDefaults()
         highscoreDefault.setValue(score, forKey: "Highscore")
     }

     goblin.removeFromParent()
     player.removeFromParent()
     self.view?.presentScene(EndScene())
     scoreLbl.removeFromSuperview()
 }

也请遵循 swift 指南,您的方法和属性应该以小写字母开头,而不是大写字母。

希望对您有所帮助