管理游戏中的碰撞检测

时间:2010-11-30 06:12:14

标签: language-agnostic

所以我的问题不是关于碰撞检测的方法,而是更广泛的“什么代码应该拥有碰撞检测”。我过去曾写过一些游戏(相对简单的2D Flash游戏),它让我想到哪些代码应该拥有碰撞检测?

让我澄清一下 - 在游戏中说我有一群敌人和一群玩家射击的射弹。所以在过去我曾经说过一个EnemyManager类,每一帧都会更新敌人的位置,同样对于玩家来说,弹丸有一个在子弹周围移动的PlayerProjectilesManager类。这很酷 - 一切都很好,花花公子。但是,我决定我希望子弹影响敌人(我知道疯了!)。所以这意味着我需要在代码中的某个地方:

  
  1. 弄清楚哪些子弹和敌人发生碰撞(我不在乎这个问题)
  2. 弄清楚每次碰撞的反应

所以基本上我过去所做的只是让EnemyManager类获取碰撞的'所有权',并且在其更新循环期间它找到与敌人子弹碰撞的玩家子弹(即步骤1)并且还调用处理碰撞的两个物体的代码(例如敌人损失健康,子弹消失)(即步骤2)。所以我已经控制了对EnemyManager的碰撞检测和碰撞“反应”。

有几条评论:

  • EnemyManager处于“控制”状态而不是PlayerProjectilesManager
  • 对我来说感觉不一样
  • 碰撞检测和碰撞'反应'均由同一所有者处理,从我的角度来看,这不是必需的。

在我脑海中形成的是管理碰撞检测的第三方实体。例如,有一个CollisionManager,其代码可以知道其他管理者需要检测到的冲突。这导致了其他一些问题,比如“管理者”需要公开哪些接口才能进行有效的碰撞检测,而不会向CollisionManager暴露太多内部结构。然后我想CollisionManager是什么广播某种事件,包含哪两个对象碰撞等......也许EnemyManager / PlayerProjectilesManager可以分别监听这些事件并做出相应的反应和分开。开始在我的脑海里有意义。 :)

思考?几乎每场比赛都有碰撞检测,所以我确信之前已经讨论过了。 :)

2 个答案:

答案 0 :(得分:11)

这是一个很好的问题。就个人而言,我不会因为使用“经理”而使其复杂化。假设我们有一个GameEngine,它在主循环中运行游戏。这个主循环可以包括3个步骤:获取用户输入,更新游戏中所有对象的状态(基于用户输入),最后在屏幕上再次绘制所有对象。

有关碰撞检测的所有内容都在第二步中完成 - 更新对象的状态。假设游戏中的所有对象都存储在池中。这包括玩家,子弹,敌人乃至整个世界(如果你想要以某种方式影响世界)。所有不同的对象都可以有一些共同的属性 - 它们可以是Drawable,Movable,Collidable e.t.c. (想想实现一个接口或扩展一个基类来拥有这些属性)

对于这些属性中的每一个,我都会有一个类对池中的所有对象执行某些操作。喜欢Mover.moveAll(objectsFromPool)。这将移动所有可移动的对象。 碰撞检测相同 - >在我们用Mover重新定位对象之后,我们检查与CollisionDetector.cehckAll(objectsFromPool)的碰撞。这个checkAll()方法将在对象本身之间进行实际的碰撞检测,知道它们的坐标。如果一个对象是Collidable,CollisionDetector将调用它的onCollide方法(withOtherObject),然后对象本身会做出正确的反应,这取决于其他对象是什么。让我们说,如果玩家被敌人的身体触碰,他们都会退后一步。如果子弹被另一颗子弹击中 - 它们都会被标记为删除。如果敌人被子弹击中,则会发生一些伤害并且子弹将被标记为删除。所有这些反应都应该在相应的对象中。碰撞检测器应用其算法来检测任意两个对象之间的碰撞,然后调用它们的onCollide(withOtherObjct)方法。 如果一个物体不是可碰撞的,它将被CollisionDetector简单地忽略(例如雨颗粒或灰尘不可碰撞)。

我希望我能表达自己的正确性:)

答案 1 :(得分:0)

顺便说一句,游戏开发特有的问题最适合https://gamedev.stackexchange.com/

  

所以在过去我曾经说过一个EnemyManager类

我认为任何SomethingManager类都表示您的代码尚未准确组织。在大多数情况下,对象应该自己管理。如果它们不能,则意味着存在关于它们的一些外部信息,并且该信息可能具有比“经理”更具体的表示。 3个游戏特定的例子可能是GameWorld,GameRegion或GameLevel。敌人存在于一个世界,一个世界的某个地区,或当前的游戏关卡中,所以这样的物体会保持其敌人的名单。

  

同样对于玩家射弹有一个PlayerProjectilesManager类

投射物也会生活在某种游戏空间,世界,地区或层面。

到目前为止,您可能猜到上述对象中的一个可能(并且可能应该)负责拥有所有上述对象(可能是间接地,通过容器类,但不是通过任何类型的重量级管理器)和负责检测碰撞并解决它们。