上一篇我们迅速构建了一个生成金币的原型,现在我们需要进一步完善我们的功能。
首先,我们需要让小飞机碰到金币不会爆炸,稍后我们让“金币”更像一个金币 ;)
现在飞机的物理对象设置如下:
player.physicsBody = SKPhysicsBody(texture: playerTexture, size: playerTexture.size()) player.physicsBody!.contactTestBitMask = player.physicsBody!.collisionBitMask player.physicsBody?.isDynamic = false player.physicsBody!.collisionBitMask = 0
这意味着飞机与其他任何物体接触而不碰撞!所以金币自然也无一幸免,我们首先要修改的是didBegin(_ contact: SKPhysicsContact)方法,将其末尾的爆炸代码修改如下:
if contact.bodyA.node?.name == coinName || contact.bodyB.node?.name == coinName{ if contact.bodyA.node == player{ contact.bodyB.node?.removeFromParent() }else{ contact.bodyA.node?.removeFromParent() } let sound = SKAction.playSoundFileNamed("coin.wav", waitForCompletion: false) run(sound) score += 10 return } if contact.bodyA.node == player || contact.bodyB.node == player{ if contact.bodyA.node == player && contact.bodyB.node?.parent == nil{ print("removed object...") return }else if contact.bodyB.node == player && contact.bodyA.node?.parent == nil{ print("removed object...") return } if let explosion = SKEmitterNode(fileNamed: "PlayerExplosion"){ explosion.position = player.position addChild(explosion) } let sound = SKAction.playSoundFileNamed("explosion.wav", waitForCompletion: false) run(sound) gameOver.alpha = 1 gameState = .dead bgMusic.run(SKAction.stop()) player.removeFromParent() speed = 0 }
代码很好理解,不过值得注意的是我在中间位置判断了node的父对象是否为nil,如果是则直接退出方法,这样做是有意而为之的!因为我们开启了SpriteKit物理对象的精确边界,这会导致短时间内多次进入didBegin(_ contact: SKPhysicsContact)方法,如果第一次在碰到金币将其删除后,第二次(在金币还未删除时就已经入栈缓存)就会直接进入后面的爆炸代码,从而出现少数玩家碰到金币仍然会爆炸的怪异情形。
而如果node从父对象中删除则其parent属性立即会被设置为nil,这就是我们在后面判断的原因。
好了,现在玩家可以“吃”金币了,可以增加分数了,现在我们需要美化一下金币了,玩家对“吃”长方体状物可没什么兴趣哦 ;)
从google找到一个金币动画的gif文件,注意背景一定要是透明的:
看起来不错,不过尺寸有点大,首先用动画编辑工具将其缩小到合理大小。
因为无法直接将gif动画在SpriteKit中播放,所以我们必须将gif中的一系列静态图片抽取出来然后形成一个动画帧。
以下是将gif文件每张静态图片转换为一个纹理数组的helper方法,如果失败则返回nil:
func load(imagePath:String)->[SKTexture]?{ guard let imageSource = CGImageSourceCreateWithURL(URL(fileURLWithPath: imagePath) as CFURL, nil) else { return nil } let count = CGImageSourceGetCount(imageSource) var images:[CGImage] = [] for i in 0..关注打赏