Swift开发Sprite Kit游戏实践(三):物理推力与碰撞检测
为了避免monkey“落下”,需要用物理推力让它重新跳起来。 这时要在spawnEnemy()后添加一个新的method: func jumpPlayer() {
// 1
let impulse = CGVector(dx: 0,dy: 75)
// 2
player.physicsBody?.applyImpulse(impulse)
}
再回顾一下上述步骤: 首先创建一个固定数值推动力的CGVector,规定monkey跳起的距离。我也是尝试了多次才总结出具体数值的。 override func touchesBegan(touches: Set<NSObject>,withEvent event: UIEvent) { jumpPlayer() }
点击屏幕时,自动调用这些method。 现在就差一步了——在 didMoveToView(_:)后添加如下代码: // 1
let collisionFrame = CGRectInset(frame,0,-self.size.height * 0.2)
// 2
physicsBody = SKPhysicsBody(edgeLoopFromRect: collisionFrame)
代码会在屏幕边缘产生一个特殊的physics body,避免monkey飞出或者坠落在太空中。现在回顾一下上述代码: 首先创造一个可通过CGRectInset()扩大或缩小至多20%的矩形,即monkey的活动范围。monkey的轮廓可以稍微消失在屏幕外,但不能完全消失不见。
到目前为止,如果monkey遇到敌人,可以跳过去;但是跟敌人相撞的话,什么效果都没有,所以需要在游戏中添加碰撞检测(collision detection),有如下几步:
首先将如下所示添加至GameScene.swift最顶端: enum BodyType: UInt32 {
case player = 1
case enemy = 2
case ground = 4
}
这里要做的就是为每个sprite创建类别。ground number不是针对sprite,而是针对应用边框设定的,所以当monkey碰到屏幕边缘时会弹起,而不是落到屏幕之外! 接下来,执行SKPhysicsContactDelegate协定,标记GameScene(游戏场景): class GameScene: SKScene,SKPhysicsContactDelegate {
协议的作用是保证代码执行特定的method。此处执行针对两个physics body相撞的method。然后调整contactDelegate的值,将如下代码添加到didMoveToView(_:)末尾: physicsWorld.contactDelegate = self
完成后,两个physics body碰撞时,物理世界就会自动调用代码中的method。 在spawnEnemy()末尾添加如下代码: // 1
enemy.physicsBody = SKPhysicsBody(circleOfRadius: enemy.size.width/4)
// 2
enemy.physicsBody?.dynamic = false
// 3
enemy.physicsBody?.affectedByGravity = false
// 4
enemy.physicsBody?.allowsRotation = false
// 5
enemy.physicsBody?.categoryBitMask = BodyType.enemy.rawValue
// 6
enemy.physicsBody?.contactTestBitMask = BodyType.player.rawValue
// 7
enemy.physicsBody?.collisionBitMask = 0
此处稍稍解释一下:
将如下所示添加到didMoveToView(_:)的后面: physicsBody?.categoryBitMask = BodyType.ground.rawValue
player.physicsBody?.categoryBitMask = BodyType.player.rawValue
player.physicsBody?.contactTestBitMask = BodyType.enemy.rawValue
player.physicsBody?.collisionBitMask = BodyType.ground.rawValue
这里为monkey和ground设置类别和碰撞位掩码,让两者彼此碰撞;在monkey和敌人之间设置“contact(接触点)”。 现在到了最重要的一步,完善碰撞检测,执行之前提到的method来处理“contacts”: func didBeginContact(contact: SKPhysicsContact) {
let contactMask = contact.bodyA.categoryBitMask | contact.bodyB.categoryBitMask
switch(contactMask) {
case BodyType.player.rawValue | BodyType.enemy.rawValue:
let secondNode = contact.bodyB.node
secondNode?.removeFromParent()
let firstNode = contact.bodyA.node
firstNode?.removeFromParent()
default:
return
}
}
因为之前已将场景设置为物理世界的contactDelegate,两个physics body碰撞时会自动调用这个method。 它将两个位掩码结合成一个单个的接触点掩码,检验是否是monkey和敌人相撞,如果是,就将两者从屏幕上移除。 编写完成后运行,效果如下: 转自:http://www.csdn.net/article/2015-05-26/2824772-sprite-kit-for-kids-with-swift/3 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |