java - LWJGL 碰撞 3D OpenGL

标签 java opengl collision-detection lwjgl game-development

目前,我正在为我的引擎开发碰撞检测系统。我的代码工作得很好,但如何防止玩家穿过对象?

我的代码:

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!!!");
    }

}

最佳答案

碰撞检测的实现可能相当复杂,而让碰撞看起来物理上正确是导致碰撞困难的部分原因。

但是,从您提供的代码来看,您似乎在询问轴对齐边界框(AABB)碰撞,这根本不那么复杂。

AABB 碰撞是一种非常简单的近似碰撞的方法。总体思路很简单;获取游戏中的每个对象并为该对象创建一个边界框。对于轴对齐的边界框碰撞,这意味着您创建的边界框与世界轴对齐,并且每个碰撞框用六个数字表示;最小 x 和最大 x、最小 y 和最大 y、最小 z 和最大 z。

要执行碰撞检查,您可以选取这些框中的任意两个,然后简单地检查它们是否在每个轴上重叠。如果它们在 x、y 和 z 轴上重叠,则这些对象发生碰撞。

具体解决这个问题:

How can I prevent the player from passing through an object?

当您进行 AABB 碰撞时,这实际上也相当简单。 这里的答案是简单地反转最初产生碰撞的运动。 所以你有一个玩家和该玩家的 AABB。更新玩家位置时,您可以将玩家边界框平移一些固定量。翻译完成后,您将执行碰撞检查。如果您发现玩家正在与某些物体发生碰撞,那么您将撤消刚刚执行的平移,将玩家移出它正在碰撞的物体。

当您最终绘制场景时,您看到的是玩家不再发生碰撞,因为每次您将玩家移动到碰撞中时,您都会撤消该移动。

当然,这种方法也不是没有问题,因为它是一项基本技术。例如,如果玩家速度太高,可能会导致玩家逐步穿过对象。您还可能遇到这样的情况:撤消玩家的移动不足以撤消碰撞,尤其是在场景中有许多对象的情况下。 使用AABB也存在很多问题,以下图为例;

enter image description here

如果您假设黑线是游戏中的某个对象,那么红色框就是您创建的用于进行碰撞检查的 AABB。对于这个对象来说,显然有一种方法可以让其他边界框与这个框相交,这将记录碰撞,但大部分框都被空白空间填充。

即使其中包含的对象没有发生碰撞,这两个 AABB 也会记录碰撞。

enter image description here

要解决这些问题,您需要一些更聪明的东西,例如定向边界框和检查定向边界框之间碰撞的方法。

关于java - LWJGL 碰撞 3D OpenGL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54381888/

相关文章:

java - Java/lwjgl 中的 OpenGL 光照问题

c# - 矩形之间的碰撞检测 2D

java - 生成与 Hibernate 的 "assigned"生成器一起使用的标识符

java - 比较公共(public)对象的 2 个 HashSet

c# - Silverlight 真的不支持 OpenGL 吗?

c++ - For 循环中的 Switch 语句无法检查特定值的变量

javascript - 如何让 JavaScript 中的碰撞函数正常工作?

java - 同一类的两个实例之间的差异

java - "Variable Assignment Request"对象设计

c++ - '2D' 相机在 OpenGL/C++ 中的移动