The code given is for example purposes, not copypasta from my codebase
Я пишу примитивную, кроссплатформенную игру Snake на C ++ с Boost и SDL, и мне интересно, каков наилучший способ реализации обработки столкновений (не collision-обнаружения).До сих пор я использовал идею единой диспетчеризации с уродливым кодом спагетти, например:
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();
...
...
}
Чтобы избежать таких вещей, как звуки, воспроизводимые дважды при столкновениях.
Я также рассмотрел двойную диспетчеризацию, например:
<code>
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();
}
Это также включает в себя аналогичный глобальный обработчик коллизий, подобный описанному выше.
Тогда есть подход only с глобальным обработчиком коллизий (который является функцией другако всем игровым объектам), вот так:
void GameWorld::CollisionHandler(WorldObject& obj1, WorldObject& obj2)
{
// snake collided with self
if(obj1.GetObjectType() == snake && obj2.GetObjectType() == snake)
{
obj1.Die();
obj2.Die();
PlayDeathSound();
}
...
...
}
Какие стратегии мне не хватает?Что из этого оказывается самым хорошим?Кажется, что все они имеют какой-то некрасивый код, а одно- и двухдиспетчерские - полиморфизм, от которого я лично стараюсь уклоняться.