【Laya】InputManager 输入管理器
Laya.InputManager 输入管理模块摘要 Laya.InputManager 是 LayaAir 引擎的核心输入事件管理类,负责处理鼠标、触摸和键盘等交互事件。主要功能包括: 输入控制开关:支持多点触控、鼠标/触摸事件、键盘事件的独立开关配置 输入状态检测:提供鼠标位置、触摸点数量、键盘按键状态等实时信息 碰撞检测:支持2D/3D场景下的点击测试,需注意手动设置Sprite尺寸 事件预
Laya.InputManager 输入管理器
版本: v3.3.6 | 模块:
laya/events/InputManager
概述
Laya.InputManager 是 LayaAir 引擎的输入事件管理类,负责处理鼠标、触摸和键盘等输入事件。
静态属性
开关控制
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
multiTouchEnabled |
boolean |
true |
是否开启多点触控支持 |
mouseEventsEnabled |
boolean |
true |
是否开启鼠标/触摸事件 |
keyEventsEnabled |
boolean |
true |
是否开启键盘事件 |
clickTestThreshold |
number |
10 |
鼠标按下和弹起位置距离阈值,超过此值不视为点击 |
鼠标位置
| 属性 | 类型 | 说明 |
|---|---|---|
mouseX |
number |
canvas 上鼠标的 X 坐标 |
mouseY |
number |
canvas 上鼠标的 Y 坐标 |
lastMouseTime |
number |
上一次鼠标事件的时间 |
触摸相关
| 属性 | 类型 | 说明 |
|---|---|---|
touchCount |
number (只读) |
当前触摸数量 |
touches |
TouchInfo[] (只读) |
当前触摸信息数组 |
touchTarget |
Node (只读) |
当前触摸目标节点 |
lastTouchId |
number |
上一次触摸事件的 ID |
回调
| 属性 | 类型 | 说明 |
|---|---|---|
onMouseDownCapture |
Delegate (只读) |
在处理 MOUSE_DOWN 事件之前调度,可用于预处理按下事件 |
静态方法
实例获取
static get inst(): InputManager
获取 InputManager 单例实例。
触摸位置
static getTouchPos(touchId?: number): Point
获取指定触摸点的位置。
参数:
touchId: 触摸点 ID,不提供则返回lastTouchId对应的触摸点位置
返回: Point - 触摸点的位置
键盘检测
static hasKeyDown(key: string | number): boolean
返回指定键是否被按下。
参数:
key: 键值(支持key字符串或keyCode数字)
返回: boolean - 是否被按下
常用键值:
| 按键 | key 值 | keyCode | 按键 | key 值 | keyCode |
|---|---|---|---|---|---|
| W | "w" |
87 |
A | "a" |
65 |
| S | "s" |
83 |
D | "d" |
68 |
| 空格 | " " |
32 |
ESC | "Escape" |
27 |
| Shift | "Shift" |
16 |
Enter | "Enter" |
13 |
取消点击
static cancelClick(touchId?: number): void
取消指定触摸点的点击事件(将 clickCancelled 设为 true)。
参数:
touchId: 要取消的触摸事件 ID,不提供则使用lastTouchId
实例方法
获取节点
getNodeUnderPoint(x: number, y: number): Node
获取指定坐标下的节点。
参数:
x: X 坐标值(已除以clientScaleX)y: Y 坐标值(已除以clientScaleY)
返回: Node - 该点下的节点,如果没有找到节点则返回舞台
getSpriteUnderPoint(sp: Sprite, x: number, y: number): Sprite
获取在相对 Sprite 指定坐标下的 Sprite。
getSprite3DUnderPoint(x: number, y: number): Node
获取 3D 场景中指定坐标下的 3D 节点(源码中返回 null,由子类实现)。
碰撞检测
hitTest(sp: Sprite, x: number, y: number, editing?: boolean): boolean
检测指定坐标是否命中 Sprite。
命中规则(源码逻辑):
if (sp.width > 0 && sp.height > 0 || mouseThrough || hitArea) {
if (!mouseThrough)
isHit = (0, 0, sp.width, sp.height).contains(x, y);
else
isHit = sp.getGraphicBounds(false).contains(x, y);
}
重要说明
graphics 绘图必须设置 size
使用 graphics.drawCircle、graphics.drawRect 等方法绘制的内容不会自动设置 Sprite 的宽高。
hitTest 方法检测条件: sp.width > 0 && sp.height > 0
因此必须手动调用 size() 设置宽高,否则鼠标事件无法正确检测。
// ❌ 错误:width=0, height=0,hitTest 返回 false
const sprite = new Laya.Sprite();
sprite.graphics.drawRect(0, 0, 100, 100, "#FF0000");
console.log(sprite.width, sprite.height); // 0, 0
// ✅ 正确:设置 size 后
sprite.size(100, 100);
console.log(sprite.width, sprite.height); // 100, 100
使用示例
示例 1: 鼠标位置追踪
export class MouseTrackExample {
private sprite: Laya.Sprite;
constructor() {
Laya.init(800, 600).then(() => {
this.init();
});
}
private init(): void {
this.sprite = new Laya.Sprite();
this.sprite.graphics.drawCircle(0, 0, 20, "#FF0000");
this.sprite.size(40, 40); // 必须设置 size
Laya.stage.addChild(this.sprite);
Laya.stage.on(Laya.Event.MOUSE_MOVE, this, this.onMouseMove);
}
private onMouseMove(): void {
this.sprite.x = Laya.InputManager.mouseX;
this.sprite.y = Laya.InputManager.mouseY;
}
}
示例 2: 多点触控
export class MultiTouchExample {
private text: Laya.Text;
private touches: Laya.Sprite[] = [];
constructor() {
Laya.init(0, 0).then(() => {
this.init();
});
}
private init(): void {
this.text = new Laya.Text();
this.text.fontSize = 30;
this.text.color = "#FFFFFF";
Laya.stage.addChild(this.text);
Laya.timer.frameLoop(1, this, this.update);
}
private update(): void {
this.text.text = `触控点数量: ${Laya.InputManager.touchCount}`;
for (let i = 0; i < Laya.InputManager.touches.length; i++) {
let touchSprite = this.touches[i];
if (!touchSprite) {
touchSprite = new Laya.Sprite();
touchSprite.graphics.drawCircle(0, 0, 30, "#00FF00");
touchSprite.size(60, 60); // 必须设置 size
Laya.stage.addChild(touchSprite);
this.touches[i] = touchSprite;
}
const pos = Laya.InputManager.getTouchPos(i);
touchSprite.pos(pos.x, pos.y);
}
}
}
示例 3: 键盘控制
export class KeyboardControlExample {
private player: Laya.Sprite3D;
private speed: number = 0.1;
constructor() {
Laya.init(0, 0).then(() => {
this.init();
});
}
private init(): void {
// 创建玩家对象...
Laya.timer.frameLoop(1, this, this.onUpdate);
}
private onUpdate(): void {
const movement = new Laya.Vector3();
if (Laya.InputManager.hasKeyDown("w")) movement.z -= this.speed;
if (Laya.InputManager.hasKeyDown("s")) movement.z += this.speed;
if (Laya.InputManager.hasKeyDown("a")) movement.x -= this.speed;
if (Laya.InputManager.hasKeyDown("d")) movement.x += this.speed;
if (movement.length() > 0) {
this.player.transform.translate(movement);
}
}
}
示例 4: 取消点击判定
export class CancelClickExample {
private sprite: Laya.Sprite;
constructor() {
Laya.init(800, 600).then(() => {
this.init();
});
}
private init(): void {
this.sprite = new Laya.Sprite();
this.sprite.graphics.drawRect(0, 0, 100, 100, "#FF0000");
this.sprite.size(100, 100);
Laya.stage.addChild(this.sprite);
this.sprite.on(Laya.Event.MOUSE_MOVE, this, () => {
// 鼠标移动时取消点击判定
Laya.InputManager.cancelClick();
});
this.sprite.on(Laya.Event.CLICK, this, () => {
console.log("只有不拖动才会触发");
});
}
}
常见问题
Q: 用 graphics 画图为什么不触发鼠标事件?
必须设置 size(),因为 hitTest 检测条件是 sp.width > 0 && sp.height > 0。
Q: 为什么 hasKeyDown 检测不到按键?
确保 Laya.InputManager.keyEventsEnabled = true。
Q: 如何禁用多点触控?
Laya.InputManager.multiTouchEnabled = false;
Q: 如何判断是点击还是拖拽?
源码中 clickCancelled 在移动距离超过 clickTestThreshold 时设为 true,可通过 Laya.InputManager.cancelClick() 手动取消。
事件流程
源码中的事件处理流程:
-
鼠标事件 (
handleMouse):mousedown→handleMouse(ev, 0)→Event.MOUSE_DOWNmouseup→handleMouse(ev, 1)→Event.MOUSE_UP→Event.CLICKmousemove→handleMouse(ev, 2)→Event.MOUSE_MOVEwheel→handleMouse(ev, 4)→Event.MOUSE_WHEEL
-
触摸事件 (
handleTouch):touchstart→handleTouch(ev, 0)→Event.MOUSE_DOWNtouchend→handleTouch(ev, 1)→Event.MOUSE_UP→Event.CLICKtouchmove→handleTouch(ev, 2)→Event.MOUSE_MOVE
-
键盘事件 (
handleKeys):keydown/keyup→Event.KEY_DOWN/Event.KEY_UP
相关类
| 类 | 说明 |
|---|---|
Laya.Event |
事件类型常量定义 |
Laya.TouchInfo |
触摸信息结构 |
Laya.Keyboard |
键盘事件常量 |
更多推荐
所有评论(0)