在Swift中,碰撞检测相当简单 - 但是在这个特定的项目中,身体碰撞不像通常那样触发didBeginContact
事件。
以下是我用于两个物体碰撞(使用士兵和子弹)的检查清单:
- 将
SKPhysicsContactDelegate
添加到类中。 - 适当设置physicsWorld,通常为:
self.physicsWorld.contactDelegate = self
- 为每个节点组创建类别。例如:
let bulletCategory = 0x1 << 0
- 为每个子弹和士兵创建SKNodes。
- 为每个子弹和士兵分别创建一个具有匹配形状的物理体。
- 将每个子弹的categoryBitMask设置为
bulletCategory
(士兵设置为soldierCategory)。 - 将每个子弹的contactBitMask设置为
soldierCategory
(士兵设置为bulletCategory)。 - 定义
didBeginContact()
处理程序。
下面是完整的代码。它是一个最小化的 ~20 行“Hello World”程序,用于演示碰撞。
如果您创建了一个新的“Game”,并将其复制粘贴到GameScene.swift中,它将运行,但不会触发碰撞事件。
import SpriteKit
class GameScene: SKScene, SKPhysicsContactDelegate {
var soldier = SKShapeNode(circleOfRadius: 40)
let soldierCategory:UInt32 = 0x1 << 0;
let bulletCategory:UInt32 = 0x1 << 1;
override func didMoveToView(view: SKView) {
self.physicsWorld.contactDelegate = self
// THE soldier
soldier.fillColor = SKColor.redColor()
soldier.position = CGPoint(x: CGRectGetMidX(self.frame), y: 40)
soldier.physicsBody = SKPhysicsBody(circleOfRadius: 20)
soldier.physicsBody!.dynamic = false
soldier.physicsBody!.categoryBitMask = soldierCategory
soldier.physicsBody!.contactTestBitMask = bulletCategory
soldier.physicsBody!.collisionBitMask = 0
// bulletS
var timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: Selector("makeBullet"), userInfo: nil, repeats: true)
self.addChild(soldier)
}
func makeBullet() {
var bullet = SKShapeNode(rect: CGRect(x: CGRectGetMidX(self.frame), y: self.frame.height, width: 10, height: 40), cornerRadius: CGFloat(0))
bullet.fillColor = SKColor.redColor()
bullet.physicsBody = SKPhysicsBody(rectangleOfSize: CGSize(width: 10, height: 40))
bullet.physicsBody?.dynamic = false
bullet.physicsBody?.categoryBitMask = bulletCategory
bullet.physicsBody?.contactTestBitMask = soldierCategory
bullet.physicsBody?.collisionBitMask = soldierCategory
var movebullet = SKAction.moveByX(0, y: CGFloat(-400), duration: 1)
var movebulletForever = SKAction.repeatActionForever(movebullet)
bullet.runAction(movebulletForever)
self.addChild(bullet)
}
func didBeginContact(contact: SKPhysicsContact) {
print("CONTACT")
}
override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
/* Called when a touch begins */
}
override func update(currentTime: CFTimeInterval) {
/* Called before each frame is rendered */
}
}