Рефакторинг кода для отрисовки игровых компонентов - PullRequest
0 голосов
/ 07 марта 2012

Как я могу преломить следующее, чтобы переместить мои функции рисования из h-файла в класс GraphicsManager?

//drawingFunctions.h
void drawTexturedQuad( Texture texture, Vector2 pos, Vector2 dim) {
    // bind texture...
    glBegin(...);    // draw  
    //...
    glEnd(...);
}

//class file
#include "drawingFunctions.h"
class Player { 
    void drawPlayer(){ drawTexturedQuad( texture, pos, dim) } 
};
class Enemy { 
    void drawEnemy(){ drawTexturedQuad( texture, pos, dim) } 
};
class Item { 
    void drawItem(){ drawTexturedQuad( texture, pos, dim) } 
};
// and so on for the other components

//gameloop file
// instantiate components objects
while (true) {
    // input, logic
    Player.drawPlayer();
    Enemy.drawEnemy();
    Item.drawItem();
    // and so on
}

(Код явно упрощен, я просто спрашиваю про рисунок здесь)

Должен ли я ...

  • передавать указатель на GraphicsManager на каждый вызов drawPlayer, drawEnemy и т. Д. Из игрового цикла
  • имеет Player, Enemy и т. Д. Имеет указатель на GraphicsManger в качестве члена данных
  • имеют Player, Enemy и т. Д., Расширяющие класс drawableGameComponent, который имеет указатель на GraphicsManager в качестве члена данных
  • что-то еще?

Ответы [ 3 ]

1 голос
/ 07 марта 2012

Я бы передал рендереру модель и попросил нарисовать себя.

class Player
{
public:
    void draw(Renderer& renderer);
};

class Enemy
{
public:
    void draw(Renderer& renderer);
};

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

class Model
{
public:
    virtual void draw(Renderer& renderer) = 0;

    virtual ~Model() {}
};

Тогда каждая ваша модель может наследоваться от Model, а каждая реализация draw.

Как я уже упоминал в комментарии к ответу @ J.N., вы также можете сделать Renderer абстрактным классом. Например, я работал над проектом, который использовал OpenGL, GDI +, а также нуждался в создании распечаток схем.

class Renderer
{
public:
    virtual render(const Triangle& triangle, const Texture& texture) = 0;

    virtual ~Renderer() {}
};
1 голос
/ 07 марта 2012

Это звучит как идеальный вариант использования для наследования:

class Drawable
{
public:
    void draw()
    {
         // gl stuff
    }

protected:
     Texture _texture;
     Vector2 _pos;
     Vector2 _dim;
};


class Player : Drawable
{
public:
     // should modify _texture _pos and _dim somewhere.       
};

// same thing for the other objects.
0 голосов
/ 07 марта 2012

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

Сказав это, я по-прежнему наследую от интерфейса Drawable и помещаю элементы, которые должны быть нарисованы, в контейнер, так что вы можете просто выполнять итерацию по нему для отображения элементов через виртуальную функцию drawItem (). Вот так (C ++ 03, не проверено):

std::vector<Drawable*> Items;
Items.push_back(&player);
Items.push_back(&enemy);
...
for (std::vector<Drawable*>::iterator it = Items.begin(); it != Items.end(): ++it)
{
  (*it)->drawItem(&graphMgr);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...