Я новичок, как в игре 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.
Итак, мой вопрос: это хорошая идея? Правильно ли мое использование наследования здесь?
источник
Ответы:
Зависит от того, что вы подразумеваете под «хорошим». Это сделает работу, конечно. У этого есть много положительных и отрицательных сторон. Вы не найдете их, пока ваш двигатель не станет намного сложнее. Смотрите этот вопрос на SO , для обсуждения на эту тему.
В любом случае, существует множество мнений, но если ваш код двигателя все еще находится на этой ранней стадии, вам будет сложно объяснить, почему это может быть плохо.
В общем, Скотту Мейерсу есть что сказать по наследству. Если вы все еще находитесь на этой стадии разработки, прочитайте эту книгу (Effective C ++), прежде чем продолжить. Это фантастическая книга и является обязательным требованием для всех программистов, работающих в нашей компании. Но подведем итог совету: если вы пишете класс и рассматриваете возможность использования наследования, будьте абсолютно ясны, что отношения между классом и его предком - это отношения «есть». То есть каждый B является A. Не просто используйте наследование как простой способ предоставить B доступ к функциональности, предоставляемой A, это приведет к серьезным архитектурным проблемам, и есть другие способы сделать это.
Проще говоря; для движка любого размера вы быстро обнаружите, что объекты редко попадают в аккуратную иерархическую структуру, для которой работает наследование. Используйте его, когда это уместно, но не попадитесь в ловушку использования его для всего - изучите другие способы взаимосвязи объектов.
источник
Для данных логик и функции ваших игровых объектов (сущностей) , я бы настоятельно рекомендовал использовать композиции над наследованием. Стартовый хорошо бы компонент на основе подхода. Это хорошо описано в этой статье Программирования ковбоя , который описывает , как эта архитектура может быть реализована и как это приносит пользу франшизы Tony Hawk.
Кроме того, эта статья о системах сущностей вдохновила меня , когда я впервые прочитал его.
Наследование является отличным инструментом для полиморфизма. За исключением очень простых проектов, которые вы должны избегать использования его как способ структурировать сущности и ваши игровые логики. Если вы идете с наследованием вы наверняка закончится вверх с того, чтобы копировать и сохранять копии одного и того же кода для реализации функций, которые не могут быть унаследованы от общего предка. И вы, вероятно, начать загрязнять свои классы с логикой и данными, наиболее часто используемой, чтобы избежать повторений слишком много коды.
Компоненты очень удобны во многих ситуациях. Вы можете добиться гораздо большего, используя их:
Гибкость с типами сущностей : Есть моменты в развитии игры , где некоторые объекты развиваются внезапно и в то время как игровой дизайнер принимает решение от разработчика , реализуйте его. Это займет всего несколько шагов , чтобы добавить существующее поведение без повторения кода. Компоненты системы , основанные , чтобы больше изменений будет сделано, не являющихся программистами. Например каждый тип объекта , вместо того , чтобы быть представлен классом может быть представлено описание файла , который содержит все составные имена и параметры , необходимые для настройки типа. Это позволяет не являющиеся программистам делать и тестировать изменения без перекомпиляции игры. Просто редактирование файлов описание будет достаточно , чтобы добавить, удалить или изменить компоненты , используемые каждый тип объекта.
Гибкость в конкретных случаях и сценариях конкретных : Есть случаи , когда вам нужен плеер , чтобы иметь возможность оборудовать оружие или предметы, вы можете добавить компонент инвентаря к плееру. во время разработки вашей игры вам нужно другие объекты , чтобы иметь инвентарь (враги, например). И в каком -то момент у вас есть в вашем сценарии ситуация , когда дерево , как предполагается, содержит какое - то скрытый элемент. С компонентами , вы можете добавить компонент инвентаризации даже лиц , которые типа не предназначены изначально иметь один без каких - либо дополнительных усилий программирования.
Гибкость во время выполнения : Компоненты предлагают очень эффективный способ изменить поведение субъектов во время выполнения. Вы можете добавлять и удалять компоненты во время выполнения и, таким образом, создавать или удалять поведение и свойства при необходимости. Они также позволяют вам разделять различные типы данных на группы, которые (иногда) могут вычисляться отдельно параллельно на нескольких графических процессорах.
Гибкость во времени : Компоненты могут быть использованы для сохранения совместимости между версиями. Например , когда изменения между выпусками игры вы можете (не всегда) просто добавлять новые компоненты, реализующие новые модели поведения и изменения. Тогда игра будет инстанцировать нужные компоненты , прикрепленные к вашим лицам в зависимости от сохранения загруженного файла, равный или подключен сервер игрок присоединяется. Это происходит очень удобно в ситуациях , когда вы не можете контролировать сроки выхода новой версии на всех платформах (Steam, Mac App Store, iPhone, Android ...).
Для лучшего понимания взгляните на теговые вопросы [на основе компонентов] и [сущности-системы] .
источник
В общем предпочитают состав наследования. http://www.artima.com/cppsource/codestandards3.html
Состав дает большую гибкость.
источник