Лучший способ организовать объекты в игре?

В строке 27 должно быть:

/posts:

вместо:

/posts

При интеграции swagger с express.js Я не могу вам помочь, хотя ..

14
задан Benjamin 18 February 2014 в 12:06
поделиться

5 ответов

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

Вот пример. Сначала вам нужно настроить базовый класс для получения ваших объектов из:

class BaseObject
{
public:
    virtual void Render() = 0;
};

Затем создайте массив указателей. Я использую набор STL, потому что это позволяет легко добавлять и удалять элементы случайным образом:

#include <set>

typedef std::set<BaseObject *> GAMEOBJECTS;
GAMEOBJECTS g_gameObjects;

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

class Enemy : public BaseObject
{
public:
    Enemy() { }
    virtual void Render()
    {
      // Rendering code goes here...
    }
};

g_gameObjects.insert(new Enemy());

Затем для доступа к объектам просто выполните итерации по ним:

for(GAMEOBJECTS::iterator it = g_gameObjects.begin();
    it != g_gameObjects.end();
    it++)
{
    (*it)->Render();
}

Чтобы создать различные типы объектов, просто выведите больше классов из класса BaseObject. Не забудьте удалить объекты при удалении их из коллекции.

11
ответ дан 1 December 2019 в 06:04
поделиться

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

Вы можете узнать больше об этом, выполнив поиск «разработка игр на основе компонентов». Известная статья - Evolve Your Hierarchy из блога программирования Cowboy.

В моей системе сущности - это просто идентификаторы - беззнаковые длинные, как в реляционной базе данных. Все данные и логика, связанные с моими сущностями, записываются в Компоненты. У меня есть системы, которые связывают идентификаторы объектов с соответствующими компонентами. Примерно так:

typedef unsigned long EntityId;

class Component {
    Component(EntityId id) : owner(id) {}
    EntityId owner;
};

template <typename C> class System {
    std::map<EntityId, C * > components;
};

Затем для каждого вида функциональности я пишу специальный компонент. У всех сущностей разные компоненты. Например, у вас может быть статический каменный объект, у которого есть WorldPositionComponent и ShapeComponent, и движущийся противник, который имеет те же компоненты плюс VelocityComponent. Вот пример:

class WorldPositionComponent : public Component {
    float x, y, z;
    WorldPositionComponent(EntityId id) : Component(id) {}
};

class RenderComponent : public Component {
    WorldPositionComponent * position;
    3DModel * model;
    RenderComponent(EntityId id, System<WorldPositionComponent> & wpSys)
        : Component(id), position(wpSys.components[owner]) {}
    void render() {
        model->draw(position);
    }
};

class Game {
    System<WorldPositionComponent> wpSys;
    System<RenderComponent> rSys;
    void init() {
        EntityId visibleObject = 1;
        // Watch out for memory leaks.
        wpSys.components[visibleObject] = new WorldPositionComponent(visibleObject);
        rSys.components[visibleObject] = new RenderComponent(visibleObject, wpSys);
        EntityId invisibleObject = 2;
        wpSys.components[invisibleObject] = new WorldPositionComponent(invisibleObject);
        // No RenderComponent for invisibleObject.
    }
    void gameLoop() {
        std::map<EntityId, RenderComponent *>::iterator it;
        for (it = rSys.components.iterator(); it != rSys.components.end(); ++it) {
            (*it).second->render();
        }
    }
};

Здесь у вас есть 2 компонента: WorldPosition и Render. Класс Game содержит 2 системы. Компонент Render имеет доступ к положению объекта. Если у объекта нет компонента WorldPosition, вы можете выбрать значения по умолчанию или игнорировать объект. Метод Game :: gameLoop () будет отображать только visibleObject. Нет отходов обработки для компонентов, не подлежащих рендерингу.

Вы также можете разделить мой класс Game на два или три, чтобы отделить системы отображения и ввода от логики. Что-то вроде модели, представления и контроллера.

Я считаю полезным определять логику игры в терминах компонентов и иметь сущности, которые имеют только ту функциональность, которая им нужна - больше никаких пустых render () или бесполезных проверок обнаружения столкновений.

35
ответ дан 1 December 2019 в 06:04
поделиться

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

2
ответ дан 1 December 2019 в 06:04
поделиться

Есть ли лучший способ? Как коммерческие игры типа HL2 справляются с этим? Я предполагаю, что должен быть какой-то модуль и т. Д., Который отслеживает все объекты.

Коммерческие 3D-игры используют вариацию Scene Graph . Иерархия объектов, подобная той, которую описывает Адам, помещается в то, что обычно является древовидной структурой. Чтобы визуализировать объекты или манипулировать ими, нужно просто пройтись по дереву.

Несколько книг обсуждают это, и лучшее, что я нашел, - это 3D Game Engine Design and Architecture, обе от David Eberly.

1
ответ дан 1 December 2019 в 06:04
поделиться

Я подошел к этому, чтобы иметь слой отображения, который ничего не знает о самом игровом мире. его единственная задача - получить упорядоченный список объектов для рисования на экране, которые все соответствуют унифицированному формату для графического объекта. так, например, если это 2D-игра, ваш дисплейный слой получит список изображений вместе с их коэффициентом масштабирования, непрозрачностью, вращением, отражением и исходной текстурой, а также с любыми другими атрибутами, которые может иметь экранный объект. Представление также может отвечать за получение высокоуровневых взаимодействий мыши с этими отображаемыми объектами и отправку их в нужное место. Но важно, чтобы слой представления ничего не знал о том, что он отображает. Только то, что это какой-то квадрат с площадью поверхности и некоторыми атрибутами.

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

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

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

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

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

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

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

Кроме того,

8
ответ дан 1 December 2019 в 06:04
поделиться
Другие вопросы по тегам:

Похожие вопросы: