From 83fd4fd42c9f11b395053afb948ac68f640921c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9F=D0=B5=D1=87=D0=B5=D0=BD=D0=B8=D0=BD=20=D0=94=D0=B0?= =?UTF-8?q?=D0=BD=D0=B8=D0=BB=D0=B0=20=D0=9C=D0=B8=D1=85=D0=B0=D0=B9=D0=BB?= =?UTF-8?q?=D0=BE=D0=B2=D0=B8=D1=87?= <dmpechenin@edu.hse.ru> Date: Sat, 22 Mar 2025 19:12:27 +0300 Subject: [PATCH] New states Pause and Begin --- source/Configuration.h | 26 +++- source/States/GameState/Context/GameContext.h | 2 +- source/States/GameState/GameState.cpp | 114 +++++++++++++----- source/States/GameState/GameState.h | 11 +- 4 files changed, 110 insertions(+), 43 deletions(-) diff --git a/source/Configuration.h b/source/Configuration.h index f7d0808..cf534c6 100644 --- a/source/Configuration.h +++ b/source/Configuration.h @@ -36,18 +36,36 @@ namespace config { constexpr sf::Keyboard::Key KEY_RIGHT = sf::Keyboard::D; constexpr sf::Keyboard::Key KEY_UP = sf::Keyboard::W; constexpr sf::Keyboard::Key KEY_DOWN = sf::Keyboard::S; + constexpr sf::Keyboard::Key KEY_LEFT_2 = sf::Keyboard::Left; + constexpr sf::Keyboard::Key KEY_RIGHT_2 = sf::Keyboard::Right; + constexpr sf::Keyboard::Key KEY_UP_2 = sf::Keyboard::Up; + constexpr sf::Keyboard::Key KEY_DOWN_2 = sf::Keyboard::Down; // Цвета: const sf::Color BUTTON_COLOR_TEXT{ 0, 0, 0 }; const sf::Color BUTTON_COLOR_FILL{ 180, 180, 180 }; const sf::Color BUTTON_COLOR_SELECTION{ 255, 180, 180 }; const sf::Color BUTTON_COLOR_FRAME{ 0, 0, 0 }; const sf::Color SELECT_LEVEL_BACKGROUND_COLOR{ 230,230,230 }; - const sf::Color GAME_COLOR_BACKGROUND_INGAME{ 230,230,230 }; - const sf::Color GAME_COLOR_BACKGROUND_WIN{ 0, 255, 0 }; - const sf::Color GAME_COLOR_BACKGROUND_LOST{ 255, 0, 0 }; const sf::Color GAME_COLOR_PACMAN{ 250, 150, 0 }; const sf::Color GAME_COLOR_ROOM{ 255, 255, 255 }; const sf::Color GAME_COLOR_WALL{ 0, 0, 0 }; const sf::Color GAME_FOOD_COLOR{ 0, 200, 100 }; const sf::Color GAME_ENEMY_COLOR{ 255, 50, 0 }; -} \ No newline at end of file + // Состояния игры: + const sf::Color GAME_COLOR_BACKGROUND_INGAME{ 230,230,230 }; + const sf::Vector2f NOTIFICATION_BANNER_SIZE = { + static_cast<float>(GAME_VIDEO_MODE.width)/1.5f, static_cast<float>(GAME_VIDEO_MODE.height)/3.0f }; + const size_t NOTIFICATION_FONT_SIZE = static_cast<size_t>(NOTIFICATION_BANNER_SIZE.y / 2.f); + const sf::Color TEXT_COLOR_NOTIFICATION{ 0, 0, 0, 255}; + const sf::Color NOTIFICATION_BANNER_COLOR_PLAY{ 0, 100, 255, 200 }; + constexpr char TEXT_PLAY[] = "PRESS SPACE"; + const sf::Color GAME_COLOR_BACKGROUND_PAUSE{ 255, 255, 128 }; + const sf::Color NOTIFICATION_BANNER_COLOR_PAUSE{ 255, 255, 128, 200 }; + constexpr char TEXT_PAUSE[] = "PAUSE"; + const sf::Color GAME_COLOR_BACKGROUND_LOST{ 255, 0, 0 }; + const sf::Color NOTIFICATION_BANNER_COLOR_LOST{ 255, 0, 0, 180 }; + constexpr char TEXT_LOST[] = "DEFEAT!"; + const sf::Color GAME_COLOR_BACKGROUND_WIN{ 0, 255, 0 }; + const sf::Color NOTIFICATION_BANNER_COLOR_WIN{ 0, 240, 0, 200 }; + constexpr char TEXT_WIN[] = "WIN!"; +} diff --git a/source/States/GameState/Context/GameContext.h b/source/States/GameState/Context/GameContext.h index 21022b2..2f4b3da 100644 --- a/source/States/GameState/Context/GameContext.h +++ b/source/States/GameState/Context/GameContext.h @@ -8,5 +8,5 @@ struct GameContext final { Pacman pacman; std::vector<std::unique_ptr<IStaticEntity>> static_objects; std::vector<std::unique_ptr<IDynamicEntity>> dynamic_objects; - enum State{ INGAME, WIN, LOST } state = INGAME; + enum State{ BEGIN, INGAME, PAUSE, WIN, LOST} state = BEGIN; }; \ No newline at end of file diff --git a/source/States/GameState/GameState.cpp b/source/States/GameState/GameState.cpp index 601d867..4172f34 100644 --- a/source/States/GameState/GameState.cpp +++ b/source/States/GameState/GameState.cpp @@ -2,16 +2,45 @@ #include <States/GameState/GameState.h> #include <States/SelectState/SelectState.h> +GameState::GameState(IStateManager& state_manager, const sf::VideoMode& video_mode, const sf::String& window_title) : + IState(state_manager), IWindowKeeper(video_mode, window_title) { + m_window.setFramerateLimit(config::FRAME_RATE_LIMIT); + m_window.setKeyRepeatEnabled(false); + m_rect.setSize(config::NOTIFICATION_BANNER_SIZE); + m_rect.setFillColor(sf::Color(240, 0, 0, 50)); + m_rect.setPosition( + round((static_cast<float>(m_window.getSize().x) - m_rect.getSize().x) / 2.0f), + round((static_cast<float>(m_window.getSize().y) - m_rect.getSize().y) / 2.0f) + ); + m_text.setFont(MyFont::Instance()); + m_text.setCharacterSize(config::NOTIFICATION_FONT_SIZE); + m_text.setStyle(sf::Text::Bold); + m_text.setFillColor(config::TEXT_COLOR_NOTIFICATION); +} + void GameState::event_handling() { sf::Event event{}; while (m_window.pollEvent(event)) { if (event.type == sf::Event::Closed) { m_state_manager.set_next_state(std::make_unique<SelectState>(m_state_manager, config::SELECT_LEVEL_VIDEO_MODE, config::SELECT_LEVEL_TITLE)); } + if (event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::Space) { + GameContext& context = m_context_manager.get_current_context(); + switch (context.state) { + case GameContext::BEGIN: + case GameContext::PAUSE: + context.state = GameContext::INGAME; + break; + case GameContext::INGAME: + context.state = GameContext::PAUSE; + break; + default: + } + } if (event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::Z && event.key.control) m_context_manager.restore_previous_context(); if (event.type == sf::Event::KeyPressed && m_context_manager.get_current_context().state == GameContext::INGAME) - process_key_pressed(event.key.code); + process_control_key_pressed(event.key.code); } } @@ -42,62 +71,83 @@ void GameState::update() { } void GameState::render() { - sf::Text text; - sf::RectangleShape rect; - switch (m_context_manager.get_current_context().state) { + draw_notification(); + m_maze.draw_into(m_window); + for (const auto& obj : m_context_manager.get_current_context().static_objects) + obj->draw_into(m_window); + m_context_manager.get_current_context().pacman.draw_into(m_window); + for (const auto& obj : m_context_manager.get_current_context().dynamic_objects) + obj->draw_into(m_window); + if (m_context_manager.get_current_context().state != GameContext::INGAME) { + m_window.draw(m_rect); + m_window.draw(m_text); + } + m_window.display(); +} + +void GameState::draw_notification() { + switch (m_context_manager.get_current_context().state) { + case GameContext::BEGIN: + m_window.clear(config::GAME_COLOR_BACKGROUND_INGAME); + m_rect.setFillColor(config::NOTIFICATION_BANNER_COLOR_PLAY); + m_text.setString(config::TEXT_PLAY); + m_text.setPosition( + m_rect.getPosition().x + (m_rect.getSize().x - m_text.getLocalBounds().width) / 2.0f - m_text.getLocalBounds().left, + m_rect.getPosition().y + (m_rect.getSize().y - m_text.getLocalBounds().height) / 2.0f - m_text.getLocalBounds().top + ); + break; case GameContext::INGAME: m_window.clear(config::GAME_COLOR_BACKGROUND_INGAME); break; + case GameContext::PAUSE: + m_window.clear(config::GAME_COLOR_BACKGROUND_PAUSE); + m_rect.setFillColor(config::NOTIFICATION_BANNER_COLOR_PAUSE); + m_text.setString(config::TEXT_PAUSE); + m_text.setPosition( + m_rect.getPosition().x + (m_rect.getSize().x - m_text.getLocalBounds().width) / 2.0f - m_text.getLocalBounds().left, + m_rect.getPosition().y + (m_rect.getSize().y - m_text.getLocalBounds().height) / 2.0f - m_text.getLocalBounds().top + ); + break; case GameContext::LOST: - text.setFont(MyFont::Instance()); - text.setFillColor({255, 0, 0, 220}); - text.setString("LOST!"); - text.setCharacterSize(300); - text.setStyle(sf::Text::Bold); - text.setPosition( - round((m_window.getSize().x - text.getLocalBounds().width) / 2 - text.getLocalBounds().left), - round((m_window.getSize().y - text.getLocalBounds().height) / 2 - text.getLocalBounds().top) - ); - rect.setSize(sf::Vector2f(text.getLocalBounds().width + 100, text.getLocalBounds().height + 100)); - rect.setFillColor(sf::Color(240, 0, 0, 50)); - rect.setOutlineThickness(5); - rect.setOutlineColor(sf::Color::White); - rect.setPosition( - round((m_window.getSize().x - rect.getSize().x) / 2), - round((m_window.getSize().y - rect.getSize().y) / 2) - ); - m_window.clear(config::GAME_COLOR_BACKGROUND_INGAME); + m_window.clear(config::GAME_COLOR_BACKGROUND_LOST); + m_rect.setFillColor(config::NOTIFICATION_BANNER_COLOR_LOST); + m_text.setString(config::TEXT_LOST); + m_text.setPosition( + m_rect.getPosition().x + (m_rect.getSize().x - m_text.getLocalBounds().width) / 2.0f - m_text.getLocalBounds().left, + m_rect.getPosition().y + (m_rect.getSize().y - m_text.getLocalBounds().height) / 2.0f - m_text.getLocalBounds().top + ); break; case GameContext::WIN: m_window.clear(config::GAME_COLOR_BACKGROUND_WIN); + m_rect.setFillColor(config::NOTIFICATION_BANNER_COLOR_WIN); + m_text.setString(config::TEXT_WIN); + m_text.setPosition( + m_rect.getPosition().x + (m_rect.getSize().x - m_text.getLocalBounds().width) / 2.0f - m_text.getLocalBounds().left, + m_rect.getPosition().y + (m_rect.getSize().y - m_text.getLocalBounds().height) / 2.0f - m_text.getLocalBounds().top + ); break; } - m_maze.draw_into(m_window); - for (const auto& obj : m_context_manager.get_current_context().static_objects) - obj->draw_into(m_window); - m_context_manager.get_current_context().pacman.draw_into(m_window); - for (const auto& obj : m_context_manager.get_current_context().dynamic_objects) - obj->draw_into(m_window); - m_window.draw(rect); - m_window.draw(text); - m_window.display(); } -void GameState::process_key_pressed(const sf::Keyboard::Key key) { +void GameState::process_control_key_pressed(const sf::Keyboard::Key key) { switch (key) { case config::KEY_UP: + case config::KEY_UP_2: m_context_manager.save_context(); m_context_manager.get_current_context().pacman.replace(Room::UP); break; case config::KEY_DOWN: + case config::KEY_DOWN_2: m_context_manager.save_context(); m_context_manager.get_current_context().pacman.replace(Room::DOWN); break; case config::KEY_LEFT: + case config::KEY_LEFT_2: m_context_manager.save_context(); m_context_manager.get_current_context().pacman.replace(Room::LEFT); break; case config::KEY_RIGHT: + case config::KEY_RIGHT_2: m_context_manager.save_context(); m_context_manager.get_current_context().pacman.replace(Room::RIGHT); break; diff --git a/source/States/GameState/GameState.h b/source/States/GameState/GameState.h index 83cdfbf..0d23325 100644 --- a/source/States/GameState/GameState.h +++ b/source/States/GameState/GameState.h @@ -7,11 +7,7 @@ class GameState final : public IState, public IWindowKeeper { public: - explicit GameState(IStateManager& state_manager, const sf::VideoMode& video_mode, const sf::String& window_title) : - IState(state_manager), IWindowKeeper(video_mode, window_title) { - m_window.setFramerateLimit(config::FRAME_RATE_LIMIT); - m_window.setKeyRepeatEnabled(false); - } + explicit GameState(IStateManager& state_manager, const sf::VideoMode& video_mode, const sf::String& window_title); bool do_step() override; void set_maze(Maze&& maze) { m_maze = std::move(maze); } void set_context(GameContext&& context) { m_context_manager.reset(std::move(context)); } @@ -19,8 +15,11 @@ private: void event_handling() override; void update() override; void render() override; - void process_key_pressed(sf::Keyboard::Key key); + void process_control_key_pressed(sf::Keyboard::Key key); + void draw_notification(); private: Maze m_maze; ContextManager m_context_manager; + sf::Text m_text; + sf::RectangleShape m_rect; }; -- GitLab