Cocos2d-x的事件分发教程(二)

2015年03月23日 12:48 0 点赞 0 评论 更新于 2025-11-21 18:15

当订阅者成功注册到事件分发器后,事件分发器需要依据接收到的相应事件进行分发操作。本节课将着重讲解如何进行事件分发。

教学视频

(此处应补充教学视频的相关链接或说明)

课程笔记

事件的触发

事件的触发可通过 dispatchEvent 或者 dispatchCustomEvent 函数来实现。dispatchCustomEvent 会自动创建一个 CustomEvent;也可以先手动创建一个 CustomEvent 类型的事件对象,然后使用 dispatchEvent 方法来触发该事件。

事件的分发

dispatchEvent 函数中,主要完成了对 listenerID 对应订阅者的排序工作,按照排序后的顺序依次调用订阅者的回调函数,最后更新事件分发的状态。

在对 listenerID 对应订阅者进行排序时,具体步骤如下:

  1. 首先将优先级列表按照从小到大的顺序排列。
  2. 找到第一个优先级大于 0 的订阅者索引。
  3. 接着将 Node 对应的订阅者列表按照绘制顺序进行排序。

需要注意的是,频繁排序会导致性能问题。为了解决这个问题,EventDispather 采用了做标记的方法。当对做了标记的 listenerID 进行变动时,就会重新进行排序;否则,不会进行重新排序。在以下函数中会进行标记操作:setLocalZOrdersetGlobalZOrdersetPriorityforceAddEventListenerremoveEventListener。如果关联的 Node 或者关联 Node 的父类 Node 发生 Z 变换,也需要重新排序。

事件允许嵌套,即在事件的回调函数中可以调用 dispatchEvent 触发另外一个事件。在函数中通过 DispatchGuard guard(_inDispatch); 进行标记,其中 _inDispatch 初始值为 0,在进行 dispatch 操作时加 1,当该标记的生命周期结束时减 1。需要特别注意的是,在嵌套事件中不能执行相同的事件,否则会导致死循环。

在事件分发的过程中,优先级高的订阅者可以通过 eventstopPropagation 方法选择让事件停止传播。

订阅者的修改

  • 优先级修改:在事件分发的过程中修改订阅者的优先级,该修改会在下一次触发事件时生效。
  • 状态修改:通过 setEnablesetPausesetRegistered 方法对订阅者状态进行修改,这些修改会即时生效。
  • 订阅者删除:在事件分发的过程中删除订阅者,只是将其标记为 setRegistered(false),在分发结束时才会真正将其从订阅者列表中移除。
  • 订阅者添加:在事件分发的过程中添加订阅者,只是将其加入临时数组 _toAddedListeners,在所有事件分发结束后,才会将其加入订阅者列表。

事件与 Node

  • 当调用 NodeonExit 方法时,会调用 Node 及其子 Nodepause 函数。在 pause 函数中,会调用 pauseEventListenersForTarget 方法。
  • 当调用 NodeOnEnter 方法时,会调用 Node 及其子 Noderesume 函数。在 resume 函数中,会调用 resumeEventListenersForTarget 方法。
  • 删除 Node 时,会自动移除和该 Node 相关的订阅者。

作者信息

boke

boke

共发布了 3994 篇文章