AABB碰撞响应(推回碰撞物体)

我在用C ++游戏碰撞检测时遇到了问题。 我首先尝试了AABB并成功地检测到了碰撞,但问题是我想能够互相推送,所以我采用了一种基本解决方案,将两个物体推回到距离的一半。 但是,只是将对象彼此推到45度角。链接到GIF解释我的意思

如果您不想阅读本段落

所以我认为我需要一个方向来推入对象,所以我试图从教程中修改一些代码。 方向是两个对象中心之间的归一化矢量。 然后,一半的碰撞深度乘以归一化的矢量,以便它们被推向彼此相反的方向。 这工作,但它使用圆形碰撞(它使用半径+半径来计算碰撞深度),这意味着我不能使用具有不同宽度和高度的矩形,例如32x64 48x32(我必须使用32x32 48x48 64x64等等和等等)。 这是一个很大的问题,因为我需要能够使用具有不同宽度和高度的纹理

所以再次回到AABB,让它能够互相推动,所以你就完全停下来了。 但是这里的问题是,当我在一个轴上发生碰撞时,我不能在另一个轴上移动。 例如,如果我按住UP和LEFT并与左侧的墙相碰,我会完全停下来,而不是继续向上,在没有墙的地方。

因此,我需要帮助的是:AABB碰撞,物体彼此之间以正确方向穿透的距离的一半互相推动,或者只是简单的AABB,您完全停下来, 在碰撞时能够以非碰撞方向行走其他轴,例如上下按下会导致这种情况


下面是关于AABB碰撞检查的一些想法:

假设您有两个盒子对象:O1(x,y,宽度,高度)和O2(x,y,宽度,高度),其中'x'和'y'是盒子对象的左下角。

假设你用S(x,y)的一步移动O1,

为了避免碰撞完全停止,您应该将碰撞检查分为两部分 - 一次是水平碰撞,一次是垂直碰撞。

因此,移动后得到原点差异: diff = vec2(O1.x + Sx - O2.x, O1.y + Sy - O2.y)

在继续之前,您应该检查两个对象是否不重叠:

if( (diff.x < -O1.width || diff.x > O2.width) && (diff.y < -O1.height || diff.y > O2.height) return;

如果它们从不重叠,则不需要限制运动,而只是跳过碰撞。

然后我们开始限制我们的水平运动:

  • 如果diff.x小于-O1.width ,则O1位于最左侧。 它可以在水平方向上自由移动。 所以Sx保持原样。

  • 否则,如果diff.x大于O2.width ,那么O1位于最右侧,并且可以在水平方向上自由移动。 所以Sx保持原样。

  • 否则,我们有一种情况,O1在水平方向上与O2重叠。 所以只需检查if(diff.x<0) Sx -= O1.width+diff.x; 并分别if(diff.x>=0) Sx += O2.width-diff.x;

  • 你的水平移动应该在Sx准备好。 现在,遵循相同的原则,照顾你的垂直运动:

  • 如果diff.y小于-O1.height ,那么O1远低于。 它可以在垂直方向上自由移动。 所以Sy保持原样。

  • 否则,如果diff.y大于O2.height ,那么O1远远高出,并且可以在垂直方向上自由移动。 所以Sy保持原样。

  • 否则,我们有一种情况,O1在垂直方向上与O2重叠。 所以只需检查if(diff.y<0) Sy -= O1.height+diff.y; 并且, if(diff.y>=0) Sy += O2.height-diff.y;

  • 实质上,最后你有一个S(x,y) ,它包含你的新'安全'移动步骤。 您只需要将O1移动S,然后在下一步重复该过程。

    链接地址: http://www.djcxy.com/p/95571.html

    上一篇: AABB Collision response(Push back colliding objects)

    下一篇: Visual Studio 2010 conio.h