19

我想学习如何为游戏开发中两个对象之间的碰撞情况创建良好的面向对象 (OO) 设计实践。

假设我有一个 SpaceShip 类和一个 Meteor 类。当 Meteor 与 SpaceShip 相撞时,SpaceShip 将被摧毁。

问题:流星与飞船是否发生碰撞的方法以及碰撞解决方法(摧毁飞船)应该放在什么类?是在 SpaceShip 类还是 Meteor 类?或者,也许我应该上另一堂课,即。GameArea 或 GameController 类?

注意:为简单起见,假设 Meteor 和 SpaceShip 是图像资源的形式。我习惯使用Java语言,但其他语言也可以。

4

4 回答 4

15

更自然地认为碰撞检测是不属于 Spaceship 或 Meteor 类的职责。尤其是当这变得复杂时,在不同方向有多种碰撞可能性。如果你把这个逻辑放在这两个类中,它们将需要引用它们周围的许多其他对象,这是不合适的。

您可以将它放在一个单独的类上,例如CollisionDetector,它跟踪游戏空间中所有对象的坐标并检测碰撞。在我看来,防撞似乎也是一项单独的责任,应该属于不同的类别。您可以为此设置一个单独的类CollisionResolver。根据要求,CollisionDetector可以与CollisionResolver对话。

CollisionResolver可能需要能够与 Spaceships 对话,以便建议它们改变方向或命令向 Meteor 发射导弹。

CollisionDetectorCollisionResolver可以位于GameSpace /* GameController * 中。ETC..

这将促进单一职责原则,因此每个组件将只执行一项重点任务。

于 2012-07-04T21:56:22.037 回答
3

在我看来,碰撞检测不是对象的一部分......它应该被定义为其他东西 - 一些物理管理器等。这样你的对象将独立于碰撞算法。

另一件事是,在游戏中,对象通常由几个层(组件)组成:图形层、物理层、逻辑层。这样物理管理器只管理给定对象的物理组件。

class GameObject 
{
    RenderComponent  m_renderComponent;
    LogicComponent   m_aiComponent;
    PhysicsComponent m_physicsComponent;
};
于 2012-04-11T08:05:05.390 回答
1

好吧,我通常创建一个(有时是通用的)GameObject类或接口,它有一个碰撞方法。例如:

template< typename T = int > class GameObject
{
public:
    bool collides(const GameObject& obj);
};

// usage
GameObject<int> my_obj, your_obj;
if(my_obj.collides(your_obj)) { ... };

我有时(但很少)做的另一件事是创建一个单独的GamePhysics类:

template< typename T > class GamePhysics
{
public:
    /* you may make this static or the class a singleton */
    void detect_collision(const T& obj, const T& obj2);
};
于 2012-04-11T04:54:10.720 回答
1

在 Java(或任何其他 OO 语言)中,我会在游戏中所有移动对象的公共祖先类中放置一个CollisionDetected 回调/事件

这是对游戏的简化描述:

  • 在游戏中,通常有一个游戏循环。游戏循环就像一个持续运行的while(true)循环(有点像应用程序的主 UI 线程),并且在每一步都检查对象发生了什么变化,应该更新什么以及应该调用什么事件(和更多...)。

  • 为了响应,这个循环应该每秒循环很多次。

  • 在这个循环中,物理引擎对象应该不断更新它的状态。这将是一个独立类的实例对象。正是这个引擎应该检测对象之间的碰撞并在所有碰撞的对象上调用 CollisionDetected 事件。

这是一个想法,而不是最终的解决方案...

于 2012-07-04T23:18:35.490 回答