做一个类似Cut The Rote 的游戏(二)

上一篇文章,我们添加了游戏的背景,现在我们来添加鳄鱼了。

将鳄鱼添加到场景中

有言在先,这只鳄鱼是十分活泼的,请你保持一个安全距离!:]

像风景背景一样,鳄鱼也是由一个SKSpriteNode表示。不同的是:你需要保存对鳄鱼的引用,你需要为鳄鱼建立一个physics body,用来检测和处理鳄鱼与其他物体的碰撞。

仍然在GameScene.swift中,将以下属性添加到类的顶部:

private var crocodile: SKSpriteNode!
private var prize: SKSpriteNode! `

这些属性各自保存了对鳄鱼和奖品(菠萝)的引用。它们不需要在GameScene外面被访问,所以将它们定义为private

这些属性的类型是SKSpriteNode!。这!意味着隐式解开的可选项,它告诉Swift这些属性无需立即被初始化。如果要使用!,你必须确保无论什么时候访问属性,属性都不会为nil,否则应用程序将崩溃。

找到在GameScene.swift内的方法setUpCrocodile(),并添加以下代码:

crocodile = SKSpriteNode(imageNamed: ImageName.CrocMouthClosed)
crocodile.position = CGPoint(x: size.width * 0.75, y: size.height * 0.312)
crocodile.zPosition = Layer.Crocodile
crocodile.physicsBody = SKPhysicsBody(texture: SKTexture(imageNamed: ImageName.CrocMask), size: crocodile.size)
crocodile.physicsBody?.categoryBitMask = PhysicsCategory.Crocodile
crocodile.physicsBody?.collisionBitMask = 0
crocodile.physicsBody?.contactTestBitMask = PhysicsCategory.Prize
crocodile.physicsBody?.isDynamic = false
addChild(crocodile)
animateCrocodile()

以上代码创建鳄鱼节点并设置它的positionzPosition

与风景背景不同,鳄鱼有一个SKPhysicsBody,它可以与世界上其他物体进行物理交互。这对后面检测菠萝是否落在鳄鱼口中是十分有用的。你不想鳄鱼被撞倒,或者从屏幕底部掉下来,所以你需要设定isDynamic = false,防止它受到作用力的影响。

categoryBitMask--设置了鳄鱼的身体物理类别为PhysicsCategory.Crocodile。你不想让鳄鱼对其他物体进行反弹,所以设置collisionBitMask = 0。你需要检测的是“Prize”的身体与鳄鱼接触,所以你需要设置contactTestBitMask = PhysicsCategory.Prize

您可能已经注意到,鳄鱼的physics body使用SKTexture对象进行初始化。您使用CrocMouthOpen作为鳄鱼的身体纹理,该图像包括鳄鱼的全身,但是mask纹理只包括鳄鱼的头和嘴,毕竟鳄鱼不能用它的尾巴吃菠萝!(mask纹理用来判断物理碰撞检测,身体纹理只是用来展示)

现在你会添加一个鳄鱼正在“waiting”的动画。找到animateCrocodile()方法并添加以下代码:

let duration = 2.0 + drand48() * 2.0
let open = SKAction.setTexture(SKTexture(imageNamed: ImageName.CrocMouthOpen))
let wait = SKAction.wait(forDuration: duration)
let close = SKAction.setTexture(SKTexture(imageNamed: ImageName.CrocMouthClosed))
let sequence = SKAction.sequence([wait, open, wait, close])
crocodile.run(SKAction.repeatForever(sequence)) 

除了使小鳄鱼非常焦虑,上面的代码创建了一些改变鳄鱼节点纹理的动作,使它的嘴巴在闭合和开口之间交替。

SKAction.sequence()根据数组创建了动作序列。在这种情况下,纹理动作在2-4秒的随机时间里进行组合。

这一系列的序列动作放在repeatActionForever()中,所以这些动作将在持续时间内重复执行。然后由鳄鱼节点执行这些动作。

建立并运行,然后就会看到这个凶猛的爬行动物张开了它的死亡之嘴!


做一个类似Cut The Rote 的游戏(二)_第1张图片
鳄鱼张开嘴巴

你有丛林背景,你有鳄鱼 -- 现在你需要一个菠萝。

添加奖励--菠萝

打开GameScene.swift 并找到setUpPrize()方法。添加以下内容:

prize = SKSpriteNode(imageNamed: ImageName.Prize)
prize.position = CGPoint(x: size.width * 0.5, y: size.height * 0.7)
prize.zPosition = Layer.Prize
prize.physicsBody = SKPhysicsBody(texture: SKTexture(imageNamed: ImageName.Prize), size: prize.size)
prize.physicsBody?.categoryBitMask = PhysicsCategory.Prize
prize.physicsBody?.collisionBitMask = 0
prize.physicsBody?.density = 0.5
addChild(prize)

与鳄鱼类似,菠萝节点也使用physics body。不同的是,菠萝应该掉落并反弹,而鳄鱼就在那里不耐烦地等待着。所以你设置isDynamic = true。你也可以减少菠萝的密度density,减轻了重量,菠萝可以摆动得更大。

使用物理学

在开始让菠萝掉落之前,我们最好先配置物理世界。找到GameScene.swift文件内的 setUpPhysics()方法,并添加以下三行代码:

physicsWorld.contactDelegate = self
physicsWorld.gravity = CGVector(dx: 0.0, dy: -9.8)
physicsWorld.speed = 1.0

上面设置了物理世界的contactDelegategravity和。gravity为世界的重力加速度,而speed为模拟执行的速度(这两个属性都设置成默认值)。

您已指定delegate 为self,但是因为GameScene没有遵循SKPhysicsContactDelegate协议,因此编译器在第一行代码处报错。解决这个问题需要将该协议添加到类定义上,如下所示:

class GameScene: SKScene, SKPhysicsContactDelegate {

再次编译并运行程序。您应该看到菠萝越过鳄鱼,并掉入水中(它实际上落在水的后面)。

下一篇文章,我们要添加葡萄藤,并且将菠萝挂到上面去。

你可能感兴趣的:(做一个类似Cut The Rote 的游戏(二))