在babylonjs中如何将键盘输入事件转变为方向向量

220 阅读2分钟

键盘交互(Keyboard Interactions

1、记录按键的按下与弹起状态
import {
  KeyboardEventTypes,
  Scene,
  Vector2,
  Vector3,
} from '@babylonjs/core';
class InputManager {
    private _keys_press: Map<string, boolean> = new Map();
    public attachScene(scene: Scene) {
        scene.onKeyboardObservable.add((kbInfo) => {
          switch (kbInfo.type) {
            case KeyboardEventTypes.KEYDOWN:
              this._keys_press.set(kbInfo.event.key, true);
              break;
            case KeyboardEventTypes.KEYUP:
              this._keys_press.set(kbInfo.event.key, false);
              break;
          }
        });
   }
}

逻辑说明:

  1. 事件监听:

    • scene.onKeyboardObservable.add 用于监听键盘事件。每当有键盘事件发生时,回调函数会被调用,kbInfo 包含了事件的详细信息。
  2. 事件类型判断:

    • kbInfo.type 用于判断事件类型。KeyboardEventTypes.KEYDOWN 表示按键被按下,KeyboardEventTypes.KEYUP 表示按键被释放。
  3. 按键状态更新:

    • 当按键被按下时(KEYDOWN),将 _keys_press 中对应按键的状态设置为 true。

    • 当按键被释放时(KEYUP),将 _keys_press 中对应按键的状态设置为 false。

2、判断按键是否按下
class InputManager {
  // ... 省略上面的代码
  public isKeyPressed(key: string): boolean {
    return this._keys_press.get(key) || false;
  }
}

isKeyPressed 就干了一件事:通过入参(按键wasd)判断其是否按下,下面的代码会用到

3、将WASD转换为方向向量
class InputManager {
   // ... 省略上面的代码
   private _wsadDirection: Vector3 = new Vector3(0, 0, 0);
   public wsadToDirection(): Vector3 {
        const v = this._wsadDirection;
        v.set(0, 0, 0);
        if (this.isKeyPressed('w')) {
          v.z = 1;
        }
        if (this.isKeyPressed('s')) {
          v.z = -1;
        }
        if (this.isKeyPressed('a')) {
          v.x = -1;
        }
        if (this.isKeyPressed('d')) {
          v.x = 1;
        }
        // 归一化
        v.normalize();
        return v;
      }
}

逻辑说明:

  1. 初始化向量:

    • v.set(0, 0, 0); 将 _wsadDirection 向量重置为零向量,以确保每次计算时不受之前状态的影响。
  2. 方向判断:

    • isKeyPressed('w'):如果 W 键被按下,设置 v.z = 1,表示向前移动。

    • isKeyPressed('s'):如果 S 键被按下,设置 v.z = -1,表示向后移动。

    • isKeyPressed('a'):如果 A 键被按下,设置 v.x = -1,表示向左移动。

    • isKeyPressed('d'):如果 D 键被按下,设置 v.x = 1,表示向右移动。

  3. 向量归一化:

    • v.normalize(); 将向量 v 归一化,使其长度为1。这是为了确保无论按下多少个键,移动的速度保持一致。比如:同时按下W和D键,假如不将其归一化,那么在这个向量上的移动速度就明显快于单个按键的移动速度,不信可以试试。
  4. 返回向量:

    • 返回计算后的方向向量 v,用于在游戏中确定角色或物体的移动方向。

总结:键盘交互的核心是通过监听键盘事件将按键转换为方向向量,以供逻辑帧使用。