SFML и C++ Уроки \ Разработка игр › Форумы › SFML Graphics › Отображение окна › Ответ в теме: Отображение окна
1. Окно не реагирует ни на что т.к. в функции main нет обработчика Event’ов (или есть, но находится он после функции menu())
2. Создавать для каждого игрового состояния(меню, настройки, игра и т.д.) собственную функцию с циклом while внутри неправильно, дальше это может привести к большим проблемам. Цикл while желательно иметь один на всю игру.
Для этого лучше использовать паттерн State(состояние). Можешь загуглить полную его реализацию, я лишь вкратце опишу как он работает.
Для начала нужно создать класс Game для всей игры:
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 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
class 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; // ... }; |
Далее нужно создать базовый класс для состояний:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
class 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; }; |
Теперь для каждого состояния игры можно делать свой класс. Покажу на примере меню:
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 35 36 |
class 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 будет выглядеть следующим образом:
1 2 3 4 5 6 7 |
int main() { Game game; game.loop(); return 0; } |