Swift SpriteKit写一个简单的打飞碟小游戏(二)

按照上一篇的步骤,我们已经完成前两步了,接下来是第三步:添加物理效果。

在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