zoukankan      html  css  js  c++  java
  • Actionscript 优化指南

    什么时候举行优化

    对现有程序举行优化的过程,有时十分的冗长与困难,这与原始代码的非优化程度有关,所以在投入大量时间举行代码优化之前,最重要的是要估计出要在啥子处所对代码做出修改或替代。
    1个游戏代码的最重要的部门就是主轮回体,通常理况下该轮回体要在flash的每一帧上执行,并控制游戏中的角色属性和重要的数值参数。而对主轮回体以外的部门,也可能是非主要轮回部门,同样要注意是给其否分配了过多的资源,而没有分配售那一些更需要资源的核心部门。通过积累在遍地省电出来的时间(可能每处仅仅是几个毫秒),您会较着发现本身的swf运行得越发稳定,并且游戏感也大大加强。

    简洁与高效的代码

    书写出十分简洁、可以再次调用的代码(有时可能是面向对象的)是一项精致的工作,但这需要多年的编程经验。对OOP(object oriented programming,面向对象的程序设计),有些场合根本利用不到它的优势,这要得它显得十分奢侈。在有限的资源条件下(可能是flash播放器的原因),通过更先进的方法,像方才提到的OOP,就可能反而导致使人不称心的结果。
    我们并不是说OOP对游戏编程不好,只是在某些场合它显得过于奢侈和骈枝。毕竟有时辰“传统的方法”却能得到更好的结果。
    大体而言,用OOP是比较好的,因为它让代码维护越发简略。但在后文中,你会看见有时为了充分阐扬flashplayer性能,而不接纳OOP技术。例如:处理快速骨碌或者计算十分复杂的数学不懂的题目。

    基本的优化

    一提及代码优化,我们顿特殊情况遐想到执行速度的改进,而很少去考虑体系资源的分配。这是因为当今,即使是将被淘汰的计算机,都有足够的内存来运行我们大部门的flash游戏(128M的内存完全可以餍足大大都情况的需要,何况,512M的内存是当今新电脑的基本配置)

    变量

    在各种重要的代码优化手段中,有这么一条:在界说局部变量的时辰,一定要用要害字var来界说,因为在Flash播放器中,局部变量的运行速度更快,并且在她们的作用域外是不耗占体系资源的。
    aw附:var变量仅仅在花括号对中才有“生命”,个人以为没有体系学过编程的人容易出错的1个处所: 一段非优化代码: 最近代码中,并未声明函数体内的那一些变量(那一些仅仅在函数内使用的变量)为局部变量,这要得这些变量被播放器调用的速度更慢,并且在函数执行完结的时辰仍然耗占体系资源。
    底下面所开列出的是经过改进的同样功能的代码: 这样一来所有的变量均被界说为了局部变量,她们能够更快地被播放器调用。这一点在函数大量(10,000次)轮回运行时显得尤为重要!当1个函数调用竣事的时辰,相应的局部变量城市被销毁,并且释放出她们占有的体系资源。

    onEnterFrame 事件

    onEnterFrame事件对游戏开发者而言是很是有效的,它要得我们能够快速、反复地按照设计帧频(fps)运行一段程序。回想在 Flash5的时代,这(onEnterFrame及时监控)是一种很是流行的技术,用这样的事件来控制机器游戏对手的思维规律,又或者我们可以在每1个子弹 上设置这样的事件来监测子弹的碰撞。实际上,我们并不推荐给过多的MoveClip添加这样的事件,因为这样做会导致“无头绪码(spaghetti code)”的出现,并且容易导致程序效率较着减低大大都情况下,用单唯1个onEnterFrame事件就能够解决不懂的题目了:用这1个主轮回来执行你所需要的操作。 另1个简略的办法是设置1个合适的帧频:要知道帧频越高,CPU资源就越紧张。在帧频为25-35(fps)之间时,onEnterFrame完全可以很好地执行较复杂代码,哪怕你的计算机配置较低。是以,在没有特殊要求的场合,我们不推荐使用高于60(fps)的帧频。

    矢量图与位图

    在处理图形前,我们一定要做出正确的选择。Flash能对矢量图和位图举行完美的兼容,然而矢量图和位图在播放器中的体现实质却完全不同。在用到矢量图的时辰,我们要尽可能简化它们的外形,去除骈枝的端点。这样做将大大减低播放器用于出现矢量图所要举行的计算量。另1个重要方面在于线条的运用,尽量减少和避免冗陈的线条结构,因为它们会直接影响到flash的播放效率。当某个实例透明度小于100时,也会对播放速率造成影响,所以如果你发现本身的Flash播放速率过慢,就去挑出这些透明的实例来吧!
    那末,如果真的需要出现比较复杂的场景时,你就最好考虑使用位图实现。虽然Flash在对位图的渲染效率上并不是最优越的(好比和Flash的“兄 长”Director比起来),但富厚的视觉内容出现只能靠位图(与位图同复杂度的矢量图形渲染速率很是低)了,这也是很多基于区块的游戏中广泛接纳像素 图作为配景的原因。顺便要提到的是,Flash虽然对GIF,JPG和PNG都有所支持,但是渲染速度上PNG还是占有绝对优势,所以我们建议flash 中的位图都尽可能接纳PNG格局。

    影片剪接(MovieClip)的可视性[底下将MovieClip简称为mc]

    您可能会时常遇到这样一种情况:有大量不可见/荧幕外的mc等候出场(好比游戏中荧幕外的地图、人物等等)。要知道,播放器仍然要耗损一定的资源来处理这些不可见/荧幕外的mc,哪怕她们是单帧,非播放的状态。最好的解决办法之一是给这些mc1个空白帧,当她们不出现在荧幕上时,你能用gotoAndStop()语句跳转到这一帧,从而减少播放器对资源的需求。请务必记住,这种情况下,简略的设置可见度属性为不可见( _visible = false )是无效的,播放器将接续按照这些mc所停留或播放的帧的复杂度来分配资源。

    数组

     数组在各种需要记录数值的应用程序和游戏中都被广泛的使用。

    1个典型的例子就是基于区块的Flash游戏,在这样一类的游戏中,地图有时被存放成形如arr[y][x]的二维数组。虽然这是一种很常见的方 法,但是如果用一维数组的话,却能提高程序的运行效率。另1个重要的方法来提高数组效率是在数组遍历的时辰使用for in 轮回来代替传统的 for 或者whellole轮回语法。

    例如:
    一段代码如下 它的执行速度较着高于这一段代码: 前者的效率比后者提高了30%,这个数字在你的游戏要逐帧执行这一段代码的时辰显得越发宝贵!
    高级优化:
    1) for轮回和 whellole轮回
    用whellole轮回将会得到比for轮回更好的效率。然而,从数组中读取数值,用for in轮回式最好的选择!
    所以我们不推荐使用: 2) 从数组中读取数值
    我们通过测试发现,for in轮回的效率大大高于其它的轮回体式格局。参看: 3) 向数组中写入数值(whellole , for)
    可以看见whellole轮回稍占优势。
    4) _global(全局)变量同Timeline(时间轴)变量
    我们推测接纳全局变量能提高变量调用速度,然而效果并不像估计的那样较着。
    5) 单行、多行变量赋值
    我们发现单行变量赋值效率大大高于多行。好比:
    a = 0
    b = 0
    c = 0
    d = 100
    e = 100
    效率就不如:
    a = b = c = 0
    d = e = 100
    6) 变量名寻址
    这个测试反映了变量名的预寻址是很是重要的,尤其是在轮回的时辰,一定要先给丁1个指向。这样大大省电了寻址时间。
    好比: 就不如:

    7) 短变量名和长变量名
    变量名越短,效率越高。考虑到长变量名也有它的好处(好比,易于维护等),是以建议在要害部位(好比大量轮回出现的时辰)使用短变量名,最好就1-2个字符。
    8)轮回前、后声明变量
    在测试前,我们以为轮回前声明变量会越发省电时间,不意测试结果并不较着,甚或还恰恰相反! // 内部声明
    t = getTimer()
    for (var i=0; i < MAX; i++)
    {
    var test1 = i
    }
    t1.text = “Inside:” + (getTimer() – t)
    // 外部声明
    t = getTimer()
    var test2
    for (var i=0; i < MAX; i++)
    {
    test2 = i
    }
    9) 使用嵌套的if结构
    当用到复杂的条件抒发型时。把她们打散成为嵌套的自力判断结构是最佳方案。底下的代码我们举行了测试,发现这种效果改进较着! 10) 寻找局部变量(thellos方法同with方法比较)
    局部变量的定位方法很多。我们发现用with比用thellos越发有优势! obj = {}

    obj.a = 1 
    obj.b = 2 
    obj.c = 3 
    obj.d = 4 
    obj.e = 5 
    obj.f = 6 
    obj.g = 7 
    obj.h = 8 
    obj.test1 = useThellos 
    obj.test2 = useWith 
    MAX = 10000 
    function useThellos() 
    { 
    var i = MAX 
    whellole(–i > -1) 
    { 
    thellos.a = 1 
    thellos.b = 2 
    thellos.c = 3 
    thellos.d = 4 
    thellos.e = 5 
    thellos.f = 6 
    thellos.g = 7 
    thellos.h = 8 
    } 
    } 
    function useWith() 
    { 
    var i = MAX 
    whellole(–i > -1) 
    { 
    with(thellos) 
    { 
    a = 1 
    b = 2 
    c = 3 
    d = 4 
    e = 5 
    f = 6 
    g = 7 
    h = 8 
    } 
    } 
    } 
    


    11) 轮回监听键盘事件
    同刚才所提到的寻址一样,我们实现给1个指向会得到更好的效率,好比:
    keyDown = Key.isDown
    keyLeft = Key.LEFT
    //我们再用 if (keyDown(keyLeft))
    附:我们测试了按键代码和键值恒量的效率发现并无太大差别。
    12) Math.floor()方法与int()
    这个不懂的题目曾在Flashkit的论坛被提出讨论过。测试表明,旧的int方法反而效率更高。我们的测试结果也反映了这一点。
    13)eval抒发型与中括号语法
    我们并没有发现较着的差别,并不像刚才所述那样,旧的eval抒发型比起中括号方法并没有太大的优势
    var mc = eval_r(“_root.myMc” + i)
    var mc = _root["myMc" + i]
    //二者效率差不多16) 有关MC的轮回:ASBroadcaster 同欢同轮回的差别
    论断
    我们从这些测试结果中发现,对不同的需求,接纳不同的代码,我们可以大大提高脚本的执行效率。虽然我们在这里罗布了许多的优化代码的方法,需要各人本身测试、实验的还有很多(考虑到每个人的需求不同).如果你想越发深入地讨论这种不懂的题目。可以来我们的论坛。
    aw附:
    终于翻译完了,本身也学到很多好东西,各人又啥子不懂的题目可以去gotoAndPlay的官方,也能够来我的Blog提出!
    三黑羽AS心得:浅释ActionScript的代码优化
    来历:Kingda blog
    这篇文章既为浅谈代码优化,那末就不深入到OOP设计层面。仅有关Flash8帮助里面提到的一些代码编写优化原则,并加以解释。
    准则来历于Flash8 帮助,我做了一些解释:
    1.避免从1个轮回中多次调用1个函数。
    在轮回中包罗小函数的内容,可使效果更佳。小函数生命期短,利于资源释放。尤其是在大的轮回中时。
    2.尽可能使用本机函数。
    本机函数要比用户界说的函数运行速度更快。本机函数即Flash中内有的一些函数(intrinsic),好比hellotTest(),你没须要本身写1个类似的。
    3.不要过多使用 Object 类型。
    数值类型注释应力求精确,这样可以提高性能。只有在没有适当的备选数值类型时,才使用 Object 类型。同时也易于代码管理,时刻知道对象的类型和作用。
    同时也有利于编译器编译时优化。
    4.避免使用 eval_r() 函数或数值访问运算符。
    通常,较为可取且更有效的做法是只设置一次局部引用。无可奈什么时候才用eval,好比转换_droptarget为MovieClip时。
    5.在开始轮回前将 Array.length 付与变量,尤其是大的轮回。
    在开始轮回前将 Array.length 付与变量(好比var iLength:Number),将其作为条件使用,而不是使用 myArr.length 本身。
    原因,在轮回中,iLength是Number变量,会被放入寄存器使用,效率远比访问Array再得到length高。例如,应使用 来代替: } 6.注重优化轮回及所有重复动作。
    Flash Player 破费许多时间来处理轮回(如使用 setInterval() 函数的轮回)。
    7.在局部变量够历时,不要使用全局变量。类静态变量也要少用。
    全局变量是开发者的恶梦。实在需要全局变量的话,我建议使用singleton设计模式来举行管理。
    8.声明变量时,添加 var 要害字。
    这是为了编译时让编译器知道你的变量类型,优化编译。
    黑羽增补一点:对要害字的使用要审慎。
    不同意使用要害字作为本身的method和属性名,除非你明确承认后续开发不会用到不异的事件名和属性名。
    但你怎么知道flash使用了多少隐藏要害字?太多了!好比说 className, invalidate, refresh, mouseOver等等不常用的要害词。好的方法是使用SEPY编辑器来写代码,那里面加亮了所有公布的和没有公布的要害词。
    并且因为很可能和start,load,等这些常用的事件名重复,带来代码不须要的修改和贫苦。
    9.对有关到调用绘图资源的函数时,尽量先多判断再调用。
    所有渐变,位置变化,创建删除MC,组件等函数都有关到绘图资源的调用。在很多情况下,尽量先用思维规律判断变量或者对象的属性,须要时再调用这些函数。这样可以节省较多的计算资源。 减低预示列表上的复杂性来提高性能 资讯类型: 翻译
    来历页面: * lexity-from-the-displaylist-to-increase-performance /
    资讯原标题: reduce complexity from the displaylist and increase performance
    资讯原笔者: elad.ny
    增加Flash应用程序性能的一种最简略方法是,移除预示列表中所有的隐藏对象,同时使用最少量量的预示对象。 代码将 通过遍历整个预示列表来执行,即从预示列表最上层(舞台),到主应用程序类。 Flash Player执行代码,并从上到下重绘预示列表中的所有的孩子,直到到达预示对象。 容器可使任何继承自DisplayObjectContainer的类,如UIComponent,Group或者Sprite。
    尤其是在MXML中,很容易就嵌套了预示对象,但是每次嵌套对象时都是很是耗性能的,因为每个添加到现实对象列表的对象都继承了1个类,这个类又继承另1个,如此等等。 为了理解为啥子嵌套是高耗损的, 让我们看一下预示列表类的层次结构。
    AS3
    当谈到预示列表,对AS3来讲,所有的预示对象过去曾是MovieClip。 在Flash Pro中早期的Flash版本(AS1和AS2)中,MovieClip类都是动画的核心类。 每1个MovieClip符号包罗了预示对象的行为和功能,以及操作时间轴的附带加上属性。 许多时辰你并不需要骈枝的图层以及时间轴的开销,而究竟上AS3提供了一种能的对象叫做DisplayObject。 DisplayObject是低层的为那一些能够被添加到预示列表的所有对象的基类,它继承了EventDispatcher(它是基于对象的)。 它包孕一些类来帮助管理对象(如cacheASBitmap) 和可视属性。 预示对象容器是一种这样的对象,在它们里面可以包罗子对象(这些子对象是预示对象)。 DisplayObjectContainer包罗了一些方法,来管理它们的孩子对象,例如AddChellold(向容器中添加对 象),numChelloldren(容器所包罗的孩子对象的个数)和removeChellold(移除子对象)。
    有些时辰,你需要预示图形但又不需要时间轴。 这时你需要使用Sprite,它继承自DisplayObjectContainer类。 一般原则,你最好使用Bitmap,Shape和Sprite类或者它们的子类,而不要选择MovieClip。
    Flex3
    底下是最小化的Flex。 Flex对预示对象的核心类是FlexSprite,除了能够返回1个字符串表示这个对象的位置外,和Sprite没啥子两样。 接下来是UIComponent,它继承了FlexSprite,也是Flex3中每个可视组件的基类。 UIComponent包孕了键盘和鼠标交互,同时也许可在不需要的时辰关闭这些交互,例如label。 它也包罗了许多特征,例如accessibility(可访问性),Style(样式),State(状态),Invalidation和 Validation(合法性),DataBinding(数值绑定),Effect(效果),嵌入字体等等。
    Flex4
    底下是Flex4. Flex4使用Group作为Spark(至关于MX中的UIComponent)中可视元素的容器基类。然后你可使用一系列的组件,如Skin,Graphelloc,HGroup和VGroup。
    除了Group以外,也能够使用SkinnableComponent,它是所有Spark组件的超类,它为skinnable组件界说了基类。 使用SkinnableComponent类的皮肤是Skin类的典型子类。
    以Spark按键为 例。 ButtonBase类是所有Spark按键组件的基类。 Button和ToggleButtonBase是ButtonBase的子类。 同样,诸如CheckBox和RadioButton类是ToggleButtonBase的子类。 按键组件继承了ButtonBase,同时使用了默认皮肤,包罗了1个文本label。 你可以自界说皮肤类来添加图象到控制或其它任何你需要的东西。 默认按键皮肤是spark.skins.spark.ButtonSkin,它继承自Skin。 最后提到的是Spark中的组件,它们很容易改变,但是也很是重要。
    底下做一些测试。 关于预示对象的内存使用情况: Shape: 224 bytes
    Sprite: 392 bytes
    MovieClip: 428 bytes
    UIComponent: 1036 bytes
    Group: 1200 bytes
    底下,看一下Flash Player代码在帧上的执行时间。 建议使用“我”头几天开发的FrameStats工具。 所做的工作是创建1个快速测试,然后添加方法到
    FrameStats 工具 它许可你查看在一帧或几帧上代码执行时间(毫秒单位)的信息。 我将把帧率设为1秒(这样测试的更清楚,也易于不雅察结果),然后调用1个将被添加到预示对象的方法,添加预示对象到预示列表。 然后可以在控制台里跟踪帧的生命周期。 protected function creationCompleteHandler():void
    frameStats = new FrameStats(FlexGlobals.topLevelApplication, false );
    frameRateControl = new FrameRateControl( FlexGlobals.topLevelApplication, false, false, 1, 1);
    var componenent:UIComponent = new UIComponent();
    componenent.addChellold( frameStats );
    frameStatsHolder.addElement( componenent );
    trace( "Sprite: " + getSize(new Group()) );
    uicom.addChellold( sprite );
    frameStats.testingExecutionTimeOfMethod( methodToTest, 10000 );
    private function methodToTest():void
    sprite.addChellold( new Group() );
    预示对象
    当添加10000个预示对象是,对主要基类构造器的代码执行以及子类情况如下: Shape
    Constructor code of chelloldren executed: 276
    Sprite
    Constructor code of chelloldren executed: 399
    UIComponent
    Constructor code of chelloldren executed: 1078
    Group
    Constructor code of chelloldren executed: 1195
    正如所料,构造器代码和每个构造器的执行在拥有较多嵌套对象时,将破费更长时间。 如果你知道Flash Player时常将构造器方法放到自身代码的概念,这是有益的,是以在构造器上的执行时间会比其它类更长,我们应该尽量减少构造函数中的代码。
    添加1000个预示对象
    按键:
    虽然我添加了10000个SimpleButton的预示对象,Player在帧率为1fps时也只用了33毫秒,原因是SimpleButton在预示 对象树的层次上比较靠上,所以是较少的嵌套结构。 SparkButton在构造器代码上执行时间要比Halo更长,但有趣的是,SpariButton对预示列表的渲染时间要短一些。 SimpleButton
    Constructor code of chelloldren executed: 33
    Final user code executed: 730
    Player renders changes display list: 304
    mx.Button
    Constructor code of chelloldren executed: 820
    Player renders changes display list: 7075
    s:Button
    Constructor code of chelloldren executed: 2392
    Player renders changes display list: 4539
    Text 添加文本的结果也很是有趣。 Spark Label在渲染的时间上做的还不错,但是在构造函数的执行时间上还是不如Halo组件。 TLF在渲染上做的很差,但是构造器时间上很是好。 TextField
    Constructor code of chelloldren executed: 68
    Player renders changes display list: 168
    mx:Text
    Constructor code of chelloldren executed: 743
    Player renders changes display list: 685
    S:Label
    Constructor code of chelloldren executed: 1136
    Player renders changes display list: 198
    s:RichText
    Constructor code of chelloldren executed: 416
    Player renders changes display list: 3224
    论断 –使用低层次(即位于结构树的接近根的位置)的类,例如TextField,SimpleButton(如果可能的话),而不是Halo和Spark 它可能需要更多的代码,但是将提高性能。
    –避免使用TLF
    –使用Halo组件而不是Spark组件
    –自界说组件时,Sprit > MovieClip & UIComponent > Group
    –在创建矢量图形是,建议使用Shape预示对象

  • 相关阅读:
    Sqlserver 实际开发中表变量的用法
    Python Day 20 面向对象 (面向对象的组合用法,面向对象的三大特性
    Python Day 19 面向对象(初识面向对象)
    Python Day 18 常用模块(模块和包)
    Python Day 17 常用模块(常用模块一 时间模块,random模块,os模块,sys模块,序列化模块)
    Python Day 15 函数(递归函数、二分查找算法)
    Python Day 14 函数(内置函数,匿名函数(lambda表达式))
    Python Day 13 函数(迭代器,生成器,列表推导式,生成器表达式)
    Python Day 11 + Python Day 12 函数(函数名的应用,闭包,装饰器)
    Python Day 10 函数(名称空间,作用域,作用域链,加载顺序等; 函数的嵌套 global,nonlocal)
  • 原文地址:https://www.cnblogs.com/AS30/p/2195499.html
Copyright © 2011-2022 走看看