输入事件系统
本篇文档我们将介绍在 Cocos Creator 中对全局输入事件的处理。
全局输入事件是指与节点树不相关的各种输入事件,由 input
来统一派发,目前支持了以下几种事件
鼠标事件
触摸事件
键盘事件
设备重力感应事件
定义输入事件
上文提到的输入事件都可以通过input.on(type,callback,target)
来监听,其中 type
是事件类型,callback
是事件回调函数,target
是回调函数的 this
上下文。
鼠标事件
type 类型
Input.EventType.MOUSE_DOWN
Input.EventType.MOUSE_UP
Input.EventType.MOUSE_MOVE
Input.EventType.MOUSE_WHEEL
触摸事件
type 类型
Input.EventType.TOUCH_START
Input.EventType.TOUCH_MOVE
Input.EventType.TOUCH_END
Input.EventType.TOUCH_CANCEL
键盘事件
type 类型
Input.EventType.KEY_DOWN
键盘按下Input.EventType.KEY_UP
键盘释放Input.EventType.KEY_PRESSING
持续按下
设备重力感应事件
type 类型
Input.EventType.DEVICEMOTION
指针事件
指针事件包括 鼠标事件
和 触摸事件
。
使用方法如下
ts
import { _decorator, Component, input, Input, EventTouch } from "cc";
const { ccclass } = _decorator;
@ccclass("Example")
export class Example extends Component {
onLoad() {
input.on(Input.EventType.TOUCH_START, this.onTouchStart, this);
}
onDestroy() {
input.off(Input.EventType.TOUCH_START, this.onTouchStart, this);
}
onTouchStart(event: EventTouch) {
console.log(event.getLocation()); // Location on screen space
console.log(event.getUILocation()); // Location on UI space
}
}
键盘事件
使用方法如下
ts
import {
_decorator,
Component,
input,
Input,
EventKeyboard,
KeyCode,
} from "cc";
const { ccclass } = _decorator;
@ccclass("Example")
export class Example extends Component {
onLoad() {
input.on(Input.EventType.KEY_DOWN, this.onKeyDown, this);
input.on(Input.EventType.KEY_UP, this.onKeyUp, this);
}
onDestroy() {
input.off(Input.EventType.KEY_DOWN, this.onKeyDown, this);
input.off(Input.EventType.KEY_UP, this.onKeyUp, this);
}
onKeyDown(event: EventKeyboard) {
switch (event.keyCode) {
case KeyCode.KEY_A:
console.log("Press a key");
break;
}
}
onKeyUp(event: EventKeyboard) {
switch (event.keyCode) {
case KeyCode.KEY_A:
console.log("Release a key");
break;
}
}
}
设备重力感应事件
使用方法如下
ts
import { _decorator, Component, input, Input, log } from "cc";
const { ccclass } = _decorator;
@ccclass("Example")
export class Example extends Component {
onLoad() {
input.setAccelerometerEnabled(true);
input.on(Input.EventType.DEVICEMOTION, this.onDeviceMotionEvent, this);
}
onDestroy() {
input.off(Input.EventType.DEVICEMOTION, this.onDeviceMotionEvent, this);
}
onDeviceMotionEvent(event: EventAcceleration) {
log(event.acc.x + " " + event.acc.y);
}
}
3D 物体的触摸检测
3D 物体的触摸检测需要通过射线检测来实现。
具体做法是通过渲染 3D 物体的 Camera 到触点的屏幕坐标,生成一条射线,判断射线是否穿过想要检测的对象。具体代码实现如下:
ts
import {
_decorator,
Component,
Node,
Camera,
geometry,
input,
Input,
EventTouch,
PhysicsSystem,
} from "cc";
const { ccclass, property } = _decorator;
@ccclass("Example")
export class Example extends Component {
// Specify the camera rendering the target node.
@property(Camera)
readonly cameraCom!: Camera;
@property(Node)
public targetNode!: Node;
private _ray: geometry.Ray = new geometry.Ray();
onEnable() {
input.on(Input.EventType.TOUCH_START, this.onTouchStart, this);
}
onDisable() {
input.off(Input.EventType.TOUCH_START, this.onTouchStart, this);
}
onTouchStart(event: EventTouch) {
const touch = event.touch!;
this.cameraCom.screenPointToRay(
touch.getLocationX(),
touch.getLocationY(),
this._ray
);
if (PhysicsSystem.instance.raycast(this._ray)) {
const raycastResults = PhysicsSystem.instance.raycastResults;
for (let i = 0; i < raycastResults.length; i++) {
const item = raycastResults[i];
if (item.collider.node == this.targetNode) {
console.log("raycast hit the target node !");
break;
}
}
} else {
console.log("raycast does not hit the target node !");
}
}
}