Flash开发移动设备技巧

随着Adobe Flash技术向iOS, Android, BlackBerry这三大移动平台的进军,必然将涌现出大量的基于Flash Player和AIR的手机和平板应用。然而移动设备的硬件限制,对Flash的运行效率产生了很大的挑战,所以如何优化代码成为Flash移动开发的核心问题。另外、基于触摸的全新交互方式和移动设备上独有的系统环境,也让移动平台上的Flash开发多了许多机会和功能点。今天我就给大家简单介绍一下我在近期总结的一些经验和技巧。

GPU渲染

移动设备的CPU和电脑上的CPU相差甚远,所以要运行大量动画(尤其是矢量动画),则最好要使用GPU来渲染。Flash Profession CS5在针对Android或者iOS项目的发布设置中可以选择是否使用GPU硬件加速。

不要大量使用位图缓冲

很多人认为使用位图(包括cacheAsBitmap) 要比使用矢量图要好,实际情况并非如此,一味单纯地使用图片也有弊端。论据之一是位图在缩放时显示不佳,我相信大家都有这样的体会;另外,如果位图元素被用在了移动、缩放、旋转等动画之内,那么它的运行效率不是提高反而下降了不少。而且在在使用GPU加速情况下,使用位图缓冲会让画面锯齿增加,远不如矢量图的清晰度高。但是如果用GPU渲染内容较多的动态文本,则必须使用位图缓冲。

大量文本的渲染

正如上点所说,GPU对处理动态矢量文本是非常之慢,原因就是GPU对矢量图采用了镶嵌渲染(tessellate),所谓镶嵌渲染就是将矢量图分为若干 个小三角形,根据它们的顶点信息分别绘制再镶嵌成整体的形状(如同Molehill的顶点着色器),镶嵌渲染对矢量图的裁剪数量是依据其本身的形状,如果 矢量图的拐点较多,那么就会裁剪出较多的三角形。因为动态文本含有大量的拐点,所以会产生很多的三角形镶嵌计算,而如果文本含有大量内容则会带来灾难性的 结果。所以对大量文本需要使用位图缓冲来处理,使用cacheAsBitmap = true,让GPU按照文本的宽高来均匀地裁剪三角形,这样会使运行速度非常流畅。在做其他矢量图形的时候同样需要注意这一点,尽量避免弯曲而且狭长的图 形,这让GPU绘制很多三角形从而拉低运行效率。

“镶”字的偏旁部分所示的是对矢量图镶嵌,“嵌”字示意的是对位图镶嵌
(如上图,“镶”字的偏旁部分所示的是对矢量图镶嵌,“嵌”字示意的是对位图镶嵌)

矢量图的帧滞后现象

这是我在制作手机游戏过程中发现的一个现象,前提是使用GPU加速,如果在第二帧要在舞台上首次显示一个复杂的矢量场景,那么在第一帧会有一个很明显的停顿,这也是由于GPU的镶嵌造成的。在我的例子中,前一个场景在做淡出效果,淡出到M帧应该是纯黑的画面,同时在M帧显示一个新的场景。由于GPU镶嵌造成的运算,使得前一个场景在M-1帧停顿了大约0.2-0.5秒,这时候画面并非纯黑,所以很明显感觉到停顿。我最后的处理方式是将前一个场景的退出和后一个场景的进入改为异步连接,在中间使用一个timer来等待100毫秒,这样肉眼就丝毫感觉不到停顿地存在。

不要使用特殊效果

对移动设备来说,无论使用CPU还是GPU,在某些效果地渲染上都尚未达到理想的结果。比如在动画上方盖一个很大的透明渐变层,会导致帧频极具下降至10以下;如果采用了滤镜,哪怕只有简单的模糊滤镜,都会让帧频下降到个位数,GPU下甚至根本就不支持滤镜的渲染。GPU同样不支持的还有部分layer,alpha,erase,overlay,hardlight,lighten,darken这些图形叠加效果以及着色器PixelBender。

关于Flash在移动设备上的效率优化,这里有一篇非常好的英文文章,建议各位仔细阅读。
http://www.adobe.com/devnet/flashplayer/articles/fplayer10_1_hardware_acceleration.html

设备键盘的使用

和电脑上获取键盘事件的原理一样,我们可以给应用程序添加一个侦听器来捕获KeyboardEvent,从而定义移动设备上的按键事件。从AIR2.5以后,我们可以使用Keyboard里的一些针对移动设备的key code(如Keyboard.BACK,Keyboard.MENU,Keyboard.SEARCH),如下面的例子:

stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);function onKeyDown(pEvent:KeyboardEvent):void{ if(pEvent.keyCode == Keyboard.BACK){ //do something here }}

另外有一点可能比较有用,我们可以利用Event的preventDefault方法来阻止一些键盘事件的默认行为。比如如果我们不希望按了返回键之后跳出当前应用程序到桌面,我们可以在上面的例子里加一行代码:

stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);function onKeyDown(pEvent:KeyboardEvent):void{ if(pEvent.keyCode == Keyboard.BACK){ pEvent.preventDefault(); //do some checking here }}

跨平台应用程序的判断

对于一个打算发布在多个平台的应用程序,我们当然希望使用相同的代码,避免为每个平台单独开发。桌面应用和移动应用在交互方式上是不一样的,桌面上更多的是采用鼠标操作,而移动上更多的是触摸和手势。这两种方式的API是不一样的,鼠标使用的是MouseEvent,触摸和手势则用TouchEvent和 GestureEvent。所以在定义交互的时候我们需要判断当前运行的平台是什么样的交互模式:

if(Capabilities.touchscreenType == TouchscreenType.FINGER){//定义触摸和手势交互}else{//定义鼠标交互}

除了交互方式的不同,移动设备上的AIR与桌面端AIR一样,有对原生系统的访问API比如NativeApplication类。举一个例子,在浏览器中运行的应用程序不用去考虑关闭应用程序,但是AIR则经常会设计一个自我关闭的功能。这个功能需要用到NativeApplication.exit()方法,可是NativeApplication类只存在于AIR运行时而非Flash Player中,所以如果在跨平台的代码中直接导入NativeApplication则会在编译浏览器版本时报错,即使使用AIR的发布功能将SWF发布成功,那么在浏览器中运行这个SWF也会报未知对象的错误。

我的解决方法是使用反射来解决编译时的导入问题,而使用Exception来解决运行时的错误:

try{ //AIR版本var myClass:Class = getDefinitionByName("flash.desktop.NativeApplication") as Class;nativeApplication = myClass.nativeApplication;nativeApplication.addEventListener(Event.DEACTIVATE, deactivateHandler);nativeApplication.addEventListener(Event.ACTIVATE, activateHandler);nativeApplication.addEventListener(KeyboardEvent.KEY_DOWN,onKeyDown);}catch(e:Error){//浏览器版本}

状态保存

Android和iOS平台与电脑平台一样,支持SharedObject本地存储功能,所以可以在所有平台使用一样的代码来对应用程序状态(比如游戏进度、应用的偏好设置)进行保存和读取。如果你对SharedObject的保存和读取不是很清楚,下面的代码可以帮助你了解。

访问本地SharedObject数据

//blabla是自定义的字符串,本地存储文件会以它来命名。var so:SharedObject = SharedObject.getLocal("blabla");//so.data是SharedObject的只读属性,可以作为容器存放需要在本地存储的数据变量,(注意,本地存储的数据有大小限制,最多为100KB)so.data.savedata = "What a nice function!!";//生成本地存储文件so.flush();

如果要清除特定的本地存储文件,可以用下面的代码来实现:

var so:SharedObject = SharedObject.getLocal("blabla");so.clear();

应用程序状态判断

举一个例子,如果你正在手机上玩一个有背景音乐的游戏,突然被来电打断,那么你当然不希望在通话的时候同时会听到游戏的背景音乐。或者你按了Back键回到了桌面,那么游戏也是理所应当被静音的。这就需要对应用程序的运行状态比如Activated, Deactivated添加侦听:

nativeApplication.addEventListener(Event.DEACTIVATE, deactivateHandler);nativeApplication.addEventListener(Event.ACTIVATE, activateHandler);function activateHandler(pEvent:Event):void{}function deactivateHandler(pEvent:Event):void{}

另外还有一些增加用户体验上的经验,比如如何处理被触摸控制的物体到达屏幕边界时的弹性缓冲运动,都可以用基本的ActionScript方法来进行处理和运算,这里不做详细介绍。

补充两点自Flash测试研发团队的同事 冀俊超
1.避免使用Timer。
2.在一些静态图片的时候可以降低帧率。

flash+flex+air移动开发入门经典——适用于android、ios和blackberry》 第1章 flash、flex和air简介 1 1.1 adobe flash 1 1.2 actionscript 3.0 2 1.2.1 ecmascript 2 1.2.2 关键概念 3 1.3 flex框架 11 1.3.1 flex 4.5.1 11 1.3.2 mxml 12 1.3.3 spark库组件 14 1.3.4 数据绑定 21 1.3.5 flex移动应用程序结构 22 1.3.6 移动开发的考虑事项 31 1.4 adobe air 31 1.5 小结 32 1.5.1 练习 32 1.5.2 本章所学内容 33 第2章 入门 35 2.1 使用flash builder 4.5.1 35 2.1.1 使用工作空间 36 .2.1.2 使用flash perspective 37 2.1.3 使用flash debug perspective 38 2.1.4 使用source和design视图 39 2.2 使用flash builder创建移动项目 41 2.3 定义运行配置 52 2.3.1 在桌面上运行移动应用程序 52 2.3.2 在设备上运行移动应用程序 55 2.4 小结 62 2.4.1 练习 63 2.4.2 本章所学内容 63 第3章 为android、blackberry和ios设备构建air应用程序 65 3.1 air应用程序描述符文件 65 3.1.1 在air应用程序描述符文件中设置属性 66 3.1.2 手动编辑hello world app的应用程序描述符文件 66 3.1.3 blackberry tablet os配置 76 3.1.4 为google android打包 79 3.1.5 为apple ios打包 85 3.1.6 为blackberry tablet os打包 90 3.2 更新air应用程序 92 3.2.1 从应用程序描述符文件获取详细信息 93 3.2.2 使用版本号 93 3.3 小结 94 3.3.1 练习 94 3.3.2 本章所学内容 95 第4章 触摸、多点触摸和手势 97 4.1 多点触摸交互 98 4.1.1 确定触摸输入支持 98 4.1.2 创建多点触摸和手势应用程序示例 99 4.1.3 触摸事件处理 102 4.1.4 在交互对象上注册触摸事件 110 4.1.5 确定支持触摸点数量 112 4.2 手势交互 113 4.2.1 确定设备支持哪些手势 113 4.2.2 手势事件和事件处理 114 4.2.3 在交互对象上注册手势事件 115 4.2.4 处理手势事件 120 4.3 在device central中利用多点触摸面板 123 4.4 小结 123 4.4.1 练习 124 4.4.2 本章所学内容 124 第5章 为多种屏幕尺寸进行开发 125 5.1 多种屏幕尺寸的考虑 125 5.1.1 像素密度 126 5.1.2 利用设备dpi 127 5.2 使内容适应舞台尺寸 131 5.2.1 使用stagescalemode 和 stagealign类 131 5.2.2 处理舞台尺寸变化事件 132 5.2.3 创建sprite layout app示例 133 5.3 处理设备朝向 144 5.3.1 使用stageorientation类 145 5.3.2 使用stageorientationevent类 145 5.4 在flex中使用布局 148 5.5 小结 167 5.5.1 练习 167 5.5.2 本章所学内容 168 第6章 调试应用程序 169 6.1 设置断点 169 6.2 全局错误处理 180 6.3 处理未捕获错误 180 6.4 try…catch语句 183 6.5 单步执行代码 185 6.6 小结 188 6.6.1 练习 189 6.6.2 本章所学内容 189 第7章 使用文件系统 191 7.1 从文件系统读取 191 7.1.1 file和filestream类 192 7.1.2 创建files explorer app示例 195 7.2 修改文件和文件系统 207 7.3 利用浏览对话框 220 7.3.1 打开单个文件 220 7.3.2 打开多个文件 221 7.3.3 将单个文件保存到某个位置 227 7.4 小结 227 7.4.1 练习 228 7.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值