Как правильно определить, какие конкретные игровые объекты сталкиваются? - PullRequest
0 голосов
/ 30 января 2011

Это по отношению к физическому движку. Как только происходит столкновение, он возвращает мне информацию о столкновении двух игровых объектов. Все сущности, такие как игрок, монстр, пуля и т. Д., Являются производными (наследуются) от GameObject.

Как правильно определить, какие конкретные игровые объекты сталкиваются?

Перечисления: я думал об использовании перечислений, но как только вы начинаете добавлять больше сущностей, становится неуправляемым отслеживать все возможные комбинации.

РЕДАКТИРОВАТЬ : я нашел здесь потенциальное решение для C #: http://blogs.msdn.com/b/laurionb/archive/2009/08/13/multimethods-in-c-4-0-with-dynamic.aspx

Но все же, если бы мне пришлось делать это в C ++, как бы я это сделал?

1 Ответ

1 голос
/ 03 февраля 2011

Типичное решение состоит в том, чтобы сделать два уровня отправки следующим образом:

class Thing
{
    public abstract void Collide(Thing other);
    public abstract void CollideWithSpaceship(Spaceship spaceship);
    public abstract void CollideWithAsteroid(Asteroid asteroid);
};

class Spaceship : Thing
{
    public override void Collide(Thing other) {
        other.CollideWithSpaceship(this);
    }

    public abstract void CollideWithSpaceship(Spaceship spaceship)
    {
        // Handle Spaceship -> Spaceship collision...
    }

    public abstract void CollideWithAsteroid(Asteroid asteroid)
    {
        // Handle Spaceship -> Asteroid collision...
    }
}

class Asteroid : Thing
{
    public override void Collide(Thing other) {
        other.CollideWithAsteroid(this);
    }

    public abstract void CollideWithSpaceship(Spaceship spaceship)
    {
        // Handle Asteroid -> Spaceship collision...
    }

    public abstract void CollideWithAsteroid(Asteroid asteroid)
    {
        // Handle Asteroid -> Asteroid collision...
    }
}

Это становится немного громоздким, так как количество разных классов увеличивается, но у него есть кое-что для этого:

  1. Это быстро. Он опирается на встроенную динамическую диспетчеризацию языка, которая довольно хорошо оптимизирован.
  2. Это безопасно. Вы заметите, что там нет кастинга.

Недостатком является:

  1. Не ограничено расширением. Добавление нового класса требует от вас прикосновения все остальные.

Более расширяемое решение состоит в создании двумерной таблицы диспетчеризации, в которой каждая ячейка идентифицирует пару сталкивающихся классов. В каждой ячейке вы помещаете функцию, которая обрабатывает столкновение между этими двумя типами классов. Это тоже хорошо работает, но немного обманывает систему типов. Вы закончите кастингом, и вам придется найти хороший способ определить класс.

Я бы не использовал поддержку C # dynamic. Я уверен, что это будет слишком медленно для физического движка.

Я также укажу, что существует стек разработки игр , который намного лучше отвечает на подобные вопросы. Увидимся там!

...