0

我正在尝试优化用 AS3 编写的碰撞检测算法。

我想知道如果我使用性能是否有任何改进

Point.distance(pointObject1, pointObject2);

在两个对象之间而不是使用

object1.hitTestObject(object2);

我的对象或多或少都是凸的,所以边界并不重要。

4

2 回答 2

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);
于 2013-04-05T10:04:03.803 回答
2

事实上,你不能将这两者相互比较。如果您的所有对象都是单像素位图,则距离测试可以正常工作。但我想情况并非如此。

hitTestObject本质上检查对象的边界矩形,所以它非常快。在进行像素级别检查之前,您总是可以检查距离以查看它们是否足够近,因为它更昂贵并且您不想做太多。

当您在对象周围设置圆形边界并确定两个这样的圆不相交时,距离检查非常有用。如果它们确实相交,那么您必须再次检查 hitTestObject 以确保两个对象形状实际上重叠。所以基本上你会使用两者,距离检查作为第一次通过检查,hitTestObject 作为准确性的后续检查。

于 2013-04-05T10:40:10.147 回答