iT邦幫忙

2025 iThome 鐵人賽

DAY 9
0

昨天,介紹完與滑鼠、觸控相關的輸入互動後,今天就要來介紹怎麼在 CG 上偵測玩家的鍵盤輸入啦~

首先,PixiJS 做為一個 2D 繪圖引擎,並不包含偵測鍵盤輸入的功能,所以正常情況下我們必須依賴瀏覽器本身的 API 來偵測鍵盤輸入。但好家在這裡是 Code.Gamelet,CG 已經幫我們把這件事情簡化了,並且結合了我們昨天介紹過的 EventEmitter ,使鍵盤的偵測方式變得和滑鼠的偵測方式相似,統一的結構在程式碼的閱覽上也會更加易讀。

▸ 認識 Keyboard 類別

Keyboard 是 CG 的核心模組 Base2 內建的類別,在開發時,我們不需要自己創建它,因為 Base2 已經幫我們把它創建好,並儲存在 keyboard 這個全域常數裡面了,我們只要從 Base2 拿出來就可以開始使用裡面的功能。

Keyboard 提供了兩個核心功能:

  1. 檢查按鍵狀態:你可以隨時檢查一個按鍵是否被按住、剛被按下或剛被放開。這對於需要持續性動作的遊戲(例如按住方向鍵讓角色移動)非常有用。
  2. 監聽鍵盤事件:你可以使用 on()off() 函數來監聽按鍵事件,這和昨天的滑鼠、觸控事件非常相似。
import keyboard = CG.Base2.keyboard;
import Keyboard = CG.Base2.keyboards.Keyboard;
import KeyCode = CG.Base2.keyboards.KeyCode;
import Key = CG.Base2.keyboards.Key;

在使用 Keyboard 的時候,原則上最頂層都會有這幾個 import ,沒意外的話,在我們使用Keyboard 時,CG 就會自動幫我們把這幾行寫好了,因此這邊只是稍微提一下,待會會個別介紹它們。

但如果 CG 真的沒有幫你寫好,你可以對著你使用的物件、類別按下滑鼠右鍵打開選單,選擇「CG自動導入」即可。

▸ 開始動手

  1. 監聽按鍵事件

    首先,讓我們用最簡單的方式來監聽按鍵被按下的事件:

    import pixi = CG.Pixi.pixi;
    import keyboard = CG.Base2.keyboard;
    import Keyboard = CG.Base2.keyboards.Keyboard;
    import KeyCode = CG.Base2.keyboards.KeyCode;
    
    async function start() {
    
        // 初始化 Pixi
        await pixi.initialize({ stageWidth: 960, stageHeight: 540 });
    
        // 建立文字物件
        const text = new PIXI.Text({
            text: "試著按點什麼",
            style: { fill: 0xFFFFFF, fontSize: 100, align: "center" },
            anchor: 0.5,
            position: { x: pixi.stageWidth * 0.5, y: pixi.stageHeight * 0.5 }
        } as PIXI.TextOptions);
    
        // 將文字物件加入舞台
        pixi.root.addChild(text);
    
        // 監聽鍵盤事件
        keyboard.on(Keyboard.EVENT.PRESSED, (key: KeyCode, event: KeyboardEvent) => {
            text.text = `按下了 ${event.code}`;
        });
    }
    
    start();
    

    這段程式碼使用 keyboard.on() 來監聽 Keyboard.EVENT.PRESSED 這個事件。當任何按鍵被按下時,它就會觸發函數,並將按鍵的相關資訊傳遞給我們,讓我們可以根據 event.code 顯示按下的鍵名。

    Keyboard 鍵盤事件監聽 預覽

    你也可以用 switch 語法來處理不同的按鍵,例如:

    // 在 keyboard.on() 內添加,其他保持不變...
    switch (key) {
        case Key.Z:
            text.text += "\\n發射了導向飛彈";
            break;
        case Key.X:
            text.text += "\\n埋了高性能地雷";
            break;
        case Key.C:
            text.text += "\\n發射了迫擊砲";
            break;
        case Key.V:
            text.text += "\\n發射了雷射砲";
            break;
    }
    

    值得注意的是,keyboard.on() 會丟出兩個參數:keyevent

    • key 是一個 KeyCode 物件,這是由 Base2 預先定義好的標準按鍵代碼,它提供了一個簡潔、統一的方式來代表按鍵(例如 Key.Z)。
    • event 則是瀏覽器原生的 KeyboardEvent 物件,它包含了更底層的資訊,例如 event.code(按鍵在鍵盤上的物理位置代碼)。通常在遊戲實作上,我們只會需要用到 key ,但若你有其他更複雜的需求,就可以自己利用 event 來處理。

    Keyboard 鍵盤事件監聽 KeyCode 預覽

  2. 偵測按鍵狀態:isDown()

    事件監聽器對於一次性的按鍵事件(例如發射子彈)非常有用。但是,如果你想讓角色在玩家按住按鍵時持續移動,單靠 on() 事件就不夠了。

    這時,我們需要使用 keyboard.isDown() 這個函數。它會回傳一個布林值(truefalse),告訴我們某個按鍵是否處於被按下的狀態。

    // 在 start() 內添加,其他保持不變...
    
    // 定義移動速度
    const moveSpeed = 5;
    
    // 設置一個循環更新函數
    CG.Base2.addUpdateFunction(() => {
        // 根據指定按鍵的狀態,改變 text 的座標位置
        if (keyboard.isDown(Key.W)) text.y -= moveSpeed; // 向上移動
        if (keyboard.isDown(Key.S)) text.y += moveSpeed; // 向下移動
        if (keyboard.isDown(Key.A)) text.x -= moveSpeed; // 向左移動
        if (keyboard.isDown(Key.D)) text.x += moveSpeed; // 向右移動
    });
    

    這裡我們使用了 CG.Base2.addUpdateFunction,它會讓程式碼在每一幀(Frame)都被執行。當我們在其中檢查 keyboard.isDown() 的狀態時,只要指定的按鍵被按住,程式碼就會在每一幀持續執行,從而實現了平滑、持續的移動。

    Keyboard 鍵盤狀態偵測 預覽

點我查看範例程式碼

▸ 總結

今天我們介紹了如何在 CG 上處理鍵盤輸入:

  • 你可以使用 keyboard.on() 來監聽一次性的按鍵事件,適合處理發射技能或切換裝備等單次動作。
  • 你可以使用 keyboard.isDown() 來偵測按鍵的即時狀態,並搭配遊戲的更新函數,實現玩家角色持續性的移動等遊戲邏輯。

這兩種方式各有用途,而 isDown() 與循環更新的結合,正是所有遊戲實現即時控制的關鍵。

明天,我們將會更深入的介紹 CG.Base2.addUpdateFunction 這個東西,雖然之前在 Day 04 介紹了它會不斷執行的功能,但還有許多細節沒有提到,像是不同設備之間的畫面更新率(FPS)不同,更新的頻率不同,該如何同步之類的,不過這些就等到明天再說吧!


上一篇
Day 08:讓物件可以互動:滑鼠與觸控事件
系列文
用 PixiJS 寫遊戲!告別繁瑣設定,在 Code.Gamelet 打造你的第一個遊戲9
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言