iT邦幫忙

2021 iThome 鐵人賽

DAY 30
2
Mobile Development

從零開始的8-bit迷宮探險!Swift SpriteKit 遊戲開發實戰系列 第 30

從零開始的8-bit迷宮探險【Level 256】恭喜全部破關!遊戲完成 & 結語

為什麼鐵人 30 天的最後一篇標題是 Level 256 呢?
主要是致敬小精靈 Pac-Man 在第 256 關的時候,發生了知名的 Bug,畫面上的亂碼造成遊戲無法再繼續遊玩。因為 8-bit 的正整數範圍是 0~255,在第 256 關的時候發生了溢位 (overflow),導致關卡最多就停留在 256 關。

遊戲完成影片

讓我們來看一下遊戲完成品吧!


技術重點整理

在遊戲實作的過程中,所使用到的技術及方法,整理在這邊:

  • SpriteKit
    • 節點 (node) 相關
      • node 在父節點中的層級:zPosition
      • 搜尋子節點:childNode(withName:)
    • 動畫相關
      • 圖片序列動畫:animate(with:timePerFrame:)
      • 依據 node 當前的所在位置移動 x 及 y 向量:moveBy(x:y:duration:)
      • 調整 Alpha 值:fadeAlpha(to:duration:)
      • 建立序列動作:sequence(_:)
      • 執行動作:run(_:)
      • 重複播放動作,可設定重複次數:repeat(_:count:)
      • 不斷重複播放動作:repeatForever(_:)
    • 場景相關
      • 通知更新場景:update(_:)
      • 轉場動畫:SKTransition
    • 燈光效果相關
      • 可以照亮周圍的燈光節點:SKLightNode
        • 燈光周圍的顏色:ambientColor
        • 光源散射和反射的顏色:lightColor
        • 陰影的顏色,由節點 (sprite) 投射而成:shadowColor
        • 光源的衰減率指數:falloff
        • 燈光的類型:categoryBitMask
      • 定義 sprite 節點是如何被光源點亮:lightingBitMask
  • SafeArea
    • 偵測當 Safe Area 改變時:viewSafeAreaInsetsDidChange()
  • 數學計算相關
    • 計算開根號的值:sqrtf
    • 隨機取整數:random(in:)
    • 取絕對值:abs(_:)
  • Timer
    • 建立計時器:scheduledTimer(timeInterval:target:selector:userInfo:repeats:)
  • 本機紀錄(Property List) 與檔案相關
    • 遵循 Decodable 與 Encodable 協定:Codable
    • 轉成 property list 檔案:encode(_:)
    • 取得檔案的內容:contents(atPath:)
    • 解析 property list 的檔案內容:decode(_:from:)
  • 音樂/音效 (AVFoundation Framework)
    • 播放音樂檔案:AVAudioPlayer

回顧 30 天

整理了一下大綱,包含遊戲實作各篇的成果,方便讓大家能直接連結到想看的主題

前言與基礎篇

前言

Xcode

Swift 基礎語法

SpriteKit

遊戲開發實作篇

【Level 10】遊戲故事及架構設計

  • 遊戲企劃書

【Level 11】在 iPhone 裡蓋座迷宮,就。很。牆

  • 創建專案
  • 畫面排版 (創建 SKSpriteNode 以及使用其屬性)
  • Safe Area 的概念

https://imgur.com/aFf5rJm.png

【Level 12】把迷宮塗上喜歡的顏色

  • 繪製迷宮背景圖片素材
  • 將迷宮套上圖片

https://imgur.com/N4X8gd3.png

【Level 13】主角總是孤獨的

  • 製作主角 (類別的概念)
  • 主角的動畫

https://imgur.com/CyaguQ6.gif

【Level 14】讓主角奔跑吧!Running Sam

  • 新增方向按鈕,控制主角的移動
  • 在迷宮中的移動邏輯

https://imgur.com/buPSWd7.gif

【Level 15】迷人的反派角色-製作怪物

  • 製作怪物
  • 怪物的動畫

https://imgur.com/uudL2ZW.gif

【Level 16】丞相,起風了!遠方飄來烏雲怪物了

  • 讓怪物自動移動 (隨機選方向移動)

https://imgur.com/0HJGD84.gif

【Level 17】稻草人也想要智慧大腦,給怪物一點靈魂跟一點點個性

  • 讓怪物追蹤主角的位置來移動
  • 讓四種怪物各有不一樣的追擊方式

https://imgur.com/qmHnrf5.gif

【Level 18】為什麼他們開始亂跑?捉摸不定的怪物移動模式

  • 改變怪物的移動模式
  • 使用計時器 (Timer)

https://imgur.com/ut7WQf7.gif

【Level 19】這個相遇我等了一輩子了-偵測主角與怪物接觸

  • 偵測主角與怪物的接觸
  • 接觸時的動畫 (跌倒動畫)

https://imgur.com/j7KUCtz.gif

【Level 20】搜集水晶可以召喚神龍嗎?

  • 在迷宮中加入水晶 (收集物)
  • 偵測主角碰觸到水晶後,水晶消失

https://imgur.com/N3kOpwy.gif

【Level 21】進擊的主角!暴風雨來吶,你坐啊!

  • 新增魔幻水晶
  • 魔幻水晶的閃爍動畫
  • 主角收集魔幻水晶後的效果:怪物變成逃逸模式,主角可以反擊怪物

https://imgur.com/YJuyNYT.gif

【Level 22】奧義隱身術 & 時間靜止術

  • 新增香菇,主角吃到後可以讓怪物停止移動一段時間
  • 位於隱身的樹,可以逃避怪物的攻擊

https://imgur.com/JWdyaph.gif
https://imgur.com/EJYTik2.gif

【Level 23】長老,這個水晶值多少錢?

  • 將主角收集到水晶、魔幻水晶、香菇、擊退怪物後的得分,顯示在畫面上

https://imgur.com/dey7rz5.gif

【Level 24】誰才是高玩?紀錄本機最高得分

  • 將最高得分存到本機中,下次開啟遊戲時可以顯示最高得分紀錄

https://imgur.com/e3xKXHi.gif

【Level 25】今天又是嶄新的一天,回到原點

  • 新增主角生命值機制
  • 遊戲重新開始流程

https://imgur.com/hqjtipx.gif

【Level 26】這遊戲沒有華佗,不能補血啊!Game Over 場景切換

  • 生命值用盡時,切換至遊戲結束場景
  • 點擊重新開始按鈕,可重新回到遊戲場景

https://imgur.com/hjcFHht.gif

【Level 27】神助攻-老弟幫我配個音效

  • 幫遊戲配上音樂及音效

【Level 28】看我把關卡難度提升-在場景加上聚光燈效果

  • 主角收集完全部水晶後,遊戲進入下一關
  • 增加關卡難度:加上 SKLightNode

https://imgur.com/j27ACRy.gif

【Level 29】讓你的 App 與眾不同!設計 Icon 及 LaunchScreen

  • 加上 App icon
  • 將螢幕鎖定為直屏
  • 調整啟動畫面

https://imgur.com/opp8CSk.png
https://imgur.com/2rf6orI.gif
https://imgur.com/pKGmYKy.gif


關於遊戲主角的原型

https://imgur.com/1EXU02K.png
你問說,主角有沒有原型,當然有啊!而且原型的名字就叫做 Sam,是個爬過 30 座百岳的男人。
他剛剛才和我說最近想安排一日單攻的百岳,還好鐵人賽完賽了,是時候該切換成戶外模式了!
他爬山會自帶水壺、對講機、封箱膠帶 (鞋子開口笑的時候可以補救),是個有如百寶袋一般的登山夥伴。
當初跟他說主角叫做山姆時,他就回了這麼一句:『不能畫太醜』。殊不知,我把他畫成了像素圖 ^_^


結語

最後,來聊一下 it 鐵人 30 天的感想
人們常把人生比喻成爬山,我想,鐵人賽也是類似爬山的一種感受吧!

『在 99% 的時間裡痛苦掙扎,用 1% 的時間去享受登頂的喜悅』

出自:youtuber 刘大白《最狂野的梦想:征服珠峰》

這些成果是自己一點一滴累積起來,而最終完賽的喜悅也是屬於自己的深刻感受吧!
最後的最後,謝謝大家的閱讀及陪伴/images/emoticon/emoticon29.gif


參考來源:
Pac-Man
小精靈遊戲中的幽靈是怎麼追蹤人的? 鮮為人知的bug和最快全破世界紀錄! | 啾啾鞋
zPosition
childNode(withName:)
animate(with:timePerFrame:)
moveBy(x:y:duration:)
fadeAlpha(to:duration:)
sequence(_:)
run(_:)
repeat(_:count:)
repeatForever(_:)
update(_:)
SKTransition
SKLightNode
ambientColor
lightColor
shadowColor
falloff
categoryBitMask
lightingBitMask
viewSafeAreaInsetsDidChange()
sqrtf
random(in:)
abs(_:)
scheduledTimer(timeInterval:target:selector:userInfo:repeats:)
Codable
encode(_:)
contents(atPath:)
decode(_:from:)
AVAudioPlayer


上一篇
從零開始的8-bit迷宮探險【Level 29】讓你的 App 與眾不同!設計 Icon 及 LaunchScreen
系列文
從零開始的8-bit迷宮探險!Swift SpriteKit 遊戲開發實戰30

尚未有邦友留言

立即登入留言