Доброго времени суток!
Продолжаем делать пошаговую стратегию. В этом уроке мы добавим в нашу игру игровую карту, через которую будет игрок взаимодействовать с программой. Карты будет делиться на три класса: интерфейс, через который пользователь будет взаимодействовать с картой; камера или вид игрока, который будет направлен на определённый участок карты, и который будет рисоваться в интерфейсе; ну и собственно сама карта, в которой всё будет храниться. Первое, что мы реализуем – это интерфейс. Создаем новый файл TMapWidget.hpp и добавляем его к проекту. Наш интерфейс должен хранить координаты расположения в окне. Также добавим на время поле текстуры, чтобы загрузить её один раз во время создания объекта данного класса.
1 2 3 4 5 6 |
class TMapWidget{ protected: int X, Y, Width, Height; sf::Texture SomeTexture; //методы класса } |
Помним, что всё содержимое .hpp файлов должно прятаться в рамки:
1 2 3 4 5 6 |
#ifndef XXX_HEADER #define XXX_HEADER <Код описывающий что-либо> #endif |
– иначе можно получить море проблем с множественным подключением.
Теперь перейдём к методам класса: конструктор, деструктор и отрисовка.
1 2 3 4 5 6 7 |
class TMapWidget{ //поля класса public: TMapWidget(int aX, int aY, int aWidth, int aHeight); ~TMapWidget (); void Draw(); } |
Создадим новый файл TMapWidget и присоединим к проекту. В этом файле опишем тела методов нашего класса.
1 2 3 4 5 6 7 8 9 10 11 12 |
TMapWidget::TMapWidget(int aX, int aY, int aWidth, int aHeight): X(aX), Y(aY), Width(aWidth), Height(aHeight), SomeTexture() { SomeTexture.loadFromFile("../img/Grassland.png"); } TMapWidget:: ~TMapWidget () { } |
Тут, в общем то, ничего особенного. В конструкторе инциализируются поля и подгружается текстура. Теперь зададим правила рисования в методе Draw.
1 2 3 4 5 6 7 8 9 10 |
void TMapWidget::Draw(sf::RenderWindow *Window) { sf::Sprite SpriteStuff; SpriteStuff.setTexture(SomeTexture); SpriteStuff.setPosition(X, Y); float WidgetWidth = (float) Width / (float) SomeTexture.getSize().x; float WidgetHeight = (float) Height / (float) SomeTexture.getSize().y; SpriteStuff.setScale(WidgetWidth, WidgetHeight); aWindow->draw(SpriteStuff); } |
Расставим точки над и: создаём спрайт, устанавливаем его координаты начала, далее вытягиваем спрайт на столько, сколько у нас задано в Width и Height, то есть вытягиваем на заданные ширину и длину. Всё это нужно потому, что SFML выводит на экран спрайт с размерами задаваемыми загружаемой текстурой. В нашем случае картинка 1024х1024, а нужно её вытянуть в размеры 640х640.
Теперь переходим к главному классу TApplication и добавляем туда объект нового класса TMapWidget.
1 2 3 4 5 6 |
class TApllication { protected: sf::RenderWindow *Window; TMapWidget *MapWidget; //методы класса } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
TApplication:: TApplication(): Window(nullptr), MapWidget (nullptr) { } void TApplication::Init() { Window = new sf::RenderWindow(sf::VideoMode(640, 640), "4X TBS Lessons"); MapWidget = new TMapWidget(0, 0, 640, 640); } void TApplication::Run() { while (Window->isOpen()) { sf::Event event; while (Window->pollEvent(event)) { if (event.type == sf::Event::Closed) Window->close(); } Window->clear(sf::Color::Black); MapWidget ->Draw(Window); Window->display(); } } void TApplication::End() { if (Window != nullptr) { delete Window; Window = nullptr; } if (MapWidget != nullptr) { delete MapWidget; MapWidget = nullptr; } } |
… и редактируем методы. В метод Init добавляем создание карты, в метод Run – отрисовку нашего объекта, а в метод End – удаление. Собираем программу. Не забываем загрузить какую-либо картинку (главное, чтобы была в png формате) и переименовать её в Grassland. Она у меня размещается в /bin/dbg/img, а exe-файл программы в /bin/dbg/x64. Запускаем программу. Вот что должно примерно получиться:
Можете поколдовать с размерами окна – размеры интерфейса карты должны остаться неизменными (то есть теми, что мы и задали)
В следующем уроке мы рассмотрим создание класса, который и будет хранить собственно саму карту.