OGEngine学习笔记--- 事件传递

事件传递

Android中的事件在表现形式上有很多,如onTouch、onClick和onLongClick等,在具体微观上的表现形势有action_down、action_move和action_up等。

无论哪种事件表现类型,首先都是基于事件的传递模型。其实Android中的事件传递有点类似于JS中事件传递模型。都是基于先捕获然后冒泡的形式。

在OGEngine的API中,OGEngine负责捕获触摸事件,如果我们需要监听触摸事件,则需要向Scene注册。

  1. mScene.registerTouchArea(touchArea);

复制代码

通过查阅ITouchArea的源码发现

  1. public boolean contains(final float pX, final float pY);
  2. public float[] convertSceneToLocalCoordinates(final float pX, final float pY);
  3. public float[] convertLocalToSceneCoordinates(final float pX, final float pY);
  4. public boolean onAreaTouched(final TouchEvent pSceneTouchEvent, final float pTouchAreaLocalX, final float pTouchAreaLocalY);

复制代码

一个区域里有自己的判断当前触摸的坐标是不是属于自己感兴趣的,如果不是则直接抛弃。 
因为Shape类是实现了ITouchArea接口的,所以我们的Sprite等精灵类都可以直接被注册。 
在Scene的源码里可以找到相关的代码,于是我们了解了,在Andengine中,监听触摸和Entity并不是同一个概念,两者是独立的,于是这也解释了,为什么在Scene中detach了一个Entity,在其注册过监听的地方触摸还是会触发和以前一样的效果。

再来关注事件的传递,在源码中我们发现由于事件需要Area本身来判断其是否属于Area,所以在注册的时候并不存在类似Android中的父子关系,传递是根据注册的顺序一个一个进行的,但是相同的是如果一个Area宣布自己处理了时间(返回了true),传递序列就会直接终止,这里和Android中的事件是一样的。 
但是这样固定的顺序会有一些问题,其实设计者已经考虑到了这个问题,于是我们在源码中发现了一个标志量:mOnAreaTouchTraversalBackToFront。 这个标志会决定当前事件的传递是正序还是逆序,这样就在一定程度上解决了我们的问题。

屏幕事件

OnAreaTouchListener的注册

  1. BaseGameActivity.onLoadEngine():生成引擎,设置引擎的参数
  2. BaseGameActivity.startScene():跳转到某个场景中

复制代码

其中会调用setOnTouchListener(),将Engine作为TouchListener注册到scene中。其后所有的屏幕事件就会知道调用Engine的onTouch()方法。

屏幕事件的预处理

Android中的屏幕事件是即时突发,也就是说只要产生了屏幕事件就会在事件线程内直接调用注册监听器的onTouch()方法,如果处理时间过长,Android会直接将程序判定为无响应,并被踢出来。在OGEngine中支持两种响应方式

*即时触发:接受到屏幕事件后立即调用注册的监听器(默认)

优点:和Android一样,容易学习
缺点:需要注意处理时间,超时的话会被判定为无响应
         容易与OGEngine中的UpdateThread线程或描画线程形成资源竞争         
         为了避免竞合,又要做线程安全麻烦,比较复杂

*UpdateThread中触发:接受到屏幕事件后先放入池中,在UpdateThread中统一调用和上面的相反

预处理Flow

Engine.onTouch():判断引擎是否运行中,如果已停止就什么也不做,否则交给mTouchController处理。

SingleTouchControler.onHandleMotionEvent():有两个分支

* 即时触发:

TouchEvent.obtain():生成TouchEvent
mTouchEventCallback.onTouchEvent():响应事件(调用Engine.onTouchEven

*UpdateThread中触发:
TouchEvent.obtain():生成TouchEvent

mTouchEventRunnablePoolUpdateHandler.obtainPoolItem():生成事件处理对象
      事件处理对象就是在run()方法中通过mTouchEventCallback.onTouchEvent()响应事件
touchEventRunnablePoolItem.set(touchEvent):设定屏幕事件
mTouchEventRunnablePoolUpdateHandler.postPoolItem:放入事件池中
Engine.onUpdate中调用mTouchController.onUpdate()执行事件处理

屏幕事件处理

a) Engine.onTouchEvent():屏幕事件处理入口

b) Camera.convertSurfaceToSceneTouchEvent():坐标变换

c) Engine.onTouchScene():处理Scene屏幕事件(遍历注册的TouchArea,找到合适的就调用对应的处理监听器,如果没有就调用Scene的监听器Scene的屏幕处理中有三个比较有意思的属性:
  mOnAreaTouchTraversalBackToFront:事件的响应顺序是从后往前,还是调过来。默认是从后往前
  mTouchAreaBindingEnabled:当监听到ACTION_DOWN事件后是否需要绑定。绑定的意思是说到ACTION_UP或ACTION_CANCEL为止的事件全部交给这个监听器处理。
  mOnSceneTouchListenerBindingEnabled:和上一次差不多,这笔绑定的对象是Scene的监听器

http://www.eoeandroid.com/forum-863-1.html

www.ogengine.com

OGEngine学习笔记--- 事件传递

时间: 2024-10-29 19:08:04

OGEngine学习笔记--- 事件传递的相关文章

OGEngine学习笔记---资源加载

声音管理兼容各种音频文件格式,比特率和样本率 OGEngine开源引擎兼容各种音频视频文件格式,并且引用了硬件加速技术,来对音频文件进行io读取,简化了资源的加载和读取写入的过程,大幅度减少应用卡顿.无响应的状况出现. 一个背景音乐 多个音效 OGEngine开源引擎在同一时间只能播放一首背景音乐,但是能同时播放多个音效. 首先自定义一个枚举类ConfigData,用来存放背景音乐key和音效key. public class ConfigData { /** 背景音乐*/ public sta

angularjs学习笔记—事件指令

angularjs学习笔记—事件指令 小俞 4.4k 3月30日 发布 推荐 4 推荐 收藏 17 收藏,11.1k 浏览 ngClick 适用标签:所有触发条件:单击 #html <div ng-controller="LearnCtrl"> <div ng-click="click()">click me</div> <button ng-click="click()">click me<

JS学习笔记-事件绑定

一.传统事件模型 传统事件模型中存在局限性. 内联模型以HTML标签属性的形式使用,与HTML混写,这种方式无疑造成了修改以及扩展的问题,已经很少使用了. 脚本模型是将事件处理函数写到js文件中,从页面获取元素进行对应事件函数的绑定以触发执行.但也存在不足之处: 1.一个事件绑定多个事件监听函数,后者将覆盖前者. 2.需要限制重复绑定的情况 3.标准化event对象 二.现代事件绑定 DOM2级事件定义了两个方法用于添加.删除事件:addEventListener().removeEventLi

js学习笔记-事件代理

通过事件代理,你可以把事件处理器绑定到父元素上,避免了把事件处理器添加到多个子级元素上.从而优化性能. 事件代理用到了事件冒泡和目标元素.而任何一个元素的目标元素都是一开始的那个元素. 这里首先要注意event的target与currentTarget的区别. target:表示触发事件的元素.currentTarget:表示事件绑定的元素. 只有当事件流处在目标阶段的时候,两个的指向才是一样的, 而当处于捕获和冒泡阶段的时候,target指向被单击的对象而currentTarget指向当前事件

Pyqt4学习笔记-事件和信号

调用应用的 exec_() 方法之后,应用进入主循环.主循环获取事件并把它们发往对象.应用在它的生命周期中产生的不同事件交互.事件主要由用户产生,但是它们也可以由其他方式产生,如:互联网,窗口管理器,定时器,当一个特殊的事件发生时,将发射信号,“槽 ”可以是任何Python调用,当链接到槽的信号发射,该槽将被调用. 在事件模型中,有三个参与者:event source:事件源,事件来源对象代理了事件的目标要处理的任务event object:事件对象,指状态改变的对象,它产生了事件. 事件对象

JavaScript 学习笔记— —事件委托

<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title></title> <script type="text/javascript"> //事件委托:利用冒泡的原理,把事件加到父级上,触发执行效果 //好处 //1.提高性能 //2.新添加的元素,还会有之前的事件 //event

Vue2学习笔记:事件对象、事件冒泡、默认行为

1.事情对象 <!DOCTYPE html> <html> <head> <title></title> <meta charset="utf-8"> <script src="http://unpkg.com/vue/dist/vue.js"></script> <script type="text/javascript"> window

JavaScript学习笔记——事件

javascript事件基础和事件绑定 一.事件驱动 1.事件 javascript侦测到的用户的操作或是页面的一些行为(怎么发生的) 2.事件源 引发事件的元素.(发生在谁的身上)3.事件处理程序 对事件处理的程序或是函数 (发生了什么事) 二.事件的分类 1.鼠标事件 onclick ondblclick onmousedowm onmouseup onmousemove onmouseover onmouseout 2.键盘事件 onkeyup onkeydown onkeypress 鼠

jquery学习笔记-----事件和动画

一.ready机制 $(document).ready( function(){} ) $().ready( function(){} ) $( function(){} )  jquery的ready函数会在dom准备完毕后执行,并且可以多次使用 $(selector).load( function(){} ) 此方法相当于js自身的onload方法 如 $(window).load(function(){})    相当于  window.onload=function(){} ------