ios – 如何在Swift,Sprite工具包中检测碰撞

我在 Swift编程这个简单的太空游戏,直到我遇到了检测碰撞的问题.在浏览了论坛,教程等之后,我尝试通过声明位掩码来实现冲突:

对象1

enemy?.physicsBody = SKPhysicsBody(circleOfRadius: ((enemy?.size.width)!/2))
    enemy?.physicsBody?.categoryBitMask = enemyBitMask
    enemy?.physicsBody?.contactTestBitMask = bulletBitMask
    enemy?.physicsBody?.collisionBitMask = 0

对象2

bullet?.physicsBody? = SKPhysicsBody(rectangleOf: (bullet?.size)!)
    bullet?.physicsBody?.categoryBitMask =  bulletBitMask
    bullet?.physicsBody?.contactTestBitMask =  enemyBitMask
    bullet?.physicsBody?.collisionBitMask = 0
    bullet?.physicsBody?.usesPreciseCollisionDetection = true

我还在里面写了一份印刷声明

func didBegin(_ contact: SKPhysicsContact) { print("Hello") }

这是我如何配置我的精灵:

func CreateNewEnemy() {
    var enemy : SKSpriteNode?

       let moveEnemyDown = SKAction.repeatForever(SKAction.moveBy(x: 0,y: -1,duration: 0.01))
       let rotateEnemy = SKAction.repeatForever(SKAction.rotate(byAngle: 25,duration: 5))

      let enemyXpos = randomNum(high:  self.frame.size.width/2,low: -1 * self.frame.size.width/2)
      let enemyYpos = randomNum(high:  2.5*self.frame.size.height,low: self.frame.size.height/2)
      let enemyOrigin : CGPoint = CGPoint(x: enemyXpos,y: enemyYpos)

      enemy = SKSpriteNode(imageNamed: possibleEnemyImage[Int(arc4random_uniform(4))])
      print(enemy?.size.height)
      enemy?.scale(to: CGSize(width: player.size.height,height: player.size.height))
      print(enemy?.size.height)
      enemy?.position = enemyOrigin
      enemy?.run(moveEnemyDown)
      enemy?.run(rotateEnemy)
      let enemyRadius : CGFloat = (enemy?.size.width)!/2
      print(enemyRadius)

      enemy?.physicsBody? = SKPhysicsBody(circleOfRadius: enemyRadius)

      enemy?.physicsBody?.categoryBitMask = enemyCategory
      enemy?.physicsBody?.contactTestBitMask = bulletCategory
      enemy?.physicsBody?.collisionBitMask = 0
      enemy?.zPosition = 1

      enemiesArray.append(enemy!)
      self.addChild(enemy!)
}

创造敌人(被称为移动查看功能)

func CreateAllEnemies(amountOfEnemies : UInt8) {
    for _ in 0...amountOfEnemies {
        CreateNewEnemy()
    }
}

和另一个精灵

func CreateNewBullet() {
     let bulletOrigin : CGPoint = CGPoint(x: player.position.x,y: player.position.y+player.size.height/2)
     let moveBulletUp = SKAction.repeatForever(SKAction.moveBy(x: 0,y: 3,duration: 0.01))

     var bullet : SKSpriteNode?
     bullet = SKSpriteNode(imageNamed: "bulletImage")
     bullet?.position = bulletOrigin
     bullet?.run(moveBulletUp)

     bullet?.physicsBody? = SKPhysicsBody(rectangleOf: (bullet?.size)!)
     bullet?.physicsBody?.categoryBitMask =  bulletCategory
     bullet?.physicsBody?.contactTestBitMask = enemyCategory
     bullet?.physicsBody?.collisionBitMask = 0
     bullet?.physicsBody?.isDynamic = true
     bullet?.physicsBody?.usesPreciseCollisionDetection = true
     bullet?.zPosition = 1

     bulletsArray.append(bullet!)
     self.addChild(bullet!)
}

这个是用计时器创建的

bulletTimer = Timer.scheduledTimer(timeInterval: 0.25,target: self,selector: #selector(CreateNewBullet),userInfo: nil,repeats: true)

不幸的是,在看到两个物体碰到后,它不会在控制台中打印任何东西.

解决方法

>定义唯一的类别,确保您的类是SKPhysicsContactDelegate并使自己成为物理联系委托:

//物理类别

let enemyCategory:    UInt32 = 1 << 1
let bulletCategory:   UInt32 = 1 << 2

class GameScene: SKScene,SKPhysicsContactDelegate {
   physicsWorld.contactDelegate = self

>分配类别(通常在didMove中(查看:):

enemy.physicsBody.catgeoryBitMask = enemyCategory
bullet.physicsBody.catgeoryBitMask = bulletCategory

(确保为每个节点创建了物理实体)

>设置碰撞:

enemy.physicsBody?.collisionBitMask = 0 //敌人没有碰撞
bullet.physicsBody?.collisionBitMask = 0 // bullet没有碰撞

甚至:

for node in [enemy,bullet] {
   node.physicsBody?.collisionBitMask = 0 //  collides with nothing
   }

>设置联系人

bullet.physicsBody?.collisionBitMask = enemyCategory // bullet接触敌人

确保每个潜在联系人中涉及的对象中至少有一个对象的物理主体上的isDynamic属性设置为true,否则将不会生成任何联系人.两个对象不必是动态的.

当子弹和敌人联系时,你现在应该调用didBegin.您可以像这样编写didBegin:

func didBegin(_ contact: SKPhysicsContact) {
     print("didBeginContact entered for \(String(describing: contact.bodyA.node!.name)) and \(String(describing: contact.bodyB.node!.name))")

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

     switch contactMask {
     case bulletCategory | enemyCategory:
        print("bullet and enemy have contacted.")
        let bulletNode = contact.bodyA.categoryBitMask == bulletCategory ? contact.bodyA.node : contact.bodyB.node
        enemyHealth -= 10
        bulletNode.removeFromParent
     default:
        print("Some other contact occurred")
     }

}

相关文章

当我们远离最新的 iOS 16 更新版本时,我们听到了困扰 Apple...
欧版/美版 特别说一下,美版选错了 可能会永久丧失4G,不过只...
一般在接外包的时候, 通常第三方需要安装你的app进行测...
前言为了让更多的人永远记住12月13日,各大厂都在这一天将应...