事件系统是游戏开发过程中需要涉及到交互常用的功能。使用事件系统不仅可以将输入行为(例如:键盘、鼠标、触摸)以事件的形式发送到应用程序,也可以将游戏过程中的发生的,需要其他对象关注的事情通过事件的形式回应。例如:游戏胜利后需要打开结算或者奖励界面。
监听和发射事件 #
Cocos Creator 引擎提供了 EventTarget 类,用以实现自定义事件的监听和发射,在使用之前,需要先从 'cc' 模块导入,同时需要实例化一个 EventTarget 对象。
import { EventTarget } from 'cc';
const eventTarget = new EventTarget();
注意:虽然
Node对象也实现了一些EventTarget的接口,但是我们不再推荐继续通过Node对象来做自定义事件的监听和发射,因为这样子做不够高效,同时我们也希望Node对象只监听与Node相关的事件。
监听事件 #
// 该事件监听每次都会触发,需要手动取消注册
eventTarget.on(type, func, target?);
其中 type 为事件注册字符串,func 为执行事件监听的回调,target 为事件接收对象。如果 target 没有设置,则回调里的 this 指向的就是当前执行回调的对象。
// 使用函数绑定
eventTarget.on('foo', function ( event ) {
this.enabled = false;
}.bind(this));
// 使用第三个参数
eventTarget.on('foo', (event) => {
this.enabled = false;
}, this);
除了使用 on 监听,我们还可以使用 once 接口。once 监听在监听函数响应后就会关闭监听事件。
取消监听事件 #
off 接口的使用方式有以下两种:
// 取消对象身上所有注册的该类型的事件
eventTarget.off(type);
// 取消对象身上该类型指定回调指定目标的事件
eventTarget.off(type, func, target);
需要注意的是,off 方法的参数必须和 on 方法的参数一一对应,才能完成关闭。
import { _decorator, Component, EventTarget } from 'cc';
const { ccclass } = _decorator;
const eventTarget = new EventTarget();
@ccclass("Example")
export class Example extends Component {
onEnable () {
// 监听
eventTarget.on('foobar', this._sayHello, this);
}
onDisable () {
// 取消监听
eventTarget.off('foobar', this._sayHello, this);
}
_sayHello () {
console.log('Hello World');
}
}
事件发射 #
发射事件可以通过 eventTarget.emit() 接口来实现,方法如下:
// 事件发射的时候可以指定事件参数,参数最多只支持 5 个事件参数
eventTarget.emit(type, ...args);
输入事件系统 #
在 Cocos Creator 3.4.0 中,我们支持了 input 对象,该对象实现了 EventTarget 的事件监听接口,可以通过 input 对象监听全局的系统输入事件。
定义输入事件 #
上文提到的输入事件,都可以通过接口 input.on(type, callback, target) 注册。可选的 type 类型包括:
| 输入事件 | type 类型 |
|---|---|
| 鼠标事件 | Input.EventType.MOUSE_DOWN Input.EventType.MOUSE_MOVE Input.EventType.MOUSE_UP Input.EventType.MOUSE_WHEEL |
| 触摸事件 | Input.EventType.TOUCH_START Input.EventType.TOUCH_MOVE Input.EventType.TOUCH_END Input.EventType.TOUCH_CANCEL |
| 键盘事件 | Input.EventType.KEY_DOWN(键盘按下) Input.EventType.KEY_PRESSING(键盘持续按下) Input.EventType.KEY_UP(键盘释放) |
| 设备重力传感事件 | Input.EventType.DEVICEMOTION |
回调函数参数类型
- 鼠标事件:
EventMouse - 触摸事件:
EventTouch - 键盘事件:
EventKeyboard - 设备重力传感事件:
EventAcceleration
屏幕事件 #
以下是当前支持的全局屏幕事件概述:
| 事件名称 | 描述 | 支持平台 | 支持版本 |
|---|---|---|---|
window-resize |
监听窗口大小变化 | Web, Native, MiniGame | 3.8.0 |
orientation-change |
监听屏幕方向变化 | Web, Native | 3.8.3 |
fullscreen-change |
监听全屏变化 | Web | 3.8.0 |
import { _decorator, Component, screen, macro } from 'cc';
const { ccclass } = _decorator;
@ccclass("Example")
export class Example extends Component {
onLoad() {
// Register event listeners with the screen object
screen.on('window-resize', this.onWindowResize, this);
screen.on('orientation-change', this.onOrientationChange, this);
screen.on('fullscreen-change', this.onFullScreenChange, this);
}
onDestroy() {
// Unregister event listeners when the component is destroyed
screen.off('window-resize', this.onWindowResize, this);
screen.off('orientation-change', this.onOrientationChange, this);
screen.off('fullscreen-change', this.onFullScreenChange, this);
}
onWindowResize(width: number, height: number) {
console.log("Window resized:", width, height);
}
onOrientationChange(orientation: number) {
if (orientation === macro.ORIENTATION_LANDSCAPE_LEFT || orientation === macro.ORIENTATION_LANDSCAPE_RIGHT) {
console.log("Orientation changed to landscape:", orientation);
} else {
console.log("Orientation changed to portrait:", orientation);
}
}
onFullScreenChange(width: number, height: number) {
console.log("Fullscreen change:", width, height);
}
}