山姆回想著剛剛看到的雪人怪,還心有餘悸。
轉了個彎,繼續找尋水晶。
「碰!」山姆迎頭撞上了白色的物體,帶有冰涼的感覺。
「糟了!得趕快逃跑才行。」
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