我一直想知道这一点。在像GTA这样有成千上万个对象的游戏中,游戏如何知道你是否在使用健康包?
每个对象不可能有一个事件监听器?迭代也不好?我只是想知道它实际上是如何完成的。
我一直想知道这一点。在像GTA这样有成千上万个对象的游戏中,游戏如何知道你是否在使用健康包?
每个对象不可能有一个事件监听器?迭代也不好?我只是想知道它实际上是如何完成的。
对此没有一个答案,但大世界通常是通过使用沿四叉树或kd 树的线进行空间划分的,这使得寻找最近邻居的搜索时间低于线性时间(分数幂,或者最坏的情况是 O( N^( 2/3) ) 用于 3D 游戏)。这些方法通常被称为二进制空间分区的BSP。
关于碰撞检测,每个对象通常还具有与其关联的包围体网格(一组多边形形成一个凸包)。这些高度简化的网格(有时只是一个立方体)不会被绘制,而是用于检测碰撞。最基本的方法是创建一个平面,该平面垂直于连接每个对象的中点的线与与该线的中点相交的平面。如果一个物体的包围体在这个平面的两边都有点,那就是碰撞(你只需要在平面上测试两个包围体中的一个)。另一种方法是增强型GJK距离算法。如果您想要深入了解教程,请查看NeHe Productions 的 OpenGL 第 30 课。
顺便说一句,包围体也可以用于其他优化,例如所谓的遮挡查询。这是一个确定哪些对象位于其他对象(遮挡物)之后的过程,因此不需要处理/渲染。边界体也可用于平截头体剔除,这是确定哪些对象在透视观察体之外(太近、太远或超出您的视野角度)并因此不需要渲染的过程。
正如 Kylotan 所指出的,在检测遮挡时使用包围体可能会产生误报,并且对于某些类型的对象(例如环形)根本不起作用(例如,通过甜甜圈中的孔看)。让像这样的对象正确地被遮挡是门户剔除的另一个线程。
游戏物理引擎中的一种常见技术是扫描和修剪方法。这在David Baraff 的 SIGGRAPH 笔记中有解释(参见 Motion with Constraints 章节)。Havok 肯定使用这个,我认为它是 Bullet 中的一个选项,但我不确定 PhysX。
这个想法是,您可以查看每个轴上的 AABB(轴对齐边界框)的重叠;如果两个对象的 AABB 的投影在所有三个轴上都重叠,则 AABB 必须重叠。您可以通过对AABB的起点和终点进行排序来相对快速地检查每个轴;帧之间有很多时间相干性,因为通常大多数对象的移动速度都不是很快,因此排序不会发生太大变化。
一旦扫描和修剪检测到 AABB 之间的重叠,您就可以对对象进行更详细的检查,例如球体与盒子。如果详细检查显示碰撞,您可以通过施加力来解决碰撞,和/或触发游戏事件或播放声音效果。
正确的。通常没有每个对象的事件侦听器。内存中通常有一个模仿游戏地图的非二叉树结构。想象一下地铁/地下地图。这种记忆结构是游戏中事物的集合。您是玩家、怪物和可以拾取的物品,或者可能会爆炸并伤害您的物品。因此,当玩家在游戏中移动时,玩家对象指针在游戏/地图内存结构中移动。
有很多优化可以使用。首先 - 任何对象(例如索引 i )都以立方体为界,中心坐标CXi
,CYi
和大小Si
其次 - 碰撞检测适用于估计:
a) 找到所有对立方体 i,j 的条件:Abs(CXi-CXj)<(Si+Sj) AND Abs(CYi-CYj)<(Si+Sj)
b) 现在我们只使用 a) 中的对。我们更准确地计算它们之间的距离,例如Sqrt(Sqr(CXi-CXj)+Sqr(CYi-CYj))
,对象现在表示为几个简单图形的集合 - 立方体、球体、圆锥体 - 我们使用几何公式来检查这些图形的交叉点。
c) b) 中检测到交叉点的对象被处理为与物理计算等的碰撞。
我想推荐 Christer Ericson 关于实时碰撞检测的实体书。它介绍了碰撞检测的基础知识,同时提供了当代研究工作的参考。