我们的山寨Starling版本将会在这里停止更新了,主要还是由于时间比较有限,而且我们的山寨版本也很好的完成了他的任务“了解Starling的核心渲染”,接下来的Starling解析我们将会直接阅读Starling的源码来了解其它的内部运行方式。

Touch事件体系无疑是除了核心渲染外最重要的东西了,我们笔记中的Touch事件体系是基于Starling v1.1来解读的。

Touch事件体系简介:

在Starling的承继关系里是没有InteractiveObject类,因此所有的显示对象都默认具有交互功能。也就是说DisplayObject是定义了交互行为的。

我们看看主要的类的功能:

  • TouchEvent:Touch事件类,Starling中将原生的鼠标和触摸事件都统一封装成TouchEvent类,这样可以保证PC开发和移动端运行时的一致性,而不同于原生事件,TouchEvent的事件类型仅有一个“TouchEvent.TOUCH”。
  • Touch:一个Touch对象包含了在屏幕上的一个手指或鼠标的相关详细信息,如果是多点触控,则会存在多个Touch对象。
  • TouchPhase:因为TouchEvent只有一个事件类型“TOUCH”,那么我们要区分具体的情况(按下、移动和弹起等)就需要使用Touch对象的phase属性了,而TouchPhase则定义了phase属性存在的值。
  • TouchProcessor:Touch事件体系核心处理类,也是我们接下来要核心解读的类。
  • TouchMarker:内部使用,PC模拟多点触控时的显示对象。

Touch事件处理流程:

Starling中持有一个TouchProcessor类的实例“mTouchProcessor”,该类用来统一处理所有的Touch事件。

还需要注意的一点是,Touch事件会有"延迟",因为Starling捕获到原生Flash层的事件之后,不会马上派发给侦听Starling事件的对象,而是先发送内部的“队列”里面,然后根据帧频,进行集中处理。不过一般我们的帧频不会设置的太小,这个延迟对用户基本没有影响。

原生事件注册:

Starling类启动时会对Stage进行事件注册:

 public function Starling(xxx)
{
...
// register touch/mouse event handlers
for each (var touchEventType:String in touchEventTypes)
stage.addEventListener(touchEventType, onTouch, false, 0, true);
...
} private function get touchEventTypes():Array
{
return Mouse.supportsCursor || !multitouchEnabled ?
[ MouseEvent.MOUSE_DOWN, MouseEvent.MOUSE_MOVE, MouseEvent.MOUSE_UP ] :
[ TouchEvent.TOUCH_BEGIN, TouchEvent.TOUCH_MOVE, TouchEvent.TOUCH_END ];
}

我们可以看到会根据是否支持鼠标和是否开启多点触控来选择注册的事件类型,而所有事件的处理都交给onTouch方法。

onTouch方法处理:

 private function onTouch(event:Event):void
{
if (!mStarted) return; var globalX:Number;
var globalY:Number;
var touchID:int;
var phase:String; // figure out general touch properties
if (event is MouseEvent)
{
var mouseEvent:MouseEvent = event as MouseEvent;
globalX = mouseEvent.stageX;
globalY = mouseEvent.stageY;
touchID = 0; // MouseEvent.buttonDown returns true for both left and right button (AIR supports
// the right mouse button). We only want to react on the left button for now,
// so we have to save the state for the left button manually.
if (event.type == MouseEvent.MOUSE_DOWN) mLeftMouseDown = true;
else if (event.type == MouseEvent.MOUSE_UP) mLeftMouseDown = false;
}
else
{
var touchEvent:TouchEvent = event as TouchEvent;
globalX = touchEvent.stageX;
globalY = touchEvent.stageY;
touchID = touchEvent.touchPointID;
} // figure out touch phase
switch (event.type)
{
case TouchEvent.TOUCH_BEGIN: phase = TouchPhase.BEGAN; break;
case TouchEvent.TOUCH_MOVE: phase = TouchPhase.MOVED; break;
case TouchEvent.TOUCH_END: phase = TouchPhase.ENDED; break;
case MouseEvent.MOUSE_DOWN: phase = TouchPhase.BEGAN; break;
case MouseEvent.MOUSE_UP: phase = TouchPhase.ENDED; break;
case MouseEvent.MOUSE_MOVE:
phase = (mLeftMouseDown ? TouchPhase.MOVED : TouchPhase.HOVER); break;
} // move position into viewport bounds
globalX = mStage.stageWidth * (globalX - mViewPort.x) / mViewPort.width;
globalY = mStage.stageHeight * (globalY - mViewPort.y) / mViewPort.height; // enqueue touch in touch processor
mTouchProcessor.enqueue(touchID, phase, globalX, globalY);
}

onTouch方法中会区分原生鼠标事件和Touch事件,同时会获取到一些基础的信息(如全局坐标等)。

最终,会将收集到的核心信息调用mTouchProcessor.enqueue方法加入待处理队列。

Touch事件处理和抛出:

mTouchProcessor.enqueue方法收集每帧需要处理的事件,注意这个时候只是得到原生stage的一些鼠标或触摸的信息。

最终生成Starling的Touch事件是在Starling的onEnterFrame方法中调用的advanceTime方法中:

 private function advanceTime():void
{
var now:Number = getTimer() / 1000.0;
var passedTime:Number = now - mLastFrameTimestamp;
mLastFrameTimestamp = now; mStage.advanceTime(passedTime);
mJuggler.advanceTime(passedTime);
mTouchProcessor.advanceTime(passedTime);
}

我们发现在处理完毕stage和动画的advanceTime方法后,紧接着就是处理mTouchProcessor的advanceTime方法。注意Starling的所有Touch事件抛出都是在该方法中执行的。而这里执行完毕后就会执行渲染,所以如果我们在Touch事件中改变对象的状态是在本帧就能看到效果的。

mTouchProcessor的advanceTime方法会处理收集的所有Touch事件消息,清理旧的Tap标记(因为Tap操作需要较长的生命周期,所以额外处理),更新已有的Touch对象;将mQueue排队的事件参数进行处理,产生新的Touch对象(通过hitTest方法寻找到该全局坐标下的target目标),并且如果需要的话,让这个Touch事件所对应的对象来派发这个事件。

Touch事件的使用:

1.对需要进行Touch监听的对象进行事件侦听:

 sprite.addEventListener(TouchEvent.TOUCH, onTouch);

2.在onTouch方法中处理:

 private function onTouch(e:TouchEvent):void
{
//获取多个Touch对象,一个对象对应一个触碰,如果存在多个对象则表示是多点触碰
var touches:Vector.<Touch> = e.touches;
//只有一个触碰
if(touches.length == 1)
{
//...
}
//两个触碰
if(touches.length == 2)
{
//...
}
}

3.获取到的具体的Touch对象中包含需要的详细信息;

我这里只是简单的带过使用方法,更多详细的使用方法可以查看下面的电子书:

http://www.starlinglib.com/wiki/OutsideDocs.html

【Stage3D学习笔记续】山寨Starling(十一):Touch事件体系的更多相关文章

  1. 【Stage3D学习笔记续】山寨Starling(三):Starling核心渲染流程

    这篇文章我们剔除Starling的Touch事件体系和动画体系,专门来看看Starling中的渲染流程实现,以及其搭建的显示列表结构. 由于Starling是模仿Flash的原生显示列表,所以我们可以 ...

  2. 【Stage3D学习笔记续】山寨Starling(八):核心优化(批处理)的实现

    批处理是使GPU进行高效绘制的一种技术手段,也是整个渲染流程中最核心的技术,到目前为止我们并没有使用到这种技术手段,下面我们看看我们现在的渲染机制. 先想一想我们最开始是怎么向GPU绘制一幅图像的,可 ...

  3. 【Stage3D学习笔记续】山寨Starling(六):动画实现和测试

    我发布了一个版本v0.2,该版本是未优化版本,且没有添加Touch事件体系,但是由于是最基础且未优化的,所以可以通过参考代码快速的了解实现原理. 接下来的一段笔记开始进行渲染优化,我会把所有的目光都集 ...

  4. 【Stage3D学习笔记续】山寨Starling(十二):总结和一些没提到的东西

    我们的山寨Starling到这里就告一段落了,不得不说这是一个非常优秀的2D框架,他的设计和架构为后来的许多框架都提供了很好的参考,比如现在正在崛起的Egret,我们的一番解读也只是窥见了Starli ...

  5. 【Stage3D学习笔记续】山寨Starling(二):VertexData探幽

    还记得之前的学习笔记中我们的顶点缓冲数组中的顶点数据么,我们使用一个一维数组来记录所有的顶点数据,这是由于顶点缓冲上传数据时是使用的一维数组. 如果对顶点数据进行一层代码的封装,就能更加的方便我们来操 ...

  6. 【Stage3D学习笔记续】山寨Starling(一):从事件说起

    我在GitHub上新开了一个项目:https://github.com/hammerc/hammerc-study-Stage3D 山寨的Starling版本我取名叫做Scorpio2D,以后的笔记中 ...

  7. 【Stage3D学习笔记续】真正的3D世界(一):透视矩阵

    如果各位看官跟着我的学习笔记一路看过来的话,一定会吐槽我的,这都是什么3D啊?从头到尾整个都是在使用GPU绘制一堆2D图像而已,的确,之前我们一直使用正交矩阵利用GPU加速来实现2D世界的展示,算不上 ...

  8. 【Stage3D学习笔记续】山寨Starling(四):渲染代码实现及测试程序

    本章会实现最核心的代码,所以涉及点会比较多,这里会发布一个版本,方便日后的回退查看. 点击下载:https://codeload.github.com/hammerc/hammerc-study-St ...

  9. 【Stage3D学习笔记续】山寨Starling(十):高效游戏设计、纹理集和ATF

    我发布了经过批处理优化的v0.3版,点击下载:https://github.com/hammerc/hammerc-study-Stage3D/archive/v0.3.zip 先看看我们批处理优化后 ...

随机推荐

  1. 落叶枫桥LOGO

    LOGO

  2. atomikos的Jta配置

    配置说明见: http://www.atomikos.com/Documentation/JtaProperties atomikos的一些配置,文档中说明的比较清楚,有两个属性配置不太明确:com. ...

  3. 游标-Oracle游标汇总

    游标(Cursor):用来查询数据库,获取记录集合(结果集)的指针,可以让开发者一次访问一行结果集,在每条结果集上作操作.    游标可分为:    <!--[if !supportLists] ...

  4. 怎么知道RTL Schematic中的instance与哪段代码对应呢

    2013-06-23 20:15:47 ISE综合后可以看到RTL Schematic,但我们知道在RTL编码时,要经常问自己一个问题“我写的这段代码会综合成什么样的电路呢”.对于一个简单的设计,比如 ...

  5. Android中Input型输入设备驱动原理分析<一>

    话说Android中Event输入设备驱动原理分析还不如说Linux输入子系统呢,反正这个是没变的,在android的底层开发中对于Linux的基本驱动程序设计还是没变的,当然Android底层机制也 ...

  6. 安装win7 32位系统出现的问题解决办法

    计算机意外地重新启动或遇到错误.Windows 安装无法继续.若要安装Windows,请单击“确定”重新启动计算机,然后重新启动安装”. http://www.baidusoso.net/      ...

  7. 第三部分 MediaPlayer的主要实现分析

    第三部分 MediaPlayer的主要实现分析 3.1 JAVA程序部分    在packages/apps/Music/src/com/android/music/目录的MediaPlaybackS ...

  8. 8.11-8.16:usaco

    summary:57 bzoj1741:裸二分图最大匹配 #include<cstdio> #include<cstring> #include<iostream> ...

  9. angular bootstrap

    2个js冲突,点击2次才显示,去掉data-toggle="dropdown"

  10. 利用icepdf将pdf文件转为图片

    所需jar 包为icepdf-core.jar.icepdf-extra.jar.icepdf-pro-intl.jar.icepdf-pro.jar和icepdf-viewer.jar. 示例代码如 ...