swift sprite kit game when I shoot on a enemy sometimes the bullet goes trough the enemy, how can I fix this?

纵然是瞬间 提交于 2019-12-03 23:07:12

SpriteKit doesn't perform precise collision detection because it aims to achieve faster performance. You can make the physicsBody's property usesPreciseCollisionDetection to true, like this:

    bullet.physicsBody!.usesPreciseCollisionDetection = true

https://developer.apple.com/reference/spritekit/skphysicsbody/1520014-usesprecisecollisiondetection

I don't know if it works, please let me know.

Instead of setting your collisionBitMasks to zero, try setting them to this:

bullet.physicsBody!.collisionBitMask = PhysicsCategories.Meteor
Meteor.physicsBody!.collisionBitMask = PhysicsCategories.Bullet

And try changing your the beginning of your didBeginContact method to this:

    var body1 = contact.bodyA.node as! SKSpriteNode
    var body2 = contact.bodyB.node as! SKSpriteNode

 if (body1.categoryBitMask == PhysicsCategories.Player && body2.categoryBitMask == PhysicsCategories.Meteor) || (body2.categoryBitMask == PhysicsCategories.Player && body1.categoryBitMask == PhysicsCategories.Meteor) {
        //if the player has hit the meteor
        spawnExplosion(body1.position)
        spawnExplosion(body2.position)

        body1.removeFromParent()
        body2.removeFromParent()

        runGameOver()
    }

I can't say the spawnExplosion will work since I can't see what it does, but this should remove the nodes.

I think your problem is inside the bullet code:

    let moveBullet = SKAction.moveToY(self.size.height + bullet.size.height, duration: 1)
    let deleteBullet = SKAction.removeFromParent()
    let bulletSequence = SKAction.sequence([bulletSound, moveBullet, deleteBullet])
    bullet.runAction(bulletSequence)

Try to replace with bullet.physicsBody?.applyImpulse(CGVectorMake( 0, 20)) instead of SKAction.moveToY and remove bullet if go out the screen

I think a neater way to code didBeginContact is as follows:

func didBeginContact(contact: SKPhysicsContact) {

   let contactMask = contact.bodyA.categoryBitMask | contact.bodyB.categoryBitMask

   switch contactMask

   case PhysicsCategories.Player | PhysicsCategories.Meteor :

      // The player and the meteor have contacted

      spawnExplosion(contact.contactPoint) //Create explosion where they touch
      contact.bodyA.node.removeFromParent()
      contact.bodyB.node.removeFromParent()
      runGameOver()

   case PhysicsCategories.Bullet| PhysicsCategories.Meteor :

      // The bullet and meteor have contacted
      // body2.node?.position.y < self.size.height // ?? Not sure what this is

      addScore()
      spawnExplosion(contact.contactPoint) //Create explosion where they touch
      contact.bodyA.node.removeFromParent()
      contact.bodyB.node.removeFromParent()

   default:
      print("Other contact detected")
}

I changed your code to create one explosion wwhere the 2 bodies touch; if you want 2 explosions, each centered on the nodes that touch, use:

spawnExplosion(contact.bodyA.node.position)
spawnExplosion(contact.bodyB.node.position)

or:

for node in [contact.bodyA.node, contact.bodyB.node] {
   spawnExplosion(node.position)
   }
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!