2013-03-20 81 views
0

我想创建一个扩展圈,原因有几个。对于测试平台,我使用actionscript来开发它的开始。Actionscript - 扩展圈 - 性能问题

这是我的代码至今:

编辑

更新的代码13.39 GMT + 1 - 更新代码再次

更新的代码14.54 GMT + 1 - 更新代码,现在感谢Vesper的帮助

Main.as

package 
{ 
import flash.display.MovieClip; 
import flash.events.Event; 
import Wavelet; 
import flash.geom.Point; 
import flash.events.TimerEvent; 
import flash.utils.Timer; 
import flash.display.Bitmap; 
import flash.display.BitmapData; 
import flash.utils.getTimer; 

public class Main extends MovieClip 
{ 

    var startColor:Number = 0x00AA00; 
    var particleBitmapdata:BitmapData; 
    var m_temptimer:int; 

    private var myVector:Vector.<Wavelet> = new Vector.<Wavelet>(); 
    public function Main() 
    { 
     // constructor code   
     addEventListener(Event.ADDED_TO_STAGE, init); 
     addEventListener(Event.ENTER_FRAME, update); 
    } 

    public function init(evt:Event) 
    { 
     particleBitmapdata = new BitmapData(3,3,false, startColor); 

     var myTimer:Timer = new Timer(100, 0); 
     myTimer.addEventListener(TimerEvent.TIMER, run); 
     myTimer.start(); 
    } 

    public function run(tevt:TimerEvent) 
    { 
     for(var i:int=0; i < 360; i+=1) 
     { 
      myVector.push(new Wavelet(3, 1, i, startColor,particleBitmapdata)); 
      myVector[myVector.length-1].x = stage.stageWidth/2; 
      myVector[myVector.length-1].y = stage.stageHeight/2; 
      addChild(myVector[myVector.length-1]); 
     } 

    } 

    public function update(evt:Event) 
    { 
     var time:int = getTimer(); 
     var dt:Number = (time - m_temptimer) * 0.001; 
     m_temptimer = time; 

     for(var i:int=0; i < myVector.length-1; i++) 
     { 
      var w:Wavelet = myVector[i]; 

      if(w.x > stage.stageWidth || w.x < 0 ) 
      { 
       removeChild(myVector[i]); 
       myVector[i] = null; 
       myVector.splice(i,1); 
      } 
      if(w.y > stage.stageHeight || w.y < 0) 
      { 
       removeChild(myVector[i]); 
       myVector[i] = null; 
       myVector.splice(i,1); 
      } 

     } 

     for(var j:int=0; j < myVector.length; j++) 
     { 
      myVector[j].update(dt); 
     } 
    } 
} 

} 

Wavelet.as

package 
{ 
import flash.display.*; 
import flash.events.*; 
import flash.geom.Point; 
import flash.filters.*; 
import flash.geom.*; 

public class Wavelet extends Bitmap 
{ 
    private var m_velocity:Number; 
    private var m_angle:Number; 
    private var m_radius:Number; 
    private var m_bmd:BitmapData; 
    private var m_color=0x0000FF; 
    private var m_angleX,m_angleY; 

    public function getAngle():Number 
    { 
     return m_angle; 
    } 


    public function getVelocity():Number 
    { 
     return m_velocity; 
    } 

    public function setVelocity(input:Number) 
    { 
     m_velocity = input; 
    } 

    public function Wavelet(radius:int, velocity:Number, angle:Number, color:Number, bitmapData:BitmapData) 
    { 
     // constructor code 
     m_radius = radius; 
     m_angle = angle * Math.PI/180 ; 
     m_velocity = velocity; 
     m_angleX = Math.cos(angle); 
     m_angleY = Math.sin(angle); 
     m_color = color; 
     m_bmd = bitmapData; 
     this.bitmapData = m_bmd; 
    } 

    public function update(dt:Number) 
    { 
     this.x+= m_angleX * m_velocity; 
     this.y+= m_angleY * m_velocity; 
     m_velocity+=dt; 
    } 
} 

} 

无论如何,我得到了它的性能是可怕可怕的慢。 我不想创建一个扩展的圆作为一个整体,我需要像素来计算它们与墙壁和物体碰撞时,使它们改变方向。

是否有无论如何你可以做一个更好的表现的exanding圈?

+0

通过在每个Wavelet对象中不使用内部更新侦听器,而是从Main.as处理位置更新,但是性能仍然很差,我自己做了第一次修复。 – Hiam 2013-03-20 09:25:35

回答

0

由于更新代码而编辑。

首先,你可以把所有的小波常规移动到Wavelet类,以及预缓存Math.sin(angle)Math.cos(angle)到班上vxvy变量。这将为您节省720 Math.sin()Math.cos()每循环运行。

其次,你在前向循环上拼接了一个粒子 - 在这种情况下,当它之前的粒子会被拼接时,你的向量中的下一个粒子将不会移动。这是一个常见的错误,但大多数情况下结果更糟,如果我查询元素过去splice(),从而得到空例外。

第三,您请求myVector[i]你的循环内的十多倍 - 这个要求是不是在代码缓存,所以不是你这样做:var w:Wavelet=myVector[i];并通过w指针地址的一切,它使一个轻微的性能提升,为Flash不需要经常检查出界问题或检索列表元素。

+0

感谢您的帮助,但是当我将更新例程从Wavelet对象移动到Main时,它们一起被删除(请参阅上面的注释) – Hiam 2013-03-20 10:47:55

+1

请更新问题中的代码。也许还有另一个性能提示被重新分配BD所遮挡。 – Vesper 2013-03-20 10:59:39

+0

@Hiam好吧,编辑答案。也许这将会放大一些性能。 – Vesper 2013-03-20 11:21:52