小遊戲開發 Mario (6)
再開始今天新的內容前,我們來修正兩個錯誤。
第一個是我們為重力補上 deltaTime。然後適當地調整 gravity 值,由於我們重力值給了 30 這時候,mario 會一下跳的很高。我們來加大重力值控制 mario 高度。


調整更新(update)和繪製(draw)方法的先後順序。


我看先一下如何新增鍵盤事件,然後輸出 event 物件,看一看 event 上有什麼屬性。

事件裡有很多屬性,我們這裡只關心兩個屬性 code 和 keyCode。這裡我們希望每次按下和鬆開按鍵為一個動作,而不是當按住鍵時一直執行這個按鍵對應的動作,對於射擊,可能需要按下按鍵一直處理某個動作。

接下來我們開始建立 keyboardState 類,然後新增 addMapping 和 handleEvent 方法,具體內容看圖中註釋吧。


我們用 preventDefault 方法來阻止瀏覽器的預設行為,舉個例子,當按下 pagedown 按鈕件瀏覽器會向下翻頁。


新增兩個靜態變數,通過 0 和 1 分別表示鍵盤事件的狀態。


handleEvent 方法中,我們首先判斷該鍵盤事件是否已經註冊到 keyMap,如果沒有註冊,直接返回。根據 event 的型別 type 獲取當前鍵盤事件狀態。判斷鍵盤事件狀態是否改變,沒有改變也會直接返回。如果狀態改變,會先儲存鍵盤事件的狀態,最後執行該鍵盤事件的狀態所對應的回撥。

新增 listenTo 用於將事件註冊到 window 物件上。

我們還需要監聽 keyup 事件,調整程式碼,遍歷要監聽的事件。

測試一下剛剛建立好的 Keyboard 類,32 為空格鍵對應 keyCode 碼。


我們將 input 這部分程式碼整理到如圖中的位置,然後定義當玩家按下空格鍵,mario 所做的動作。我們先在這裡預定兩個方法,分別是 jump 特性的 start 方法和 jump 特性的 cancel 方法。

在 Entity 中新增一個屬性 traits, 這個屬性是一個 trait (特性)的集合,也就是 Entity 具有哪些特性,然後提供一個可以新增特性的方法。this[trait.Name] 我們可以通過特性名稱來呼叫到這個 trait 特性。

定義 Trait 類,trait 因為原意是特點,特性意思,可能本領更貼切些。在建構函式需要給出特徵的名稱,然後必須實現 update 方法。


建立一個 Velocity 類來繼承 Trait 類,大家可以把 Trait 想象為抽象類,我們需要把這部分程式碼遷移到 Velocity 的 update 方法中。



然後在 mario 中,將 Velocity 新增到他的 trait 本領中,這裡 trait 也可以理解為本領,這裡將 trait 翻譯為本領或技能可能也挺貼切的。


我繼續建立 mario 的跳躍本領,建立 Jump 類。

start 方法,我們將投入時間賦值為預定的 duration 的時間。
然後 update 方法中,當投入時間(engageTime 大於 0 時)減少 mario y 軸上值,讓 mario 向上運動,同時遞減投入時間。
cancel 方法:將投入時間設定為 0 ,這時 mario 就沒有向上執行的趨勢了。

將 jump 新增到 mario 的本領列表。

重新整理介面,當按下空格鍵,看 mario 會不斷跳起。

