我在 Swift编程这个简单的太空游戏,直到我遇到了检测碰撞的问题.在浏览了论坛,教程等之后,我尝试通过声明位掩码来实现冲突: 对象1 enemy?.physicsBody = SKPhysicsBody(circleOfRadius: ((enemy?.si
对象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") }
}