The code given is for example purposes, not copypasta from my codebase
我正在使用Boost& amp ;;用C ++编写一个原始的,跨平台的Snake游戏。 SDL,我想知道实现冲突处理的最佳方法是什么(不是碰撞检测)。到目前为止,我一直在使用单一调度的想法,以及丑陋的意大利面条代码,如下所示:
void Snake::CollisionHandler(const WorldObject& obj)
{
// collided with self
if(obj.GetObjectType() == snake)
Die();
...
...
}
另外,我有一个“全局”碰撞处理程序,它处理碰撞中涉及的事情,它们独立于每个对象,例如:
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();
}
这还包括类似于上面的全局碰撞处理程序。
然后就是只有的方法有一个全局冲突处理程序(它是所有游戏对象的友方函数),如下所示:
void GameWorld::CollisionHandler(WorldObject& obj1, WorldObject& obj2)
{
// snake collided with self
if(obj1.GetObjectType() == snake && obj2.GetObjectType() == snake)
{
obj1.Die();
obj2.Die();
PlayDeathSound();
}
...
...
}
我缺少任何策略吗?哪一个最好是最好的?它们似乎都涉及到一些丑陋的代码,单一和双重调度涉及多态性,我个人试图回避。
答案 0 :(得分:5)
碰撞处理是一个C ++ / Java风格的面向对象(单一调度)不够灵活的领域。碰撞的结果取决于两个碰撞对象的类型,因此您需要多个调度来处理它。 (维基百科的multiple dispatch文章中的激励示例是碰撞处理并非巧合!)
我认为然后调度到单个对象方法的全局冲突处理程序是解决C ++中这种不足的最佳解决方法。
答案 1 :(得分:1)
IMO让游戏类完全处理碰撞和其他全局事件的最后一种方法是最明智的,也可能是最“正确”的做法。
例如,参加国际象棋程序。很明显,游戏类应该由其中一个玩家处理输赢的情况,而不是玩家类。
它实际上也更有效。想想你想要添加更多类(例如另一种类型的蛇)的情况,而不是重复代码或重写CollisionHandler,你可以让游戏类以更少的努力处理它。
然而,如果您的唯一目的是简单的蛇游戏,那么您选择实施它的方式可能并不重要。