键盘交互(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;
}
});
}
}
逻辑说明:
-
事件监听:
- scene.onKeyboardObservable.add 用于监听键盘事件。每当有键盘事件发生时,回调函数会被调用,kbInfo 包含了事件的详细信息。
-
事件类型判断:
- kbInfo.type 用于判断事件类型。KeyboardEventTypes.KEYDOWN 表示按键被按下,KeyboardEventTypes.KEYUP 表示按键被释放。
-
按键状态更新:
-
当按键被按下时(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;
}
}
逻辑说明:
-
初始化向量:
- v.set(0, 0, 0); 将 _wsadDirection 向量重置为零向量,以确保每次计算时不受之前状态的影响。
-
方向判断:
-
isKeyPressed('w'):如果 W 键被按下,设置 v.z = 1,表示向前移动。
-
isKeyPressed('s'):如果 S 键被按下,设置 v.z = -1,表示向后移动。
-
isKeyPressed('a'):如果 A 键被按下,设置 v.x = -1,表示向左移动。
-
isKeyPressed('d'):如果 D 键被按下,设置 v.x = 1,表示向右移动。
-
-
向量归一化:
- v.normalize(); 将向量 v 归一化,使其长度为1。这是为了确保无论按下多少个键,移动的速度保持一致。比如:同时按下W和D键,假如不将其归一化,那么在这个向量上的移动速度就明显快于单个按键的移动速度,不信可以试试。
-
返回向量:
- 返回计算后的方向向量 v,用于在游戏中确定角色或物体的移动方向。