如何处理2D中的角落碰撞?

我正在写一个自上而下的2D XNA游戏。 自从我第一次尝试写物理和碰撞的东西,我自己学习它。

每当我的玩家精灵角色试图移动到一个边界与墙壁相交的位置时,我会计算出一个reflection角度(入射角=reflection角),使得玩家反弹离墙并避免碰撞。

我很难找出如何处理我的精灵同时与两个墙边相交的情况,虽然它碰到了一个角落。

角落相撞

我的代码目前告诉我,两个墙边已经被相交,但不会先碰到哪个边,因此哪个边会弹起。

什么是mathtestingselect哪个边缘反弹? 看看它很明显,但我正在努力弄清楚它的mathtesting。

如果您计算Player Sprite已经移动了多Player Sprite ,则可以将其基于相交角的x和y坐标的三角形。 我希望这是有道理的,我想不出一个更好的方式来说话。

所以,例如,如果你看看你的图。 取出Player Sprite左上角的x值(移动后),然后减去Wall右下角的x值。 对y值做同样的事情,然后看哪一个更大。 关键是如果一个比另一个大,那么Player Sprite可能会在这一边相交。

这是一个图像示例(这是您的图像的一个小节,添加了我自己的行):

相交例子

现在,你在这里看到蓝线比绿线大。 在这种情况下,蓝线也是Player Sprite预计会反弹的一面。

如果这两个值是相等的,他们就在角落里。

现在,这样做有一个小问题。 如果Player Sprite的行进速度非常快,或者碰撞非常靠近角落, Player Sprite可能会以错误的方向进入Wall 。 在这种情况下,您可能需要检查移动物体的速度。 (见Nathan Reed的答案 )

注意:我想我主要是想描述一下@Blau提到的SAT碰撞检测,但是我花了很长时间写这个,所以我打算发布它。 希望它会帮助你一些。

最小位移并不总是给出正确的答案,哪个边缘先被击中。 考虑这种情况:

打破最短位移算法的情况

这发生在速度足够高以至于在一帧内块移动得相当远时。 要正确检测哪个边缘首先被击中,您需要设置一个线性方程来解决与每个边缘碰撞的时间。 在OP的图中描述的情况下,相关的方程式是:

 timeXCollision = (player.left - wall.right) / -player.velocity.x timeYCollision = (wall.bottom - player.top) / player.velocity.y 

(这是假定一个X右Y坐标系统。)一般来说,你必须使用player.velocity的X和Y分量的符号来确定哪一对边需要被testing。 无论如何,一旦计算出碰撞时间,两者中较早的就是你需要处理的碰撞。

您需要SAT碰撞检测

基本上你需要寻找最小的位移向量,减less到一个对象让他们不相交。

在你的图片中,最小排量是橙色的部分。

在这里输入图像描述

在这里回答了类似的问题

你可能要考虑检查以前的职位 –

例如:如果您的左侧位于右侧的右侧,而您正在碰撞,则发生右侧碰撞。

如果你这样做,只要解决y轴碰撞,检查是否与任何东西碰撞,然后解决x轴碰撞。