【问题标题】:Time based movement and collision detection issue基于时间的运动和碰撞检测问题
【发布时间】:2014-01-06 13:50:40
【问题描述】:

我正在实现一个简单的基于图块的游戏,其中包含基于时间的移动。

我负责移动和碰撞检测的代码是

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 负载过重。结果,游戏的帧在稍后更新,但精灵(破坏者)在正确的位置,因为它们基于时间移动。然而,由于最后两帧之间的时间差较大,精灵移动到了更远的位置,一些碰撞失败了。因此,我的问题是有人如何在基于时间的运动中解决这个碰撞检测问题?

【问题讨论】:

    标签: actionscript-3 collision-detection 2d-games


    【解决方案1】:

    在增量时间进行移动时,有一些很好的方法可以解决这种情况。

    1) 最常见的方法之一是执行“固定时间步长”。这本质上是一种实现,它强制您在受影响对象上的update()(或在这种情况下为movement())仅在“时间步长”过去后运行。假设你有一个变量常量FIXED_STEP:int = 10,这个值 10 代表 10ms。如果您的增量时间 (interval) 已过去 10 毫秒或更长时间,您将发出 update(),无论您的 (已用时间/FIXED_STEP) 多少次,并且任何剩余时间都将添加到下一个已用时间值中。

    例如,您的增量时间为 45 毫秒,因此您将运行 update() 4 次并将 5 添加到您的下一个增量时间。

    这将允许您的碰撞仍然被检测到。这是一个 C# 解释,我认为它也解释得很好:Fixed Time Step C# XNA

    2) 另一种方法是计算在帧之间移动对象的距离,然后细分距离以创建移动步骤。即 - 您在 A 点的对象(40x40 矩形)将移动到 B 点,X 轴上的距离为 200px,您将对象移动 200 / object.width(即 40)= 5,因此您将调用您的movement() 5 次,并移动对象宽度 40px。这将覆盖运动区域,并且可以在任何一次运动更新中检测到您的碰撞。

    还有其他方法可以做到这一点,但出于性能原因可能没有那么好。射线投射和在对象的给定路径上找到交点非常准确,但性能非常密集,并且需要一些挖掘来学习和实施。

    我还读到有些人从update() 之前的原点到之后的位置创建了一个新对象,并使用它来进行检测。即 - 在下一帧之后,点 (0, 0) 处的对象 A 移动到 (200, 0),您创建一个从 (0, 0) 到 (200 + object.width, 0 + object.height) 的区域并运​​行而是针对该对象进行碰撞测试。

    无论如何,我希望这会有所帮助,祝你好运!

    【讨论】:

      【解决方案2】:

      您应该使用 AS3 的 CollisionTestKit 库。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-05-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-03-29
        • 1970-01-01
        相关资源
        最近更新 更多