хороший ОО способ сделать это (с ++) - PullRequest
3 голосов
/ 17 декабря 2011

Мне нужен совет. У меня есть 2 класса для игры, которую я делаю, и эти классы:

Графика Sprite

класс sprite состоит из буфера изображения для изображения, смещения (x, y), а также ширины и высоты. Графический класс имеет буфер для экрана. в экранном буфере могут быть скрыты такие объекты, как буфер изображения для спрайта.

Есть ли рекомендуемые способы переноса буфера изображения спрайта в буфер графического экрана? у меня было 2 идеи:

есть такой метод (в классе спрайтов):

void Sprite::blit(SDL_Surface* screen)
{
    // code goes here
}

или это (в классе графики):

void Graphics::blit(Sprite sprite)
{
   // code
}

или даже это (также в классе графики):

void Graphics::blit(SDL_Surface* aSpritesImageBuffer)
{
   // code
}

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

class Graphics
{
public:
    const getScreenBuffer() const {return screenBuffer;}
private:
    screenBuffer;
};

^ то же самое с буфером изображений спрайта.

так что если я попробую (в моем основном классе)

void handleRendering()
{
    graphics.blit(sprite.getImageBuffer());
}

что было бы не очень хорошо?

или даже:

void handleRendering()
{
    graphics.blit(sprite);
}

и я не думаю, что это хорошо:

void handleRendering()
{
    sprite.blit(graphics.getScreenBuffer());
}               

Есть ли лучшие способы сделать это, не получая ошибки, такие как const к non-const? << Я получаю такую ​​ошибку. </p>

Ответы [ 2 ]

2 голосов
/ 17 декабря 2011

Обычный способ сделать это состоит в том, чтобы в вашем графическом объекте был контейнер, содержащий все спрайты в сцене.Ваш основной цикл будет вызывать Graphics::blit(), а объект Graphics будет перебирать контейнер спрайтов и вызывать функцию Sprite::blit(SDL_Surface* screen) для каждого из них, передаваемых в его экранном буфере.

2 голосов
/ 17 декабря 2011

Я не знаю, является ли ваш класс спрайтов только низкоуровневым элементом рендеринга (то есть, по сути, только оболочкой вокруг SDL_Surface *), или это уже фактическое представление существа в вашей игре. В последнем случае, в качестве альтернативы вашим разным решениям, вы можете оставить только идентификатор растрового изображения в классе спрайтов, среди других свойств, таких как координаты, размер, скорость ... И фактический код, зависящий от технологии рендеринга в отдельный набор классов, таких как «Графика», «BitmapCollection» ...

Итак, с одной стороны, у вас будет «чистый» класс спрайтов с простыми свойствами, такими как position, size, speed ... а с другой стороны, «грязные вещи», с низкоуровневыми объектами и вызовами SDL_nnn. И однажды этот идентификатор будет представлять не растровое изображение, а, например, 3D-модель.

Это даст что-то вроде этого:

void handleRendering()
{
    graphics.blit( bitmapCollection.Get( sprite.getImageId());
}

Я не знаю, действительно ли изображение спрайта должно быть приватным или только для чтения. Несколько спрайтов могут совместно использовать одно и то же изображение, другие классы, такие как «SpecialEffects», могут изменять растровые изображения спрайтов, менять их местами, делать полупрозрачными следующие призраки на экране и т. Д.

...