# 小恐龍遊戲 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` -  - 使用 npm 安裝 http-server - https://www.npmjs.com/package/http-server - `npm install http-server -g` - 在資料夾底下 `shift+滑鼠右鍵` 開啟功能表,選擇 在這裡開啟 PowerShell 視窗 -  - 安裝 eslint(js 程式碼檢測工具) - `npm install` - 在 command line 輸入 `http-server -c-1` 即會開啟服務,可以從下面顯示的網址進入網頁 -  -  - 若編輯程式碼後要檢測程式碼是否 ## 摘要 小恐龍跑步的主要專案由 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秒: -  - 攻擊模式,靠近障礙物時會自動噴火能攻擊障礙物 -  -  - 無敵模式,障礙物無效,會直接穿過障礙物 -  -  - 飛行模式,恐龍會飛起來躲避障礙物,想要提早解除可以點 "跳躍按鍵" 提早解除 -  另外為了確保程式碼品質,在此使用了一套名為 ESlint 的工具,其目的是用於檢測程式碼本身是否有不統一的 codeing style 與一些可能造成程式碼有潛在錯誤的語句,例如使用未宣告的變數、宣告變數後並未使用等。 ## 需要增加的功能與實作 ### 需要自動產出 buff 物品 #### 實作思路 - 參考障礙物的生成方式下去改寫 - 考量兩者的相同與不同處,例如:都是兩者的物件色塊碰撞會產生效果,但遇到障礙物遊戲會停止,而吃到 buff 遊戲還是會繼續 - 檢查碰撞是使用 `checkForCollision()` 相關的 function 實作,因此可以透過它來改寫,其基本原理是 計算恐龍與碰撞物體的座標有沒有相交,若相交則代表碰撞  ### 吃到 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 在原本的圖上增加素材 -  - 主遊戲的素材皆是由一張大圖做裁切而成,實作方法是用並利用 canvas 的 drawImage 去切分各個元件,透過這個方式就能將我們新增的 buff 物品與 道具skin 加到程式中 -  ### 吃到 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 將對應的裝備組合成新的圖塊  ## 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/)
×
Sign in
Email
Password
Forgot password
or
Sign in via Google
Sign in via Facebook
Sign in via X(Twitter)
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
Continue with a different method
New to HackMD?
Sign up
By signing in, you agree to our
terms of service
.