# 小恐龍遊戲 due 12/19 ## SetUp - 安裝 Node.js - https://nodejs.org/zh-tw/download/ - 開啟 cmd / power shell / git bash ,確認 node.js 與 npm(js 的 軟體套件管理系統) 是否有安裝 - 在 command line 輸入 `node -v` 與 `npm -v` - ![](https://i.imgur.com/ZhbUwyw.png) - 使用 npm 安裝 http-server - https://www.npmjs.com/package/http-server - `npm install http-server -g` - 在資料夾底下 `shift+滑鼠右鍵` 開啟功能表,選擇 在這裡開啟 PowerShell 視窗 - ![](https://i.imgur.com/7lrNw67.png) - 安裝 eslint(js 程式碼檢測工具) - `npm install` - 在 command line 輸入 `http-server -c-1` 即會開啟服務,可以從下面顯示的網址進入網頁 - ![](https://i.imgur.com/eyrl6cz.png) - ![](https://i.imgur.com/X25FdbA.png) - 若編輯程式碼後要檢測程式碼是否 ## 摘要 小恐龍跑步的主要專案由 Canvas 繪製遊戲畫面,本專案是基於 GitHub 專案 [t-rex-runner](https://github.com/wayou/t-rex-runner),所提取自 chrome 中的程式碼進行改寫,並為基底去增加新的遊戲玩法。 專案本身由幾個大物件組成,分為規則類功能組件與會顯示在場景上的元件: - 規則類 - 遊戲場景 (Runner,這個命名比較奇怪,可以視為遊戲主體的畫布與一些基礎設定的 object) - 計算用物件 (DistanceMeter,計算跑步距離) - 夜晚模式 (NightMode,恐龍跑到一半會切換到晚上) - 場景/腳色/物品類: - 恐龍 (Trex,小恐龍主體) - 地平線 (分為Horizon與HorizonLine,一個為底部的線,另一個為上面崎嶇的土地) - 障礙物 (Obstacle,仙人掌、翼手龍) - 道具 (BuffItem) - 雲 (Cloud) - 遊戲結束畫布(GameOverPanel) new Runner 會進行一系列操作,包含載入圖片、音樂等,再建立腳色與場景,因為遊戲是每 frame 刷新,因此每個 frame 都要去做判斷現在記分多少、要不要新增障礙物、碰撞檢查等操作,可以再 Runner.update 中查看。 而本專案在此新增三種功能性道具,(以下簡稱 buff 物品),吃到物品皆會顯示特效並且持續2秒: - ![](https://i.imgur.com/QHqs3f5.png =10%x) - 攻擊模式,靠近障礙物時會自動噴火能攻擊障礙物 - ![](https://i.imgur.com/cDGJ33v.png) - ![](https://i.imgur.com/HfwrrN1.png =10%x) - 無敵模式,障礙物無效,會直接穿過障礙物 - ![](https://i.imgur.com/0qgNBdQ.png) - ![](https://i.imgur.com/KV9lHLY.png =10%x) - 飛行模式,恐龍會飛起來躲避障礙物,想要提早解除可以點 "跳躍按鍵" 提早解除 - ![](https://i.imgur.com/7HrtduB.png) 另外為了確保程式碼品質,在此使用了一套名為 ESlint 的工具,其目的是用於檢測程式碼本身是否有不統一的 codeing style 與一些可能造成程式碼有潛在錯誤的語句,例如使用未宣告的變數、宣告變數後並未使用等。 ## 需要增加的功能與實作 ### 需要自動產出 buff 物品 #### 實作思路 - 參考障礙物的生成方式下去改寫 - 考量兩者的相同與不同處,例如:都是兩者的物件色塊碰撞會產生效果,但遇到障礙物遊戲會停止,而吃到 buff 遊戲還是會繼續 - 檢查碰撞是使用 `checkForCollision()` 相關的 function 實作,因此可以透過它來改寫,其基本原理是 計算恐龍與碰撞物體的座標有沒有相交,若相交則代表碰撞 ![](https://i.imgur.com/CHyuO8Z.png) ### 吃到 buff 物品後需要紀錄狀態 #### 實作思路 ##### Trex 物件本身就自帶了不少玩家狀態,因此可以 buff 狀態參數在此擴充 - 同時也需要擴充更新其參數的 function 讓程式再其它地方使用 Trex 物件時能更新參數 ```js function Trex(canvas, spritePos) { ... // buff this.attackMode = false; this.superMode = false; this.flyMode = false; ... } Trex.prototype = { ... updateAttackMode: function (status) { this.attackMode = status; }, updateSuperMode: function (status) { this.superMode = status; }, updateFlyMode: function (status) { this.flyMode = status; }, ... } ``` ##### buff 時間 - 每個 buff 會生效 2秒 - 我們可以紀錄是什麼時候吃到道具的,在使用現在時間相減就能知道該 buff 有沒有過期,若過期則更新 buff 狀態並且 reset 道具的時間 - 若持續吃到物品需要重新計算,這時只要更新吃到道具的時間即可 ```js // ms const BUFFTIME = 2000; let buffMode = 0; <!-- 吃到道具 --> buffMode = performance.now(); <!-- 檢查 --> let now = performance.now(); if ((now - buffMode) > BUFFTIME) { // reset buff status // reset buff time } ``` ### 在頁面素材上增加 buff 物品 #### 實作思路 - 使用 photoshop 在原本的圖上增加素材 - ![](https://i.imgur.com/gtb54ih.png) - 主遊戲的素材皆是由一張大圖做裁切而成,實作方法是用並利用 canvas 的 drawImage 去切分各個元件,透過這個方式就能將我們新增的 buff 物品與 道具skin 加到程式中 - ![](https://i.imgur.com/FoHnrqx.png) ### 吃到 buff 物品的特效 #### 實作思路 ##### 吃到時會有的聲音 - 現有程式有 `Runner.playSound` 可以使用,因此了解其實作方式並透過其撥放素材即可 - `playSound()` 如何實作? 要使用 `playSound()` 首先需要載入 audio,這裡使用了 `loadSounds()` 去讀取音樂,這裡的音樂檔案不是使用 file import 而是將其轉為 base64 直接放入 `<audio>` 中,並且使用 id 去指定讀取 - 若要新增 audio 可以到 `Runner.sounds` 去新增 id 與 key 的 mapping 並且在 `index.html` 增加音檔,可以使用一些 MP3 to base64 的工具去轉換(在 ref 中有附上所用工具) ``` Runner.sounds = { BUTTON_PRESS: 'offline-sound-press', HIT: 'offline-sound-hit', SCORE: 'offline-sound-reached', GET_ITEM: 'get-item', ATTACK: 'attack', WING: 'wing', SUPER_MODE: 'super-mode' }; ``` ##### 在狀態中針對特別事件有特效音 - 以下幾種情況會有效果音: - 針對當下有無 buff 狀態去進行操作 - 吃到道具 - 靠近障礙物時攻擊並消除障礙物 - 透過 `checkForCollision()` 去判斷 - 吃到無敵道具期間 - 飛起來時 ##### 有吃到 buff 道具時恐龍會穿上不同裝備 - 以下幾種情境會有不同 裝備: - 攻擊模式,恐龍會增加皇冠 - 無敵模式,恐龍會帶著一個無敵星星 - 飛行模式,恐龍會長出小翅膀 - 在此不是重新繪製恐龍 skin ,而是用素材組合的方式來實現 - 透過判斷當下 buff 將對應的裝備組合成新的圖塊 ![](https://i.imgur.com/71bl3s1.png) ## Ref - [ESlint](https://github.com/eslint/eslint) - [MDN Canvas](https://developer.mozilla.org/zh-TW/docs/Web/API/Canvas_API) - [MDN CanvasRenderingContext2D](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/drawImage) - [MDN BaseAudioContext](https://developer.mozilla.org/en-US/docs/Web/API/BaseAudioContext/createBufferSource) - [Mp3 to base64 tool](https://base64.guru/converter/encode/audio/mp3) ### Music From - [mariomayhem](https://www.mariomayhem.com/downloads/sheet_music/)