我想在理论上最能问这个问题。请忘记编程语言和API。
假设我们有一个用键盘移动的方格。在我们广场所在的屏幕上,也存在障碍。这个障碍是一个矩形,它是坚固的。这意味着,例如,如果我们的方块从左侧(障碍物的左侧)撞击它,则方块将无法在该方向上前进(如墙壁)。
这很简单,所以现在,我认为有两种主要方法可以解决这个问题。让我们假设我们使用命中测试碰撞来检测它:
- 进行移动(帧之间的时差),并查看新移动是否发生了碰撞。如果新移动发生碰撞,则“纠正”产生命中的坐标(可能是x或y)。
- 如果更新x将发生冲突。如果它成功,请不要更新x(或在碰撞障碍物之前更新它的最大值)。与y相同。
实际上,我正在使用第二种方法,它完美无缺!首先,我尝试了第一种方法,但我看到了它的一个大问题。当你在移动后发生碰撞时,这意味着我的玩家“进入”障碍物。但碰撞可能是由很多可能的方向造成的,所以我怎么知道哪一个是我必须纠正坐标的正确方向?它可能做得很好,但是当我可以简单地选择第二种方式时,它会使代码变得复杂。
我在SDL中这样做,第二种方式很好用。
你有什么看法?
答案 0 :(得分:1)
这确实取决于你想要碰撞的复杂程度。如果您有适合自己的东西,那么请务必使用它!无论如何,重要的部分是在渲染之前解决冲突。 ;)
但实际上,投射一条检查潜在碰撞的路径与先移动物体然后根据需要移回物体并没有太大的不同。这只是你看待它以及你的算法如何工作的不同之处。检查潜在的碰撞(移动前检查)意味着制作类似扫掠体形的东西并检查其他扫掠是否有重叠,然后将物体移动到外推的最终位置。检查过去的碰撞(移动后检查)只是检查物体本身的重叠(并避免高速隧道)。
如果您需要解决许多对象之间的冲突,那么(在我看来)您应该在检查重叠之前移动所有内容。你必须保留旧的位置和速度,这样你可以将物体向后滑动直到它们不再重叠,然后相应地给它们适当的动力。您可能仍希望执行子步骤以将对象带到最终位置。
总的来说,一些非常好的图书馆已经解决了这些问题。如果你需要良好的身体碰撞,可以先尝试其中一个,然后自己动手做。
答案 1 :(得分:0)
你的方式适用于方形障碍物,但对于弯曲的障碍物,如果你想要从它们反弹,你需要计算碰撞发生的sirface的角度。 以斯诺克比赛为例。
如果碰撞很少见,首先移动并检查碰撞是否有意义,如果发生碰撞,请撤消移动,然后查找碰撞原因的详细信息。