September 30, 2008

一只n00b的两个月ActionScript开发经验 (3)

续上文
  • 用Flex来做Profiling

    在AS2的时代有一只叫ASProf的插件来分析AS代码的效率...到了AS3时代,Adobe的Flex 自带Profile SWF的工具...而且还是Run-time的哦...(Adobe 官方的介绍 )

    你要做的就是如下几步

    1. 在Flash中的SWF的Publish Setting里把Permit Debugging勾上
    2. Publish一只SWF
    3. 把Flex切换到Profiler模式
    4. 选择Profile External SWF...
    5. 选到那只SWF,然后Run之,你马上就会看到的是即时的Memory Overhead
    6. 对偶来说Memory不是很关键...然后点Reset Performance Data,让他跑一会,再点Capture Performance Snapshot, 看到的就是在这段时间内,你的所有Function call的次数和time cost...非常有用

    很后悔Flex的这个功能直到很后面才发现...之前都一直是用trace(getTimer());的方法来做的...效率极其低下...
  • 用SafelyRemove来代替removeChild

    刚开始总是碰到的一个问题就是DisplayList的维护经常出岔子...因为removeChild的指令几乎没有容错度,如果那个obj不存在也会报错,如果那个obj不是child也会报错...如果有耐心的同学就应该修掉每一个bug...如果像偶这样没有耐心的就可以用下面这个safelyRemove来忽略一切细节...

    ActionScript 3语言: safelyRemove
    public function safelyRemove(obj, objContainer = "this"){
          if (objContainer == "this")
               var container = this;
          else
               container = objContainer;
          if (obj!=null)
               if (container.contains(obj))
                     container.removeChild(obj);
    }

  • DrawOrder的处理

    和寻路一样...DrawOrder总是很麻烦的...当场景上有几百个object的时候,让他们的遮罩关系时刻保持正确总是一件很麻烦的事情...

    下面是偶的做法:

    • 能用DisplayList的不同层次来解决的就用DisplayList来解决。在GameVisual中建几个不同的空Sprite Object来放那些显然不是同一个Layer的东西,例如UI,GPE,Background,不管怎样,他们之间的遮盖关系总是一定的...

    • 排序的算法:每个obj都有一个用来排序的index值,每次某个obj移动的时候就更新他的index,然后再在调整DrawOrder的时候来对index值排序,然后把obj set到相应的childIndex上

    • 最开始很容易想到的就是每一帧对每一个object做DrawOrder的排序...不过后来就会发现效率跟不上,因为对600个物体做一次排序,然后再做setChildIndex就要大概 4ms 的时间...

      改进的算法是总是维护排好序的{obj,index}数组,每次有一个obj的index值发生改变的时候先确认他是不是需要重新排序,如果需要则把它从数组中删掉,然后找到他的新的位置...然后把他更新到相应的childIndex...
本系列到此完结...之前的内容:

No comments: