Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/164.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 游戏碰撞处理_C++_Collision Detection - Fatal编程技术网

C++ 游戏碰撞处理

C++ 游戏碰撞处理,c++,collision-detection,C++,Collision Detection,给出的代码仅供示例使用,而不是从我的代码库中复制 我在C++中用Booost和SDL编写一个原始的跨平台的蛇形游戏,我想知道实现冲突处理的最佳方法是什么(不是冲突检测)。到目前为止,我一直在使用一个单一的分派想法,带有难看的意大利面代码,如下所示: void Snake::CollisionHandler(const WorldObject& obj) { // collided with self if(obj.GetObjectType() == snake)

给出的代码仅供示例使用,而不是从我的代码库中复制

我在C++中用Booost和SDL编写一个原始的跨平台的蛇形游戏,我想知道实现冲突处理的最佳方法是什么(不是冲突检测)。到目前为止,我一直在使用一个单一的分派想法,带有难看的意大利面代码,如下所示:

void Snake::CollisionHandler(const WorldObject& obj)
{
    // collided with self
    if(obj.GetObjectType() == snake)
        Die();
    ...
    ...
}

void GameWorld::CollisionHandler(WorldObject& obj1, WorldObject& obj2)
{
    // snake collided with self
    if(obj1.GetObjectType() == snake && obj2.GetObjectType() == snake)
    {
        obj1.Die();
        obj2.Die();
        PlayDeathSound();
    }
    ...
    ...
}
此外,我还有一个“全局”冲突处理程序,它处理冲突中涉及的事情,这些事情独立于每个对象,例如:


void GameWorld::CollisionHandler(WorldObject& obj1, WorldObject& obj2)
{
    if(obj1.GetObjectType() == snake && obj2.GetObjectType() == snake)
        PlayDeathSound();
    ...
    ...
}
避免碰撞时两次播放声音之类的事情

我也考虑过双重派遣,比如:

void Snake::CollisionHandler(WorldObject& obj) const
{
    // invoke obj's collision handler with a const Snake& parameter
    obj.CollisionHandler(*this);
}
// collided with self
void Snake::CollisionHandler(const Snake& obj)
{
    Die();
}

我有没有遗漏什么策略?其中哪一个是最好的?它们似乎都涉及到一些丑陋的代码,单调度和双调度的代码都涉及多态性,我个人试图避开多态性。

在我看来,让游戏类完全处理冲突和其他全局事件的最后一种方法是最明智、可能也是最“正确”的方法
例如,以国际象棋程序为例。很明显,游戏类应该处理一个玩家的输赢,而不是玩家类
它在实践中也更有效。考虑一种情况,您希望添加更多类(例如另一种类型的snake),而不是复制代码或重写CollisionHandler,您可以让游戏类轻松地处理它。


但是如果您的唯一目的是一个简单的蛇游戏,那么您选择如何实现它可能并不重要。

冲突处理是一个C++/Java风格的面向对象(单一分派)不够灵活的领域。碰撞的结果取决于两个碰撞对象的类型,因此需要多个分派来处理它。(维基百科文章中激发灵感的例子是冲突处理,这绝非巧合!)


我认为,一个全局冲突处理程序,然后发送到单独的对象方法,是解决C++中不足的最好办法。

如果我添加另一种Snake类,使用双调度方法不是更简单吗?不需要代码复制,而且它被很好地分割成模块。单行通用CollisionHandler(WorldObject&)函数存在少量代码重复。如果要从WorldObject继承,则需要复制代码。另外,作为一条经验法则,在不需要的时候最好不要使用函数重载。这就是我现在所拥有的。实际上,在C++中,有几种方法可以在C++中获得双调度。其中一个在我的原始帖子(第三段代码)中显示了是的,但我认为这是本例中较弱的解决方法。如果您在类A中有代码用于与类B冲突,在类B中有单独的代码用于与类A冲突,那么您可能会无意中使它们不一致。(也许在你的游戏中,只有蛇才能与物体碰撞,所以这在实践中不会发生,但在更一般的情况下,这是一个值得考虑的风险。)我不明白你的意思;任何事物都会处理自身与其他事物的碰撞。A只在与B发生冲突时处理其自身的结束,B只在与A发生冲突时处理其结束。我不确定我是否理解你所说的“不一致”的意思。如果你犯了错误,它将是不一致的(例如,你决定更改A/B冲突的某些方面,而你在类A中更改它,而不是在类B中更改它)。显然,如果你从未犯过错误,那么你如何组织你的代码并不重要,但对于像我这样容易犯错的凡人来说,将相关代码放在一起会有帮助。在你的上一个示例中,注释是“snake与self冲突”,然后你调用
Die()
两次。我怀疑那是件坏事。PS:不需要“交友”任何东西,只需将它需要的函数公开即可。PPS:为了避免重复代码,我倾向于只将该对象的效果放在它的“我与一个Foo冲突”函数中。当一艘船与子弹相撞时,它会受到一些伤害。当子弹与船相撞时,它就会消失。