【发布时间】:2010-12-05 17:10:38
【问题描述】:
The code given is for example purposes, not copypasta from my codebase
我正在使用 Boost 和 SDL 用 C++ 编写一个原始的跨平台 Snake 游戏,我想知道实现碰撞处理的最佳方法是什么(不是碰撞检测)。到目前为止,我一直在使用单一调度的想法,带有丑陋的意大利面条代码,如下所示:
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();
}
...
...
}
我缺少什么策略吗?其中哪一个最终是最好的?它们似乎都涉及一些丑陋的代码,而单调度和双调度涉及多态性,我个人试图回避这一点。
【问题讨论】:
-
在您的上一个示例中,注释显示为“snake collides with self”,然后您调用了两次
Die()。我怀疑那将是一件坏事。 PS:不需要“加好友”任何东西,只要把它需要的功能公开即可。 -
PPS:为了避免重复代码,我倾向于只将对该对象的效果放在它的“我与 Foo 碰撞”函数中。 EX:当一艘船与子弹相撞时,它会受到一些伤害。当一颗子弹与一艘船相撞时,它就会消失。