2012-07-03 2 views
0

[Я надеюсь, что это подходит для SO, я думал, что это слишком практично для «программистов» и слишком технический для «гамедева», но не стесняйтесь двигаться, если он не подходит .]Взаимодействие с микро-видео двигателем с классом изображения

В принципе, мне просто нужна была быстрая проверка моего фактического дизайна для микро-видео движка, который должен просто иметь возможность рисовать изображения (библиотека рендеринга несущественна) и анимированные спрайты. Мне сложно свернуть голову вокруг хорошего дизайна для этой задачи, хотя, как мне кажется, рендеринг должен выполняться моим классом VideoEngine (следовательно, не в Image), но это заставляет меня использовать friend и extern, что не очень хорошо дизайн, как я слышал. Это может быть из-за того, что я не закодировал это правильно, но я думаю, что это скорее вопрос дизайна.

// Sprite.h 
class Image 
{ 
public: 
    Image(); 
    Image(std::string path); 
    ~Image(); 

    bool IsDisplayable() { return displayed; } 
    void LoadImage(std::string path); 

    static std::vector<Image*> image_list; 
private: 
    SDL_Surface* image_surface; 
    bool   displayed; 

    friend class VideoEngine; 
}; 

// VideoEngine.h 
extern class Image; 

class VideoEngine 
{ 
public: 
    VideoEngine(); 
    VideoEngine(int width, int height); 
    ~ VideoEngine(); 

    void Initialize(int width, int height); 
    void RenderImages(); 
    void ShutdownVE(); 
private: 
    SDL_Surface* main_display; 
    SDL_Rect  main_display_area; 
}; 

// VideoEngine.cpp 
void VideoEngine::RenderImages() 
{ 
    std::vector<Image*>::const_iterator ci; 
    for(ci = Image::image_list.cbegin(); ci != Image::image_list.cend(); ci++) 
    { 
     if((*ci) != 0 && (*ci)->IsDisplayable()) 
     { 
      SDL_BlitSurface((*ci)->image_surface, 0, main_display, 0); 
      SDL_Flip(main_display); 
     } 
    } 
} 

Как вы видите, тот факт, что мне нужно, чтобы получить доступ к image_surface внутри Image от VideoEngine классовых сил мне использовать friend и extern и делать наоборот (изображение, имеющее функцию рендеринга) просто заставить меня чтобы использовать полную противоположность (VideoEngine - друг с изображением, который я считаю уродливым).

TLDR: Является ли такая двойная связь разрешенной любым чистым способом? Одна вещь, которая, на мой взгляд, может быть выполнимой, но будет больше проверять ресурсы, уведомляет VideoEngine каким-то образом каждый раз, когда создается изображение, и передавайте ему указатель SDL_Surface для хранения в списке. Будет ли это лучше?

+0

И прежде, чем кто-нибудь это упоминает: я действительно знаю, что мой класс изображения чрезвычайно упрощен (не заботясь об источнике, альфе или его позиции), но я хочу, чтобы весь дизайн был выполнен, прежде чем работать над спецификой. Если я могу нарисовать изображение, то рисование его в определенном месте - это просто вопрос добавления нескольких параметров для вызова функций и нескольких членов класса. – ApplePie

+0

Почему вы не хотите, чтобы поверхность изображения была общедоступной? –

+0

Почему у вас нет геттера для 'surface'? –

ответ

0

Мне кажется, что вы не можете ничего сделать с вашим изображением, кроме как загрузить его. Возможно, у вас должен быть какой-то интерфейс контекста рисования. То есть так что вы могли бы сказать image->drawTo(x, y, screen) для некоторого определения screen?

Поскольку вы определенно используете SDL_Surface s в качестве своего примитива нижнего уровня, может иметь смысл использовать метод void Image::drawTo(..., SDL_Surface*). Это даст вам хотя бы небольшую степень инкапсуляции.

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