2013-04-05 74 views
0

我想優化我寫在AS3中的碰撞檢測算法。哪一個執行速度更快:hitTestObject或Point.distance?

我想知道是否有任何性能上的改進,如果我使用

Point.distance(pointObject1, pointObject2); 
兩個物體之間

,而不是使用

object1.hitTestObject(object2); 

我對象都或多或少凸形的邊界沒有按」真的很重要。

回答

2

Point.distance如果您的測試對象是內部有多個孩子的複雜容器,則速度要快得多(4倍以上!)。如果你使用簡單的Sprite,它在功能執行時間上只有25%的差異。

就是這樣,因爲Point.distance只是計算了畢達哥拉斯定理的一個斜邊。所以,我們只有2次減法,1次加法和3次小數計數。許多現代處理器都有內卷指令,因此速度很快。如果我們使用hitTest,則需要執行更多的操作。而且這些動作的數量會隨着hitTest'ing Sprite的複雜性而增加(因爲它很難算出它的界限)。

我剛做了一些測試。結果證實我是對的。

var ar:Vector.<Sprite> = Vector.<Sprite>([]); //Sprites for hitTest 
for(var i:int = 0; i < 100000; i++) { 
    var sp:Sprite = new Sprite(); //!The results will be other, is case of use a huge container with come objects here! 
    sp.graphics.drawCircle(0, 0, randomIntBetween(1, 200)); //add some shapes 
    sp.graphics.drawRect(0, 0, randomIntBetween(1, 200), randomIntBetween(1, 200)); 
    sp.x = randomIntBetween(-800, 800); 
    sp.y = randomIntBetween(-800, 600); 
    sp.rotation = randomIntBetween(-360, 360); //rotate and scale in random way 
    sp.scaleX = sp.scaleY = Math.random(); 
    ar.push(sp); 
} 

var tim:Number = new Date().time; 
for each(var spr:Sprite in ar) { 
    ar[0].hitTestObject(spr); 
} 
tim = new Date().time - tim; 
trace(tim); 

var pn:Vector.<Point> = Vector.<Point>([]); //Points for Point.distance 
for(i = 0; i < 100000; i++) { 
    var point:Point = new Point(randomIntBetween(-800, 800), randomIntBetween(-800, 800)); 
    pn.push(point); 
} 

tim = new Date().time; 
for each(var pnt:Point in pn) { 
    Point.distance(pn[0], pnt); 
} 
tim = new Date().time - tim; 
trace(tim); 
+0

爲什麼? – Joetjah 2013-04-05 10:05:05

+0

現在,這是一個答案。 – Joetjah 2013-04-05 10:21:21

2

實際上,你無法將這兩者相互比較。如果所有對象都是單像素位圖,則距離測試可以正常工作。但我認爲情況並非如此。

hitTestObject本質上檢查對象的邊界矩形,所以它非常快。 在進行像素級別檢查之前,您可以隨時檢查距離,看它們是否足夠接近,因爲它更昂貴,而且您不想做太多。

當您在對象周圍設置圓形邊界並確定兩個這樣的圓不相交時,距離檢查非常適用。如果它們相交,則必須使用hitTestObject進行另一次檢查,以確保兩個對象形狀實際重疊。所以基本上你會同時使用,距離檢查作爲第一次通過檢查和hitTestObject作爲準確性的後續。