山姆回想着刚刚看到的雪人怪,还心有余悸。
转了个弯,继续找寻水晶。
「碰!」山姆迎头撞上了白色的物体,带有冰凉的感觉。
「糟了!得赶快逃跑才行。」
PS. 这里是开发 iOS 手机游戏的系列文,如果还没看过之前
剧情文章的朋友,欢迎先点这边回顾唷!
在 SKScene 类别中的 update 方法,会在游戏的每帧 (per-frame) 被呼叫,我们可以覆写 update
方法,并且将一些想要判断的逻辑放在里面,当符合逻辑时,就可以执行对应的事情
for-in
遍历所有的怪物 (self.weathers)where
分别写上当两者的 gridX
或 gridY
相等时,另一个轴向的距离相减小於一个格子的宽度 (这边因为图片在之前的章节实作时有放大,所以我们加上了一点数值 6
微调)abs
:可以取两者相减後的绝对值.ATTACK
和 .PLAY
时,且 isSamFall
为 false
才能让怪物攻击主角,并且执行 gameStop()
方法。这边设置 isSamFall
的用意是避免连续进入这个逻辑判断,导致重复执行gameStop()
:将所有 Timer 关闭,并让主角执行跌倒的动画,这边 num
带入 3,repeatAni
带入 false
class GameScene: SKScene {
...
var isSamFall: Bool = false
...
override func update(_ currentTime: TimeInterval) {
guard let sam = self.sam else {
return
}
for weather in self.weathers where weather.gridX == sam.gridX && abs(weather.node.position.y - sam.node.position.y) <= CGFloat(self.gridWH + 6) || weather.gridY == sam.gridY && abs(weather.node.position.x - sam.node.position.x) <= CGFloat(self.gridWH + 6) {
if weather.mode == .ATTACK || weather.mode == .PLAY {
if !self.isSamFall {
self.isSamFall = true
self.gameStop()
}
}
}
}
func gameStop() {
// 停止 timer
self.stopTimer()
// 跌倒动画
if let sam = self.sam {
sam.playAnimation(imageName: "sam_fall", num: 3, repeatAni: false)
}
}
}
准备三张序列图片,将它们命名为:
我们的主角很帅气的滑垒跌倒了!
因为角色们都还是处在移动的状态,接着来调整这个问题
角色们都需要有停止的状态,所以我们回到角色 GameCharacter 类别,加上一个参数 isCanMove
,预设为 false
,用来记录目前是否可以移动
在 Move 协定中,加上设定移动的方法 setCanMove(isCanMove: Bool)
class GameCharacter {
...
var isCanMove: Bool = false
...
}
protocol Move {
func startMove(direction: Direction)
func endMove()
func setCanMove(isCanMove: Bool)
}
startMove
方法一开始时,先判断目前是否可以移动,如果不行则设定 isMoving
为 false
,并且 return,不继续执行後续的移动setCanMove
方法,改变 isCanMove
的值class Sam: GameCharacter, Move {
func startMove(direction: Direction) {
if !self.isCanMove {
self.isMoving = false
return
}
...
}
func setCanMove(isCanMove: Bool) {
self.isCanMove = isCanMove
}
}
func startMove(direction : Direction) {
if !self.isCanMove {
self.isMoving = false
return
}
...
}
func setCanMove(isCanMove: Bool) {
self.isCanMove = isCanMove
}
setCanMove(isCanMove: true)
,才执行开始移动 startMove(direction: .NONE)
setCanMove(isCanMove: true)
class GameScene: SKScene {
override func didMove(to view: SKView) {
...
for weather in self.weathers {
weather.setCanMove(isCanMove: true)
weather.startMove(direction: .NONE)
}
if let sam = self.sam {
sam.setCanMove(isCanMove: true)
}
}
func gameStop() {
...
// 停止移动主角 & 跌倒动画
if let sam = self.sam {
sam.setCanMove(isCanMove: false)
sam.playAnimation(imageName: "sam_fall", num: 3, repeatAni: false)
}
// 停止移动怪物
for weather in weathers {
weather.setCanMove(isCanMove: false)
}
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
guard let sam = self.sam, sam.isCanMove == true else {
return
}
...
}
}
主角及怪物接触时,所有角色都成功停止移动了
目前我们的游戏画面上,已经有主角及怪物了,但是还少了个重要的东西,就是主角的游戏目的:收集水晶。
明日就会带大家在游戏中加上水晶罗!
参考来源:
update(_:)
abs
>>: 【在 iOS 开发路上的大小事-Day15】透过 Firebase 来管理使用者 (Sign in with E-mail 篇) Part1
注意,我只讲了codelab的50%左右,但对paging3和flow的概念讲完了 通常有codel...
上次介绍完前面两个修饰符,今天就来把它学习完吧!!! .stop .prevent .capture...
哈罗,各位好,我本来想写一些,自己想学、有主题的东西,但考量最近工作繁忙,自己又在准备一些考试,所以...
tags: Ryu REST API REST: Representational State Tr...
第 1 步 - 新增 Route 别忘了,使⽤者想要看到你网站上的内容,第⼀步是要问过 Route,...