Как организовать игровой движок в C ++? Является ли мое использование наследования хорошей идеей?

11

Я новичок, как в игре developping и программирования.

Я пытаюсь узнать некоторые принципы в построении игрового движка.
Я хочу , чтобы создать простую игру, я в точке , где я пытаюсь реализовать игровой движок.

Так я думал, что мой движок игры должен контролировать это вещи:

- Moving the objects in the scene
- Checking the collisions
- Adjusting movements based on collisions
- Passing the polygons to the rendering engine

Я разработал свои объекты, как это:

class GlObject{
private:
    idEnum ObjId;
    //other identifiers
public:
    void move_obj(); //the movements are the same for all the objects (nextpos = pos + vel)
    void rotate_obj(); //rotations are the same for every objects too
    virtual Polygon generate_mesh() = 0; // the polygons are different
}

и у меня есть 4 различных объектов в моей игре: самолет, препятствие, игрок, пуля и я проектировал их, как это:

class Player : public GlObject{ 
private:
    std::string name;
public:
    Player();
    Bullet fire() const; //this method is unique to the class player
    void generate_mesh();
}

Теперь в игровом движке я хочу иметь общий список объектов, где можно проверить, например, для столкновения, объектов двигаются, и так далее, но я хочу также, что движок игры будет принимать пользовательские команды для управления проигрывателем ...

Это хорошая идея?

class GameEngine{
private:
    std::vector<GlObject*> objects; //an array containg all the object present
    Player* hPlayer; //hPlayer is to be read as human player, and is a pointer to hold the reference to an object inside the array
public:
    GameEngine();
    //other stuff
}

конструктор GameEngine будет выглядеть так:

GameEngine::GameEngine(){
    hPlayer = new Player;
    objects.push_back(hPlayer);
}

Тот факт, что я использую указатель, заключается в том, что мне нужно вызвать fire()объект, который уникален для объекта Player.

Итак, мой вопрос: это хорошая идея? Правильно ли мое использование наследования здесь?

Pella86
источник
Я видел их после публикации, и на самом деле композиция - отличная идея! Я всегда боюсь в конечном итоге использовать c с классами, вместо того, чтобы иметь реальный дизайн на C ++!
Pella86
Я думаю, что причин использовать композицию гораздо больше, чем наследования ... Мой ответ приводит несколько примеров, касающихся преимуществ гибкости, которые она дает. Для хорошего примера реализации проверьте статьи, на которые я ссылаюсь.
Койот

Ответы:

12

Зависит от того, что вы подразумеваете под «хорошим». Это сделает работу, конечно. У этого есть много положительных и отрицательных сторон. Вы не найдете их, пока ваш двигатель не станет намного сложнее. Смотрите этот вопрос на SO , для обсуждения на эту тему.

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

В общем, Скотту Мейерсу есть что сказать по наследству. Если вы все еще находитесь на этой стадии разработки, прочитайте эту книгу (Effective C ++), прежде чем продолжить. Это фантастическая книга и является обязательным требованием для всех программистов, работающих в нашей компании. Но подведем итог совету: если вы пишете класс и рассматриваете возможность использования наследования, будьте абсолютно ясны, что отношения между классом и его предком - это отношения «есть». То есть каждый B является A. Не просто используйте наследование как простой способ предоставить B доступ к функциональности, предоставляемой A, это приведет к серьезным архитектурным проблемам, и есть другие способы сделать это.

Проще говоря; для движка любого размера вы быстро обнаружите, что объекты редко попадают в аккуратную иерархическую структуру, для которой работает наследование. Используйте его, когда это уместно, но не попадитесь в ловушку использования его для всего - изучите другие способы взаимосвязи объектов.

MrCranky
источник
Я второе мнение о наследовании. Мое личное правило: не делайте этого , если вы не имеете или делать это по -другому было бы глупо. Другими словами, наследование плохая идея в 99% случаев (по крайней мере :)). Кроме того , это может быть хорошо для отдельной игровой логики (поворот / перемещение) от рендеринга (generate_mesh ()). Другое дело, огонь () - рассмотреть возможность перечень действий и функции родового действия (my_action) - таким образом , вы не будете в конечном итоге с bazillion различные функции распространения во всех классах. В любом случае, сохранить его простым и рефакторинг беспощадно , как вы столкнетесь с проблемами.
Gilead
8

Для данных логик и функции ваших игровых объектов (сущностей) , я бы настоятельно рекомендовал использовать композиции над наследованием. Стартовый хорошо бы компонент на основе подхода. Это хорошо описано в этой статье Программирования ковбоя , который описывает , как эта архитектура может быть реализована и как это приносит пользу франшизы Tony Hawk.

Кроме того, эта статья о системах сущностей вдохновила меня , когда я впервые прочитал его.

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

Компоненты очень удобны во многих ситуациях. Вы можете добиться гораздо большего, используя их:

Гибкость с типами сущностей : Есть моменты в развитии игры , где некоторые объекты развиваются внезапно и в то время как игровой дизайнер принимает решение от разработчика , реализуйте его. Это займет всего несколько шагов , чтобы добавить существующее поведение без повторения кода. Компоненты системы , основанные , чтобы больше изменений будет сделано, не являющихся программистами. Например каждый тип объекта , вместо того , чтобы быть представлен классом может быть представлено описание файла , который содержит все составные имена и параметры , необходимые для настройки типа. Это позволяет не являющиеся программистам делать и тестировать изменения без перекомпиляции игры. Просто редактирование файлов описание будет достаточно , чтобы добавить, удалить или изменить компоненты , используемые каждый тип объекта.

Гибкость в конкретных случаях и сценариях конкретных : Есть случаи , когда вам нужен плеер , чтобы иметь возможность оборудовать оружие или предметы, вы можете добавить компонент инвентаря к плееру. во время разработки вашей игры вам нужно другие объекты , чтобы иметь инвентарь (враги, например). И в каком -то момент у вас есть в вашем сценарии ситуация , когда дерево , как предполагается, содержит какое - то скрытый элемент. С компонентами , вы можете добавить компонент инвентаризации даже лиц , которые типа не предназначены изначально иметь один без каких - либо дополнительных усилий программирования.

Гибкость во время выполнения : Компоненты предлагают очень эффективный способ изменить поведение субъектов во время выполнения. Вы можете добавлять и удалять компоненты во время выполнения и, таким образом, создавать или удалять поведение и свойства при необходимости. Они также позволяют вам разделять различные типы данных на группы, которые (иногда) могут вычисляться отдельно параллельно на нескольких графических процессорах.

Гибкость во времени : Компоненты могут быть использованы для сохранения совместимости между версиями. Например , когда изменения между выпусками игры вы можете (не всегда) просто добавлять новые компоненты, реализующие новые модели поведения и изменения. Тогда игра будет инстанцировать нужные компоненты , прикрепленные к вашим лицам в зависимости от сохранения загруженного файла, равный или подключен сервер игрок присоединяется. Это происходит очень удобно в ситуациях , когда вы не можете контролировать сроки выхода новой версии на всех платформах (Steam, Mac App Store, iPhone, Android ...).

Для лучшего понимания взгляните на теговые вопросы [на основе компонентов] и [сущности-системы] .

койот
источник