您当前的位置: 首页 >  游戏

SpriteKit游戏如何一步一步重构在场景中增加金币动画(二)

发布时间:2017-05-18 08:13:18 ,浏览量:0

上一篇我们迅速构建了一个生成金币的原型,现在我们需要进一步完善我们的功能。

首先,我们需要让小飞机碰到金币不会爆炸,稍后我们让“金币”更像一个金币 ;)

现在飞机的物理对象设置如下:

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..            
关注
打赏
1688896170
查看更多评论

暂无认证

  • 0浏览

    0关注

    107766博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文
立即登录/注册

微信扫码登录

0.0756s