我正在实施一个简单的基于平铺的游戏,其中包含基于时间的移动。
负责移动和碰撞检测的代码是
private function onEnterFrame(event:Event):void
{
if (waiting && game.movingBreakers <= 0)
endLevel();
var interval:int = getTimer() - oldTime;
oldTime += interval;
var totalBreakers:uint = breakers.length;
if (totalBreakers)
{
for each (var breaker:Breaker in breakers)
{
if (!breaker.moving)
continue;
switch (breaker.direction)
{
case TOP:
breaker.y -= SPEED * interval;
break;
case BOTTOM:
breaker.y += SPEED * interval;
break;
case LEFT:
breaker.x -= SPEED * interval;
break;
case RIGHT:
breaker.x += SPEED * interval;
break;
}
checkCollisions(breaker);
}
}
}
我最近遇到的问题是,由于游戏的一些无关紧要的原因,我的计算机上的CPU负载很重。结果,游戏的框架在稍后更新,但是精灵(破碎机)处于正确的位置,因为它们的运动基于时间。然而,由于最后两帧之间的时间差较大,精灵在另一个位置移动的事实导致一些碰撞失败。因此,我的问题是有人如何在基于时间的运动中解决这个碰撞检测问题?
答案 0 :(得分:1)
在delta时间进行移动时,有一些很好的方法可以解决这种情况。
1)最常见的方法之一是执行“固定时间步骤”。这实际上是一个实施,强制您在受影响的对象上update()
(或在这种情况下为movement()
仅在“时间步长”结束后运行。假设你有FIXED_STEP:int = 10
的变量常量,这个值10表示10毫秒。如果您的增量时间(interval
)已超过10毫秒或更长时间,则会发出update()
多次(经过时间/ FIXED_STEP
)并将剩余时间添加到下一个已用时间值
一个示例是说您的增量时间是45毫秒,因此您将运行update()
4次并在下一个增量时间添加5。
这样可以检测到您的碰撞。这是一个C#解释,我认为它也很好地解释了它:Fixed Time Step C# XNA
2)另一种方法是计算在帧之间移动对象的距离,然后细分距离以创建移动步骤。 ie - A点的物体(一个40x40矩形)将移动到B点,X轴上的距离为200px,您将物体移动200 / object.width(即40)= 5,因此您将调用movement()
5次,并按物体宽度40px移动。这将覆盖移动区域,并且可以在任何一个移动更新中检测到您的碰撞。
还有其他方法可以做到这一点,但可能因性能原因而不太好。光线投射和在对象的给定路径上找到交叉点是非常准确的,但性能非常密集,需要一些挖掘来学习和实现。
我还读到有些人在update()
之前从原点创建了一个新对象,然后用它来进行检测。 ie - 对象A在点(0,0)移动到下一帧之后的(200,0),你创建一个从(0,0)到(200 + object.width,0 + object.height)的区域并运行而是针对该对象的碰撞测试。
无论如何,我希望这有帮助,祝你好运!
答案 1 :(得分:0)
您应该将CollisionTestKit库用于AS3。