马上注册,结交更多好友,享用更多功能,让你轻松玩转社区!
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
浅谈Adobe Air滑移及其优化所以,若打算用Air来开发移动应用,则会碰到滑移这个问题。以下是对基于Air滑移的一些基本原理及其优化方案的讨论,本文最后会给出一个示例。
基本原理
上图说明了滑移的显示列表。 ScrollBg是整个滑移的背景,手指在此进行操作,它是侦听手指滑移事件的目标。 ScrollTarget是需要进行滑移的对象,其父为ScrollBg。p1,p2和p3为内部的显示对象。 ScrollMask是滑移对象的mask,用于对滑移对象形成遮罩,其父为ScrollBg。 综上,我们需要在ScrollBg上侦听用户手指事件,对ScrollTarget进行滑移,在滑移时我们只能看到被ScrollMask遮罩的那部分。
- 手指按下处理
通常情况下,手指按下是整个滑移过程的开始。我们可以侦听MouseDown事件来模拟手指按下。 在MouseDown侦听器里我们还要添加一系列事件侦听器,来构成整个滑移过程的侦听。 我们需要知道用户的手指移动,于是需要侦听MouseMove事件。我们还需要知道用户手指的释放,于是需要侦听RollOut和MouseUp事件。此外,我们还可能需要侦听EnterFrame事件,来做一些内部的更新逻辑。 综上,我们在MouseDown侦听器里处理滑移的开始,并为手指移动,手指释放及每帧更新等事件添加侦听器。 - 手指滑移处理
在MouseMove事件侦听器里,我们需要让滑移对象跟随玩家的手指进行移动。 所以在添加MouseMove侦听器之前,我们需要事先记录滑移对象当前的位置信息(诸如mouseX,mouseY),并在MouseMove侦听器对滑移对象的位置进行记录,通过两个位置的差异,我们可以计算出滑移对象需要移动的距离。 若需要移动的距离在合理的范围之内(如:不超过边界值的一半大小),我们将对滑移对象的位置进行改变,并进行更新。 有时候,我们可能会对滑移对象内的对象添加点击事件,但是我们不希望在滑移释放手指的时候触发这些点击事件。这时候我们可以在MouseMove侦听器里通过计算滑移对象的移动距离,来判断是否应该触发点击事件。 比如若用户的手指只移动了1-2个像素,用户很可能只是希望点击,而非滑移,所以此时我们不进行处理;但是用户的手指移动了10个以上像素,则我们可以认为用户是在进行滑移操作,此时我们将滑移对象的mouseChildren和mouseEnabled属性禁用,则点击事件则不会在滑移时触发了。 综上,我们在MouseMove侦听器里记录手指的位置,更新滑移对象的位置以跟随手指移动,做一些特殊处理以避免滑移时让用户触发点击事件。 - 手指离开处理
我们可以将RollOut事件和MouseUp事件视为用户手指离开了滑移触发区域,从而为这两个事件添加一个共同的侦听器MouseLeaveHandler。 在ios和android的原生滑移里,当用户滑移时手指离开屏幕,系统会对滑移对象进行自动滑移,这类似于物理中的惯性。 所以我们需要对滑移对象进行一个类似“惯性”的缓动,并在缓动结束的时候,做一些滑移结束的处理。 同时释放MouseMove和MouseLeaveHandler的侦听,并重新添加MouseDown事件的侦听,来侦听新的滑移。 综上,我们在MouseLeaveHandler里移除MouseMove和手指移开的事件侦听,并对滑移对象做一个”惯性”的缓动,在缓动结束时,做滑移结束的处理。
优化方案
相对于其他移动开发的引擎,Flash的渲染效率较低,在弱CPU的移动设备上体现尤其明显。 滑移需要移动大块显示区域,可能会造成卡顿和跳帧,所以优化是必须要进行的一项工作。 以下是一些我在实践总结出来的优化方案。
- var i:int;
- var numChildren:int = _target.numChildren;
- var child:DisplayObject;
- for(i = 0; i < numChildren; i++)
- {
- child = _target.getChildAt( i );
- //对所有滑移对象的子项,若其超过mask超过一定距离MAX_VISIBLE_DIST
- //则将其visible设为false
- if( _direct == ScrollDirection.VECTORIAL || _direct == ScrollDirection.BOTH )
- {
- if( child.y + child.height + _target.y < _bounds.top - MAX_VISIBLE_DIST || child.y + _target.y > _bounds.bottom + MAX_VISIBLE_DIST )
- {
- child.visible = false;
- }
- else
- {
- child.visible = true;
- }
- }
- else if( _direct == ScrollDirection.HORIZONTAL || _direct == ScrollDirection.BOTH )
- {
- if( child.x + child.width + _target.x < _bounds.left - MAX_VISIBLE_DIST || child.x + _target.x > _bounds.right + MAX_VISIBLE_DIST )
- {
- child.visible = false;
- }
- else
- {
- child.visible = true;
- }
- }
- }
复制代码
- [color=rgb(0, 45, 122) !important]stage[color=rgb(51, 51, 51) !important].[color=rgb(0, 45, 122) !important]quality[color=rgb(0, 111, 224) !important] [color=rgb(0, 111, 224) !important]=[color=rgb(0, 111, 224) !important] [color=rgb(0, 45, 122) !important]StageQuality[color=rgb(51, 51, 51) !important].[color=rgb(0, 45, 122) !important]LOW[color=rgb(51, 51, 51) !important];
复制代码 等滑移结束时,再恢复舞台显示质量。 此方案带来的效率提升也是显著的。 但是会显著的降低显示质量,所以需要在效率和效果方面做取舍。
|