Как организовать рисование объектов?

При изучении C++ и OpenGL столкнулся с некоторыми трудностями.
Подскажите, пожалуйста, как с точки зрения архитектуры более правильно организовать взаимодействие классов при рисовании объектов на экране?

Допустим, я хочу отобразить несколько игровых объектов, для каждого из которых имеется отдельный класс: Player, Enemy и т.п. Имеются классы ResourceManager, Sprite, Renderer.

Пока рассматриваю два варианта:
1) В каждом классе, который может быть отрисован, добавить метод draw() и использовать как-то так:
playerSprite->draw();
enemySprite->draw();

2) Реализовать в классе Renderer методы для рисования объектов и использовать так:
renderer->drawSprite(playerSprite, coors, orientation);


В обоих случаях есть трудности с управлением ресурсами. Хотелось бы сделать загрузку спрайтов и управление всем отображением в классах игровых объектов. Но тогда придётся в каждый из них при создании передавать указатель на менеджер ресурсов, а при втором варианте ещё и на Renderer.
Player* player = new Player(resMgr, renderer);
Как мне кажется, это не очень правильное решение.

Есть вариант сделать классы ResourceManager и Renderer Singleton'ами и использовать их в любом нужном месте, тогда проблем не будет, но я читал много аргументов против такого метода.

Как организовать всё это правильно, чтобы можно было легко расширять и дорабатывать в дальнейшем?
  • Вопрос задан
  • 517 просмотров
Пригласить эксперта
Ответы на вопрос 2
devalone
@devalone
̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻
Ну, если у вас чисто 2D движок, то, например, как-то так:
Базовый класс для 2D игровых сущностей:
class GameObject2D : public GameObject {
public:
  const Sprite& getSprite() const { return sprite; };
private:
  Sprite sprite;
}

Игрок:
class Player : public GameObject2D {
// его особенные методы
}

Renderer:
class Renderer {
public:
  void drawScene(const Scene& scene)
  {
    auto& visibleObjects = scene.getVisibleObjects();

    for(auto& gameObject : visibleObjects) {
      drawSprite(gameObject->getPosition(), gameObject->getSprite());
    }
  }
}
Ответ написан
k12th
@k12th
console.log(`You're pulling my leg, right?`);
Есть вариант сделать классы ResourceManager и Renderer Singleton'ами и использовать их в любом нужном месте, тогда проблем не будет, но я читал много аргументов против такого метода.


Вместо синглтонов стоит использовать Dependency Injection.

А еще посоветую вот такую книжку: gameprogrammingpatterns.com
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

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