12321官方游戏论坛

 找回密码
 立即注册
查看: 3180|回复: 6

浅谈Adobe Air滑移及其优化

[复制链接]

76

主题

131

帖子

1万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
17958
发表于 2017-7-7 12:01:30 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区!

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
浅谈Adobe Air滑移及其优化
Adobe Air是Adobe公司用来争夺移动设备应用开发的一个重要武器。移动设备的一个重要体验是手指滑移,但Adobe并没有为Air推出官方滑移的SDK
所以,若打算用Air来开发移动应用,则会碰到滑移这个问题。以下是对基于Air滑移的一些基本原理及其优化方案的讨论,本文最后会给出一个示例。

基本原理
上图说明了滑移的显示列表。
ScrollBg是整个滑移的背景,手指在此进行操作,它是侦听手指滑移事件的目标。
ScrollTarget是需要进行滑移的对象,其父为ScrollBg。p1,p2和p3为内部的显示对象。
ScrollMask是滑移对象的mask,用于对滑移对象形成遮罩,其父为ScrollBg。
综上,我们需要在ScrollBg上侦听用户手指事件,对ScrollTarget进行滑移,在滑移时我们只能看到被ScrollMask遮罩的那部分。




    在Adobe Air里,MouseEvent等同于手指触摸的TouchEvent,而只有在需要多点触控时,TouchEvent才有其特有的优势。所以我们侦听MouseEvent即可以侦听用户的手指操作。
  • 手指按下处理
    通常情况下,手指按下是整个滑移过程的开始。我们可以侦听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的移动设备上体现尤其明显。
滑移需要移动大块显示区域,可能会造成卡顿和跳帧,所以优化是必须要进行的一项工作。
以下是一些我在实践总结出来的优化方案。

  1. var i:int;
  2. var numChildren:int = _target.numChildren;
  3. var child:DisplayObject;
  4. for(i = 0; i < numChildren; i++)
  5. {
  6.         child = _target.getChildAt( i );
  7.         //对所有滑移对象的子项,若其超过mask超过一定距离MAX_VISIBLE_DIST
  8.         //则将其visible设为false
  9.         if( _direct == ScrollDirection.VECTORIAL || _direct == ScrollDirection.BOTH )
  10.         {
  11.                 if( child.y + child.height + _target.y < _bounds.top - MAX_VISIBLE_DIST ||  child.y + _target.y > _bounds.bottom + MAX_VISIBLE_DIST )
  12.                 {
  13.                         child.visible = false;
  14.                 }
  15.                 else
  16.                 {
  17.                         child.visible = true;
  18.                 }
  19.         }
  20.         else if( _direct == ScrollDirection.HORIZONTAL || _direct == ScrollDirection.BOTH )
  21.         {
  22.                 if( child.x + child.width + _target.x < _bounds.left - MAX_VISIBLE_DIST ||  child.x + _target.x > _bounds.right + MAX_VISIBLE_DIST )
  23.                 {
  24.                         child.visible = false;
  25.                 }
  26.                 else
  27.                 {
  28.                         child.visible = true;
  29.                 }
  30.         }
  31. }
复制代码



  • 切换为GPU模式
    经试验,将大面积滑移从cpu模式切换到gpu模式后,滑移的效率显著的提升了,基本可以达到原生滑移的效果。 只需要修改-app.xml里面的
    1. [color=rgb(0, 111, 224) !important]<renderMode[color=rgb(0, 111, 224) !important]>gpu[color=rgb(0, 111, 224) !important]</renderMode[color=rgb(0, 111, 224) !important]>
    复制代码

    GPU模式的优点是处理大块渲染区域移动的效率会显著提升。 缺点是不能使用滤镜,不能使用混合模式,在某些android机型(基本是低端机)上可能会跑不起来。 其中滤镜可以用位图替代,但是可能会带来内存上升的问题。
  • 在滑移时降低显示质量

    相对于PC屏幕,移动设备屏幕的ppi值要高很多。这就意味着,当我们在移动设备上降低显示质量时,实际感觉画质效果并没有PC上丢失的那么多。 所以在滑移开始时,我们可以先降低舞台显示质量。

  1. [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];
复制代码
       等滑移结束时,再恢复舞台显示质量。
       此方案带来的效率提升也是显著的。
       但是会显著的降低显示质量,所以需要在效率和效果方面做取舍。


  • 减少渲染区域
    减少渲染区域可以从根本上解决渲染压力的问题。
    实际上,在滑移时,有许多区域都在遮罩区域之外,但这些人眼不可见的区域的位置仍然会被CPU计算,从而浪费CPU周期,降低了效率。
    所以,我们可以在EnterFrame事件里,将在遮罩区域之外的滑移对象的visible设为false。从而避免了它们占用CPU周期。
    以下代码片段说明以上的方法。
  • 尽可能使用位图而非矢量
    矢量需要CPU实时进行计算,所以尽可能避免在移动设备上使用矢量,尽可能用位图来替代。
  • 减少事件侦听
    事件侦听会消耗帧时间,而且不能恰当的销毁事件侦听会带来恐怖的内存泄露。 所以尽可能减少不必要的事件侦听。 比如在滑移时,将目标的mouse相关属性禁用,等待滑移结束时再启用。


回复

使用道具 举报

61

主题

2万

帖子

3万

积分

管理员

野心家

Rank: 9Rank: 9Rank: 9

积分
38159
QQ
发表于 2017-7-7 12:02:42 | 显示全部楼层
顶      
既然无法一起出生,  那就一起祸害苍生。
回复

使用道具 举报

37

主题

1536

帖子

5272

积分

论坛元老

念旧

Rank: 8Rank: 8

积分
5272
发表于 2017-7-22 14:25:06 | 显示全部楼层
顶                          
“i love u three thousand times”
回复

使用道具 举报

2

主题

49

帖子

409

积分

中级会员

Rank: 3Rank: 3

积分
409
发表于 2018-12-2 14:45:37 | 显示全部楼层
6666666666666666666
回复

使用道具 举报

0

主题

14

帖子

58

积分

注册会员

Rank: 2

积分
58
发表于 2020-7-24 17:27:13 | 显示全部楼层
。。。。ll,...............
回复

使用道具 举报

0

主题

25

帖子

27

积分

新手上路

Rank: 1

积分
27
发表于 2020-12-23 05:13:51 来自手机 | 显示全部楼层
666666666666666
回复

使用道具 举报

0

主题

24

帖子

50

积分

注册会员

Rank: 2

积分
50
发表于 2021-6-14 14:10:10 | 显示全部楼层
666666666666666666666
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|12321官方游戏论坛  

GMT+8, 2024-4-26 07:13 , Processed in 0.029072 second(s), 25 queries .

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表