Cocos Creator 3.0 基础——事件系统
Posted 许英俊
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Cocos Creator 3.0 基础——事件系统相关的知识,希望对你有一定的参考价值。
触摸事件
触摸事件指的是用户手指触摸时候的事件
- TOUCH_START:当手指触点落在目标节点区域内时。
- TOUCH_MOVE:当手指在屏幕上移动时。
- TOUCH_END:当手指在目标节点区域内离开屏幕时。
- TOUCH_CANCEL:当手指在目标节点区域外离开屏幕时。
//绑定事件
this.node.on(SystemEvent.EventType.TOUCH_START, this._touchStart, this);
this.node.on(SystemEvent.EventType.TOUCH_END, this._touchEnd, this);
this.node.on(SystemEvent.EventType.TOUCH_MOVE, this._touchMove, this);
this.node.on(SystemEvent.EventType.TOUCH_CANCEL, this._touchCancel, this);
//解除事件
this.node.off(SystemEvent.EventType.TOUCH_START, this._touchStart, this);
this.node.off(SystemEvent.EventType.TOUCH_END, this._touchEnd, this);
this.node.off(SystemEvent.EventType.TOUCH_MOVE, this._touchMove, this);
this.node.off(SystemEvent.EventType.TOUCH_CANCEL, this._touchCancel, this);
//事件回调
_touchMove(touch: Touch, event: EventTouch)
_touchStart(touch: Touch, event: EventTouch)
_touchEnd(touch: Touch, event: EventTouch)
_touchCancel(touch: Touch, event: EventTouch)
键盘事件
键盘事件指的是用户在键盘上输入的事件,他可以同时按下多个键盘,并要完成多个事件的响应
- SystemEventType.KEY_DOWN:键盘按下
- SystemEventType.KEY_UP:键盘释放
//绑定事件
systemEvent.on(SystemEventType.KEY_DOWN, this.onKeyDown, this);
systemEvent.on(SystemEventType.KEY_UP, this.onKeyUp, this);
//解除事件
systemEvent.off(SystemEventType.KEY_DOWN, this.onKeyDown, this);
systemEvent.off(SystemEventType.KEY_UP, this.onKeyUp, this);
//事件回调
onKeyDown(event: EventKeyboard)
onKeyUp(event: EventKeyboard)
监听键盘wasd,控制人物往前后左右运动
export class CubeCtrl extends Component
body: RigidBody = null
keyMask = 0
speed = 50
start()
this.body = this.node.getComponent(RigidBody)
systemEvent.on(SystemEventType.KEY_DOWN, this.onKeyDown, this);
systemEvent.on(SystemEventType.KEY_UP, this.onKeyUp, this);
onKeyDown(event: EventKeyboard)
switch (event.keyCode)
case macro.KEY.a:
this.keyMask |= (1 << 0)
break;
case macro.KEY.s:
this.keyMask |= (1 << 1)
break;
case macro.KEY.w:
this.keyMask |= (1 << 2)
break;
case macro.KEY.d:
this.keyMask |= (1 << 3)
break;
case macro.KEY.space:
this.keyMask |= (1 << 4)
break;
onKeyUp(event: EventKeyboard)
switch (event.keyCode)
case macro.KEY.a:
this.keyMask &= ~(1 << 0)
break;
case macro.KEY.s:
this.keyMask &= ~(1 << 1)
break;
case macro.KEY.w:
this.keyMask &= ~(1 << 2)
break;
case macro.KEY.d:
this.keyMask &= ~(1 << 3)
break;
case macro.KEY.space:
this.keyMask &= ~(1 << 4)
break;
update(deltaTime: number)
if (this.keyMask & (1 << 0))
var pos = this.node.getPosition()
this.body.applyForce(v3(this.speed, 0, 0))
if (this.keyMask & (1 << 3))
var pos = this.node.getPosition()
this.body.applyForce(v3(-this.speed, 0, 0))
if (this.keyMask & (1 << 1))
var pos = this.node.getPosition()
this.body.applyForce(v3(0, 0, -this.speed))
if (this.keyMask & (1 << 2))
var pos = this.node.getPosition()
this.body.applyForce(v3(0, 0, this.speed))
if (this.keyMask & (1 << 4))
var pos = this.node.getPosition()
this.body.applyForce(v3(0, this.speed, 0))
触发事件
触发事件属于两个物体触碰后触发,其事件触发的前提
- 需要配置物理系统分组
- 需要有刚体组件才可触发
- 需要刚体组件勾选
IsTrigger
选项才可触发
触发事件类型
- onTriggerEnter:触发开始
- onTriggerStay:触发保持
- onTriggerExit:触发结束
//绑定事件
onEnable()
const collision = this.getComponent(Collider)
collision.on('onTriggerEnter', this._onTriggerEnter, this);
collision.on('onTriggerStay', this._onTriggerStay, this);
collision.on('onTriggerExit', this._onTriggerExit, this);
//解除事件
onDisable()
const collision = this.getComponent(Collider)
collision.off('onTriggerEnter', this._onTriggerEnter, this);
collision.off('onTriggerStay', this._onTriggerStay, this);
collision.off('onTriggerExit', this._onTriggerExit, this);
//触发事件掩码
public static CollisionT =
SELF_PLANE: 1 << 1,
ENEMY_PLANE: 1 << 2,
SELF_BULLET: 1 << 3,
ENEMY_BULLET: 1 << 4
//触发事件回调,通过掩码判断是哪个物体
_onTriggerEnter(event: ITriggerEvent)
const group = event.otherCollider.getGroup()
const name = event.selfCollider.node.name
if (group === Constants.CollisionT.ENEMY_BULLET || group === Constants.CollisionT.ENEMY_PLANE)
2D碰撞事件
组件要使用Collider2D类型,2D事件有全局的监听
// 注册全局碰撞回调函数
if (PhysicsSystem2D.instance)
PhysicsSystem2D.instance.on(Contact2DType.BEGIN_CONTACT, this.onBeginContact, this);
PhysicsSystem2D.instance.on(Contact2DType.END_CONTACT, this.onEndContact, this);
PhysicsSystem2D.instance.on(Contact2DType.PRE_SOLVE, this.onPreSolve, this);
PhysicsSystem2D.instance.on(Contact2DType.POST_SOLVE, this.onPostSolve, this);
2D事件有组件的监听
//绑定事件
onEnable()
// 注册单个碰撞体的回调函数
let collider = this.getComponent(Collider2D);
if (collider)
collider.on(Contact2DType.BEGIN_CONTACT, this.onBeginContact, this);
collider.on(Contact2DType.END_CONTACT, this.onEndContact, this);
collider.on(Contact2DType.PRE_SOLVE, this.onPreSolve, this);
collider.on(Contact2DType.POST_SOLVE, this.onPostSolve, this);
//解除事件
onDisable()
let collider = this.getComponent(Collider2D);
if (collider)
collider.off(Contact2DType.BEGIN_CONTACT, this.onBeginContact, this);
collider.off(Contact2DType.END_CONTACT, this.onEndContact, this);
collider.off(Contact2DType.PRE_SOLVE, this.onPreSolve, this);
collider.off(Contact2DType.POST_SOLVE, this.onPostSolve, this);
//触发事件回调
onBeginContact (selfCollider: Collider2D, otherCollider: Collider2D, contact: IPhysics2DContact | null)
// 只在两个碰撞体开始接触时被调用一次
console.log('onBeginContact');
onEndContact (selfCollider: Collider2D, otherCollider: Collider2D, contact: IPhysics2DContact | null)
// 只在两个碰撞体结束接触时被调用一次
console.log('onEndContact');
onPreSolve (selfCollider: Collider2D, otherCollider: Collider2D, contact: IPhysics2DContact | null)
// 每次将要处理碰撞体接触逻辑时被调用
console.log('onPreSolve');
onPostSolve (selfCollider: Collider2D, otherCollider: Collider2D, contact: IPhysics2DContact | null)
// 每次处理完碰撞体接触逻辑时被调用
console.log('onPostSolve');
3D碰撞事件
碰撞事件属于两个物体碰撞后触发,其事件触发的前提
- 需要配置物理系统分组
- 需要有刚体组件才可触发
- 静态类型的刚体之间不会产生碰撞数据
触发事件类型
- onCollisionEnter:碰撞开始
- onCollisionStay:碰撞保持
- onCollisionExit:碰撞结束
//绑定事件
onEnable()
const collision = this.getComponent(Collider)
collision.on('onCollisionEnter', this._onCollisionEnter, this);
collision.on('onCollisionStay', this._onCollisionStay, this);
collision.on('onCollisionExit', this._onCollisionExit, this);
//解除事件
onDisable()
const collision = this.getComponent(Collider)
collision.off('onCollisionEnter', this._onCollisionEnter, this);
collision.off('onCollisionStay', this._onCollisionStay, this);
collision.off('onCollisionExit', this._onCollisionExit, this);
//触发事件掩码
public static CollisionT =
SELF_PLANE: 1 << 1,
ENEMY_PLANE: 1 << 2,
SELF_BULLET: 1 << 3,
ENEMY_BULLET: 1 << 4
//触发事件回调,通过掩码判断是哪个物体
_onCollisionEnter(event: ICollisionEvent)
const group = event.otherCollider.getGroup()
const name = event.selfCollider.node.name
if (group === Constants.CollisionT.ENEMY_BULLET || group === Constants.CollisionT.ENEMY_PLANE)
3D模型点击事件
3D模型需要创建射线去射到碰撞体上,才能实现点击物体,物体上需要有Collision
组件才行
@property( type: Camera, tooltip: '主相机' )
public mainCamera: Camera | null = null;
@property( type: Node, tooltip: '待触摸物体' )
public node_touch_1: Node | null = null;
private _ray: geometry.Ray = new geometry.Ray();
onLoad()
systemEvent.on(SystemEventType.TOUCH_START, this.onTouchStart, this);
onDestory()
systemEvent.off(SystemEventType.TOUCH_START, this.onTouchStart, this);
onTouchStart(touch: Touch, event: EventTouch)
// 基于摄像机 画射线
this.mainCamera?.screenPointToRay(event.getLocation().x, event.getLocation().y, this._ray);
// 基于物理碰撞器的射线检测
// 当点击 node_touch_1 时,控制台打印 “node_touch_1”
if (PhysicsSystem.instance.raycast(this._ray))
const r = PhysicsSystem.instance.raycastResults;
for (let index = 0; index < r.length; index++)
const element = r[index];
console.log('当前点击: ' + element.collider.node.uuid);
if (element.collider.node.uuid == this.node_touch_1?.uuid)
以上是关于Cocos Creator 3.0 基础——事件系统的主要内容,如果未能解决你的问题,请参考以下文章