按照上一篇的步骤,我们已经完成前两步了,接下来是第三步:添加物理效果。
在didMove方法中添加代码:
self.physicsBody = SKPhysicsBody(edgeLoopFrom: self.frame)
self.physicsWorld.contactDelegate = self
依文档来看physicsWorld和physicsBody属性的设置是为了开启模拟真实世界的模式,contactDelegate代理中有一个物理世界中的元素只要碰撞就会触发的didBegin方法,待会儿要用。现在给子弹和飞碟添加上物理属性:
bullet.physicsBody = SKPhysicsBody(edgeLoopFrom: CGRect(x: 0, y: 0, width: bullet.size.width, height: bullet.size.height))
bullet.physicsBody?.categoryBitMask = 2
bullet.physicsBody?.contactTestBitMask = 1
barrier.physicsBody = SKPhysicsBody(rectangleOf: barrier.frame.size)
barrier.physicsBody?.categoryBitMask = 1
barrier.physicsBody?.affectedByGravity = false
barrier.physicsBody?.contactTestBitMask = 2
注意categoryBitMask和contactTestBitMask属性,
categoryBitMask:A mask that defines which categories this physics body belongs to.
contactTestBitMask:A mask that defines which categories of bodies cause intersection notifications with this physics body.
文档解释categoryBitMask定义了这个物理体属于哪一类的,而contactTestBitMask定义了哪一类的物理体能跟当前物理体产生交叉事件的通知。既然是热狗打飞碟那么这两个值就是相互设置,然后添加碰撞检测的方法:
//MARK:配置场景的物理体代理
extension GameScene {
func didBegin(_ contact: SKPhysicsContact) {
//为方便我们判断碰撞的bodyA和bodyB的cateBitMask哪个小,小的则将它保存在新建的变脸bodyA里,大的则保存到新建d变量bodyB里
var bodyA:SKPhysicsBody
var bodyB:SKPhysicsBody
if contact.bodyA.categoryBitMask > contact.bodyB.categoryBitMask {
bodyA = contact.bodyA
bodyB = contact.bodyB
} else {
bodyA = contact.bodyB
bodyB = contact.bodyA
}
//判断bodyA是否为子弹,bodyB是否为飞碟,如果是则调用爆炸方法
if (bodyA.categoryBitMask == 2 && bodyB.categoryBitMask == 1) {
print("热狗打到了飞碟")
}
}
}
最后一步,添加爆炸效果。
找一个效果不错的爆炸gif图,分解成单张图片,新建一个文件夹,后缀必须为.atlas,把爆炸图片素材拉进去,然后拖进项目中
爆炸发生在热狗跟飞碟接触的地方,可以确定爆炸的位置,下一个方法,传入爆炸位置:
//MARK:爆炸效果
func explode(point:CGPoint) {
//提取atlas文件中的素材
let explodeAtlas = SKTextureAtlas.init(named: "exploded")
let allTextureArray = NSMutableArray.init(capacity: 16)
for i in 0..<explodeAtlas.textureNames.count {
let textureName = String(format: "%[email protected]", arguments: [i+1])
let texture = explodeAtlas.textureNamed(textureName)
allTextureArray.add(texture)
}
let bombNode = SKSpriteNode(texture: allTextureArray[0] as? SKTexture)
bombNode.position = point
bombNode.name = "bomb"
bombNode.size = CGSize(width: 50, height: 50)
bombNode.zPosition = 2.0
self.addChild(bombNode)
//爆炸效果动画
let animationAction = SKAction.animate(with: allTextureArray as! [SKTexture], timePerFrame: 0.05)
bombNode.run(animationAction) {
//爆炸结束后移除
bombNode.removeFromParent()
}
}
在碰撞代理方法中"热狗打到了飞碟"那里添加:
//在飞碟的位置爆炸
explode(point: (bodyB.node?.position)!)
//爆炸结束后,热狗和飞碟都消失
bodyB.node?.removeFromParent()
bodyA.node?.removeFromParent()
运行看效果:
源码下载:https://github.com/caimengnan/OpenFire.git
|
请发表评论