如何在视频游戏中表示弹丸?


14

我正在做一个简单的固定射击游戏,类似于“ Galaga”,),这是我正在做的演示的一部分。我想知道人们会使用什么策略和数据结构来跟踪弹丸,例如从飞船发射的激光。我以前使用的一种超级简单的实现方式是将每个弹丸表示为一个点,并检查是否与场景中的所有对象发生碰撞。

但是,在有许多弹丸的大型场景中,这似乎很昂贵。我想知道这种用例还使用了哪些其他类型的策略或实现。FPS之类的游戏用于跟踪弹丸(子弹,坦克炮弹等)有什么作用?


5
许多FPS游戏都假定子弹是即时的,但是有些计算轨迹和旅行时间的子弹。
约翰·麦当劳

2
+1这是一个很好的问题,我也不必将其限制为3d。
ashes999

Answers:


8

对于非常快的弹丸(例如激光或子弹),可以使用Ray

射线具有起点和终点。射线的(非常少的)数据结构是:

struct Ray
{
  Vector3f start, end ;
} ;

看起来像这样:

在此处输入图片说明

(您也可以缓存方向矢量和长度,但是我在上面使用了一个非常简单的defn)。

如果射线是以光速传播的激光束,则只需将其保留(如从喷枪喷嘴处开始到墙的某处结束)几帧。每帧与射线相交的任何东西都会受到损害。

如果射线是较慢的射弹(例如,子弹),则射线对子弹在一个时间步上的行进距离进行建模。起点是射线在帧开始处的位置,终点是射线在帧完成后的位置。子弹射线中的任何东西都会被子弹损坏。

光线可以有效地与球体,aabbs,凸包等碰撞。检查我的Hullinator项目以获取实际运行的程序(CTRL +单击以发射光线)


1
对于许多射弹来说,射线效果不是很好。例如,任何可以上垂的弹丸,例如坦克炮弹。射线非常适合直射弹丸。
MichaelHouse

好吧,如果炮弹移动得非常慢(相比于子弹或激光),是的,我会将其建模为常规物体(就像玩家一样)
bobobobo

7
从技术上讲,射线是起点和方向。可以用一个起点和另一个点来确定,但这不是其定义的一部分。根据定义,射线是无限的,没有终点。
Casey Kuball 2013年

1
没错,我所描述的实际上是一个线段,但是大多数人在谈论碰撞检测时都称其为射线。
bobobobo

3

使用射线对瞬时移动的子弹等子弹非常有效。对于速度较慢的弹丸,例如您要在太空游戏中使用的弹丸,像其他任何实体一样,简单地跟踪它们在游戏世界中的位置是有意义的。我经常做的是创建一个名为Entity的基类,其中包含任何持久游戏对象的属性-位置,旋转,碰撞盒等。我的玩家驱动和弹丸继承了该属性,而我的游戏世界只需要知道如何应对超类实体,而不是每种单独的实体类型。

为了提高性能,通常会为您经常创建和销毁的任何对象保留一个池。当您需要从该池中取出新弹丸时,请根据需要修改新弹丸,并在到期时将其返回到池中。


2

如果要针对碰撞检测进行优化,则可以将所有游戏对象存储在二维或三维树中。这种数据结构使检索特定区域中的所有对象非常有效。

但是,二叉树确实有一个缺点,当添加,删除和更改对象的位置时,它们容易退化,因此您需要对其进行自动平衡

一种折衷方案是使用基于块的方法,这种折衷方案更容易实现,但效率却不那么高。将运动场划分为多个多维数据集,并跟踪哪些对象正在触摸每个多维数据集。当您检查与某个对象的碰撞时,只需对照它所接触的多维数据集的对象列表来检查它(对于2D游戏,将“多维数据集”替换为“矩形”)。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.