当前,我正在为引擎开发碰撞检测系统。我的代码工作得很好,但是如何防止播放器穿过物体呢?
我的代码:
public void isCollide(Player player, Entity entity) {
if (
( player.getPosition().x <= entity.getScale() + entity.getPosition().x && player.getScale() + player.getPosition().x >= entity.getPosition().x ) &&
( player.getPosition().y <= entity.getScale() + entity.getPosition().y && player.getScale() + player.getPosition().y >= entity.getPosition().y ) &&
( player.getPosition().z <= entity.getScale() + entity.getPosition().z && player.getScale() + player.getPosition().z >= entity.getPosition().z )
)
{
System.out.println("Player is colliding!!!");
}
}
答案 0 :(得分:0)
实现碰撞检测可能非常复杂,并且使碰撞看起来物理上正确是导致碰撞困难的部分原因。
但是,从您提供的代码中,您似乎在询问关于轴对齐边界框(AABB)的碰撞,这根本没有那么复杂。
AABB碰撞是近似碰撞的一种非常简单的方法。总体思路很简单;以游戏中的每个对象为对象创建一个边界框。对于轴对齐的边界框碰撞,这意味着您创建的边界框与世界坐标轴对齐,并且每个碰撞框都用六个数字表示;最小x和最大x,最小y和最大y以及最小z和最大z。
要执行碰撞检查,您可以选择其中两个框,然后简单地检查它们是否在每个轴上重叠。如果它们在x,y和z轴上重叠,则这些对象会发生碰撞。
要专门解决这个问题:
如何防止播放器穿过物体?
在进行ABB碰撞时,这实际上也非常简单。 答案是简单地扭转最初造成碰撞的运动。 因此,您有一个播放器和该播放器的AABB。更新玩家位置时,您需要将玩家边界框平移一定的数量。翻译完成后,您将执行碰撞检查。如果您发现播放器与某个物体发生碰撞,则可以撤消刚刚执行的翻译,将播放器移出与之碰撞的物体。
当您最终绘制场景时,您看到的是播放器不再发生碰撞,因为每次将播放器移入碰撞时,您都将撤消该移动。
当然,此方法并非没有问题,因为它是一种基本技术。例如,如果播放器速度过高,则可能导致播放器逐步移过对象。您还可以进入撤消玩家动作不足以撤消碰撞的情况,尤其是在场景中存在许多对象的情况下。 使用AABB还存在很多问题,例如下图;
如果您假设黑线是游戏中的某个对象,则红色框是您用来进行碰撞检查的AABB。显然,对于此对象,有一种方法可以使其他边界框与该框相交,这将记录碰撞,但是大多数框都填充有空白空间。
这两个AABB即使没有碰撞,也会发生碰撞。
要解决这些问题,您需要一些更聪明的东西,例如定向边界框和一种用于检查定向边界框之间冲突的方法。