SFML и C++ Уроки \ Разработка игр › Форумы › SFML Graphics › Отображение окна
В этой теме 2 ответа, 2 участника, последнее обновление makish 6 года/лет, 3 мес. назад.
-
АвторСообщения
-
Я сделал меню, как бы все кнопки и тело цикла while работают, но почему-то я не могу двигать окно и кнопки закрытия и свертывания окна не реагируют, консоль работает нормально
C++12345678910111213141516171819void menu(RenderWindow & window){bool menuOn = true;Texture menu;menu.loadFromFile("images/additional/menu.png");Sprite menuS(menu);while (menuOn){if (Keyboard::isKeyPressed(Keyboard::L)){menuOn = false;}window.draw(menuS);window.display();}}C++123456int main(){RenderWindow window(VideoMode(1920, 1080), "Glinskii adventures"); //sf::VideoMode().getDesktopMode()window.setFramerateLimit(90); //fpsmenu(window);И еще меню сильно виснет, компьютер очень сильно нагружаетя
1. Окно не реагирует ни на что т.к. в функции main нет обработчика Event’ов (или есть, но находится он после функции menu())
2. Создавать для каждого игрового состояния(меню, настройки, игра и т.д.) собственную функцию с циклом while внутри неправильно, дальше это может привести к большим проблемам. Цикл while желательно иметь один на всю игру.
Для этого лучше использовать паттерн State(состояние). Можешь загуглить полную его реализацию, я лишь вкратце опишу как он работает.
Для начала нужно создать класс Game для всей игры:
C++12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758class Game{public:Game(){// Инициализация всего, что общее для всей игры, например окно, евент//...// Можно прямо здесь инициализировать текущее состояние игрыstate = new MenuState(this);}~Game(){// То, что придется удалить, когда игра закроетсяdelete state;}// игровой циклvoid loop(){while (window.isOpen()){while (window.pollEvent(event)){// обработка событийstate->handleInput(event);switch(event.type){case sf::Event::Closed:close();return;}}// обновлениеstate->update(elapsed);// отрисовкаstate->draw(window);}}void changeState(GameState* newState){delete state;state = newState;}void close(){// закрытие игрыwindow.close();}private:sf::RenderWindow window;sf::Event event;float elapsedTime;// ...};Далее нужно создать базовый класс для состояний:
C++12345678910111213141516class GameState{GameState(Game* game){// указатель на игруthis->game = game;}virtual ~GameState() {}// чистые виртуальные методы состоянияvirtual void handleInput(sf::Event& event) = 0;virtual void update(float time) = 0;virtual void draw(sf::RenderTarget& window) = 0;protected:Game* game;};Теперь для каждого состояния игры можно делать свой класс. Покажу на примере меню:
C++123456789101112131415161718192021222324252627282930313233343536class MenuState : public GameState{public:MenuState(Game* game) : GameState(game){// Инициализация всего, что нужно конкретно для// этого состояния (текстуры, кнопки и т.д.)// ...}~MenuState() {}virtual void handleInput(sf::Event& event){// Обработка евентов, нажатий на кнопки и т.д.// ...if (/*нажата кнопка начала игры*/){// просим игру переключиться на геймплейgame->changeState(new GameProcessState(game));return; // (!)Важно сразу выходить из функции.}}virtual void update(float time){// обновление текущего состояния}virtual void draw(sf::RenderTarget& window){// отрисовка состояния}private:// текстуры, кнопки, спрайты и т.д.};И так для каждого состояния игры.
После этого функция main будет выглядеть следующим образом:
C++1234567int main(){Game game;game.loop();return 0;} -
АвторСообщения
Для ответа в этой теме необходимо авторизоваться.