上一篇文章,我们添加了游戏的背景,现在我们来添加鳄鱼了。
将鳄鱼添加到场景中
有言在先,这只鳄鱼是十分活泼的,请你保持一个安全距离!:]
像风景背景一样,鳄鱼也是由一个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()
以上代码创建鳄鱼节点并设置它的position
和zPosition
。
与风景背景不同,鳄鱼有一个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()
中,所以这些动作将在持续时间内重复执行。然后由鳄鱼节点执行这些动作。
建立并运行,然后就会看到这个凶猛的爬行动物张开了它的死亡之嘴!
你有丛林背景,你有鳄鱼 -- 现在你需要一个菠萝。
添加奖励--菠萝
打开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
上面设置了物理世界的contactDelegate
,gravity
和。gravity
为世界的重力加速度,而speed
为模拟执行的速度(这两个属性都设置成默认值)。
您已指定delegate 为self
,但是因为GameScene
没有遵循SKPhysicsContactDelegate
协议,因此编译器在第一行代码处报错。解决这个问题需要将该协议添加到类定义上,如下所示:
class GameScene: SKScene, SKPhysicsContactDelegate {
再次编译并运行程序。您应该看到菠萝越过鳄鱼,并掉入水中(它实际上落在水的后面)。
下一篇文章,我们要添加葡萄藤,并且将菠萝挂到上面去。