From 01fa749e3100fb67ae31b2dcc28e79a87bb03917 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, 15 Mar 2025 21:20:49 +0300 Subject: [PATCH] Standard ComplexBuilder was implemented and previous ComplexBuilder -> ComplexRandomBuilder. Final was added to some classes. --- source/Application/Application.h | 2 +- source/BasicAbstractions/Button/Button.h | 2 +- source/BasicAbstractions/Font.h | 2 +- source/Configuration.h | 5 +- source/States/ExitState/ExitState.h | 2 +- .../States/GameState/Context/ContextManager.h | 2 +- source/States/GameState/Context/GameContext.h | 2 +- .../DynamicEntities/DynamicEntities.h | 2 +- .../States/GameState/Entities/Pacman/Pacman.h | 2 +- .../Entities/StaticEntities/StaticEntities.h | 2 +- .../GameState/GameBuilder/GameBuilder.cpp | 119 ++++++++++++++++-- .../GameState/GameBuilder/GameBuilder.h | 12 +- .../GameBuilder/GameBuilderDirector.h | 2 +- source/States/GameState/GameState.h | 2 +- source/States/GameState/Maze/Maze.h | 2 +- source/States/GameState/Maze/Room/Room.h | 2 +- .../GameState/Maze/Room/RoomSide/RoomSide.h | 4 +- source/States/SelectState/SelectState.cpp | 14 ++- source/States/SelectState/SelectState.h | 6 +- 19 files changed, 153 insertions(+), 33 deletions(-) diff --git a/source/Application/Application.h b/source/Application/Application.h index a813170..0900b6f 100644 --- a/source/Application/Application.h +++ b/source/Application/Application.h @@ -1,7 +1,7 @@ #pragma once #include <States/SelectState/SelectState.h> -class Application : public IStateManager { +class Application final : public IStateManager { public: Application() = default; int run(); diff --git a/source/BasicAbstractions/Button/Button.h b/source/BasicAbstractions/Button/Button.h index add9902..5695c94 100644 --- a/source/BasicAbstractions/Button/Button.h +++ b/source/BasicAbstractions/Button/Button.h @@ -2,7 +2,7 @@ #include <BasicAbstractions/Command.h> #include <BasicAbstractions/IDrawable.h> -class Button: public IDrawable { +class Button final : public IDrawable { public: Button() = default; void set(sf::Vector2f pos, sf::Vector2f size, const std::string& text, size_t font_size, std::unique_ptr<ISelectCommand> ptr_command); diff --git a/source/BasicAbstractions/Font.h b/source/BasicAbstractions/Font.h index 4fd6264..d77f027 100644 --- a/source/BasicAbstractions/Font.h +++ b/source/BasicAbstractions/Font.h @@ -1,7 +1,7 @@ #pragma once #include <Configuration.h> -class MyFont { +class MyFont final { public: static sf::Font& Instance() { static MyFont instance; diff --git a/source/Configuration.h b/source/Configuration.h index 676104d..84d12d4 100644 --- a/source/Configuration.h +++ b/source/Configuration.h @@ -5,7 +5,7 @@ namespace config { // Общее: constexpr unsigned int FRAME_RATE_LIMIT = 60; // Меню: - const sf::Vector2f BUTTON_SIZE = { 250, 100 }; + const sf::Vector2f BUTTON_SIZE = { 250, 80 }; const size_t BUTTON_FONT_SIZE = static_cast<size_t>(BUTTON_SIZE.y / 1.5f); constexpr float BUTTON_FRAME_THICKNESS = 2.0f; constexpr char FONT_FILE[] = ASSETS_PATH "calibril.ttf"; @@ -14,6 +14,7 @@ namespace config { constexpr char BUTTON_TEXT_EASY[] = "Easy"; constexpr char BUTTON_TEXT_MEDIUM[] = "Medium"; constexpr char BUTTON_TEXT_HARD[] = "Hard"; + constexpr char BUTTON_TEXT_EXTREME[] = "Extreme"; constexpr char BUTTON_TEXT_EXIT[] = "Exit"; // РРіСЂР°: const sf::VideoMode GAME_VIDEO_MODE{ 1080, 720 }; @@ -25,7 +26,7 @@ namespace config { constexpr float HARD_GAME_ENEMY_RATIO = 0.07f; constexpr float ROOM_SIZE = 50; constexpr float GAME_ENEMY_SIZE = ROOM_SIZE * 0.7; - constexpr float GAME_FOOD_SIZE = ROOM_SIZE * 0.2; + constexpr float GAME_FOOD_SIZE = ROOM_SIZE * 0.1; // Пакмэн: constexpr float GAME_PACMAN_SIZE = ROOM_SIZE * 0.8; // constexpr sf::Keyboard::Key KEY_LEFT = sf::Keyboard::A; diff --git a/source/States/ExitState/ExitState.h b/source/States/ExitState/ExitState.h index f886cd4..ed914a5 100644 --- a/source/States/ExitState/ExitState.h +++ b/source/States/ExitState/ExitState.h @@ -1,7 +1,7 @@ #pragma once #include <BasicAbstractions/IState.h> -struct ExitState : IState { +struct ExitState final : IState { using IState::IState; bool do_step() noexcept override { return false; } }; \ No newline at end of file diff --git a/source/States/GameState/Context/ContextManager.h b/source/States/GameState/Context/ContextManager.h index 9c84bc3..8ad7e9f 100644 --- a/source/States/GameState/Context/ContextManager.h +++ b/source/States/GameState/Context/ContextManager.h @@ -2,7 +2,7 @@ #include <States/GameState/Context/GameContext.h> #include <stack> -class ContextManager { +class ContextManager final { public: void reset(GameContext&& context); GameContext& get_current_context() { return m_contexts.top(); } diff --git a/source/States/GameState/Context/GameContext.h b/source/States/GameState/Context/GameContext.h index 81b3bdc..21022b2 100644 --- a/source/States/GameState/Context/GameContext.h +++ b/source/States/GameState/Context/GameContext.h @@ -3,7 +3,7 @@ #include <States/GameState/Entities/StaticEntities/StaticEntities.h> #include <States/GameState/Entities/DynamicEntities/DynamicEntities.h> -struct GameContext { +struct GameContext final { [[nodiscard]] GameContext clone() const; Pacman pacman; std::vector<std::unique_ptr<IStaticEntity>> static_objects; diff --git a/source/States/GameState/Entities/DynamicEntities/DynamicEntities.h b/source/States/GameState/Entities/DynamicEntities/DynamicEntities.h index b8be739..2033a0f 100644 --- a/source/States/GameState/Entities/DynamicEntities/DynamicEntities.h +++ b/source/States/GameState/Entities/DynamicEntities/DynamicEntities.h @@ -8,7 +8,7 @@ struct IDynamicEntity : IEntity { ~IDynamicEntity() override = default; }; -class Enemy : public IDynamicEntity { +class Enemy final : public IDynamicEntity { public: Enemy(); [[nodiscard]] std::unique_ptr<IDynamicEntity> clone() const override; diff --git a/source/States/GameState/Entities/Pacman/Pacman.h b/source/States/GameState/Entities/Pacman/Pacman.h index 827fb79..03772e0 100644 --- a/source/States/GameState/Entities/Pacman/Pacman.h +++ b/source/States/GameState/Entities/Pacman/Pacman.h @@ -1,7 +1,7 @@ #pragma once #include <States/GameState/Entities/IEntity.h> -class Pacman : public IEntity { +class Pacman final : public IEntity { public: Pacman(); void move(Room::Direction direction); diff --git a/source/States/GameState/Entities/StaticEntities/StaticEntities.h b/source/States/GameState/Entities/StaticEntities/StaticEntities.h index d005d7d..193f3fc 100644 --- a/source/States/GameState/Entities/StaticEntities/StaticEntities.h +++ b/source/States/GameState/Entities/StaticEntities/StaticEntities.h @@ -6,7 +6,7 @@ struct IStaticEntity : IEntity { ~IStaticEntity() override = default; }; -class Food : public IStaticEntity { +class Food final : public IStaticEntity { public: Food(); [[nodiscard]] std::unique_ptr<IStaticEntity> clone() const override; diff --git a/source/States/GameState/GameBuilder/GameBuilder.cpp b/source/States/GameState/GameBuilder/GameBuilder.cpp index 0c4502f..db301b6 100644 --- a/source/States/GameState/GameBuilder/GameBuilder.cpp +++ b/source/States/GameState/GameBuilder/GameBuilder.cpp @@ -57,7 +57,7 @@ void SimpleBuilder::create_rooms() { const auto number_of_rooms_in_row = static_cast<size_t>(m_width / m_room_size), number_of_rooms_in_col = static_cast<size_t>(m_height / m_room_size); - sf::Vector2f gap( + const sf::Vector2f gap( (m_width - static_cast<float>(number_of_rooms_in_row) * m_room_size + m_room_size) / 2.f, (m_height - static_cast<float>(number_of_rooms_in_col) * m_room_size + m_room_size) / 2.f ); @@ -78,8 +78,8 @@ void SimpleBuilder::create_rooms() { void SimpleBuilder::set_rooms_sides() { if (m_rooms.empty()) return; if (m_rooms[0].empty()) return; - for (size_t i = 0; i < m_rooms[0].size(); ++i) - m_rooms[0][i]->set_side(Room::UP, std::make_shared<Wall>(*m_rooms[0][i])); + for (const auto & room : m_rooms[0]) + room->set_side(Room::UP, std::make_shared<Wall>(*room)); m_rooms[0][0]->set_side(Room::LEFT, std::make_shared<Wall>(*m_rooms[0][0])); for (size_t i = 1; i < m_rooms[0].size() - 1; ++i) { auto tmp_side_ptr = std::make_shared<Pass>(*m_rooms[0][i], *m_rooms[0][i-1]); @@ -110,19 +110,122 @@ void SimpleBuilder::set_rooms_sides() { } } -ComplexBuilder::ComplexBuilder(const float width, const float height, const float room_size, const sf::Color room_color) : +void ComplexBuilder::create_rooms() { + const auto number_of_rooms_in_row = static_cast<size_t>(m_width / m_room_size), + number_of_rooms_in_col = static_cast<size_t>(m_height / m_room_size); + + const sf::Vector2f gap( + (m_width - static_cast<float>(number_of_rooms_in_row) * m_room_size + m_room_size) / 2.f, + (m_height - static_cast<float>(number_of_rooms_in_col) * m_room_size + m_room_size) / 2.f + ); + + for (size_t i = 0; i < number_of_rooms_in_col; ++i) { + std::vector<std::unique_ptr<Room>> room_row; + room_row.reserve(number_of_rooms_in_row); + for (size_t j = 0; j < number_of_rooms_in_row; ++j) { + if (i % 2 == 0 && j % 2 == 0) continue; + auto tmp_room = std::make_unique<Room>(m_room_size); + tmp_room->set_color(m_room_color); + tmp_room->set_position(gap + sf::Vector2f{ m_room_size * static_cast<float>(j), m_room_size * static_cast<float>(i) }); + room_row.emplace_back(std::move(tmp_room)); + } + m_rooms.emplace_back(std::move(room_row)); + } +} + +void ComplexBuilder::set_rooms_sides() { + if (m_rooms.empty()) return; + if (m_rooms[0].empty()) return; + for (size_t i = 0; i < m_rooms.size(); i+=2) { + for (const auto & room : m_rooms[i]) { + room->set_side(Room::LEFT, std::make_shared<Wall>(*room)); + room->set_side(Room::RIGHT, std::make_shared<Wall>(*room)); + } + } + for (const auto & room : m_rooms[0]) + room->set_side(Room::UP, std::make_shared<Wall>(*room)); + for (size_t i = 1; i < m_rooms.size() - 1; i+=2) { + m_rooms[i][0]->set_side(Room::LEFT, std::make_shared<Wall>(*m_rooms[i][0])); + m_rooms[i][0]->set_side(Room::UP, std::make_shared<Wall>(*m_rooms[i][0])); + m_rooms[i][0]->set_side(Room::DOWN, std::make_shared<Wall>(*m_rooms[i][0])); + for (size_t j = 1; j < m_rooms[i].size() - 1; ++j) { + if (j % 2 == 0) { + m_rooms[i][j]->set_side(Room::UP, std::make_shared<Wall>(*m_rooms[i][j])); + m_rooms[i][j]->set_side(Room::DOWN, std::make_shared<Wall>(*m_rooms[i][j])); + continue; + } + auto side_ptr_temp = std::make_shared<Pass>(*m_rooms[i][j], *m_rooms[i-1][j-j/2-1]); + m_rooms[i][j]->set_side(Room::UP, side_ptr_temp); + m_rooms[i-1][j-j/2-1]->set_side(Room::DOWN, side_ptr_temp); + side_ptr_temp = std::make_shared<Pass>(*m_rooms[i][j], *m_rooms[i][j-1]); + m_rooms[i][j]->set_side(Room::LEFT, side_ptr_temp); + m_rooms[i][j-1]->set_side(Room::RIGHT, side_ptr_temp); + side_ptr_temp = std::make_shared<Pass>(*m_rooms[i][j], *m_rooms[i][j+1]); + m_rooms[i][j]->set_side(Room::RIGHT, side_ptr_temp); + m_rooms[i][j+1]->set_side(Room::LEFT, side_ptr_temp); + side_ptr_temp = std::make_shared<Pass>(*m_rooms[i][j], *m_rooms[i+1][j-j/2-1]); + m_rooms[i][j]->set_side(Room::DOWN, side_ptr_temp); + m_rooms[i+1][j-j/2-1]->set_side(Room::UP, side_ptr_temp); + } + if (m_rooms[i].size() % 2 == 1) { + m_rooms[i][m_rooms[i].size()-1]->set_side(Room::UP, std::make_shared<Wall>(*m_rooms[i][m_rooms[i].size()-1])); + m_rooms[i][m_rooms[i].size()-1]->set_side(Room::DOWN, std::make_shared<Wall>(*m_rooms[i][m_rooms[i].size()-1])); + } + else { + auto side_ptr_temp = std::make_shared<Pass>(*m_rooms[i][m_rooms[i].size()-1], *m_rooms[i][m_rooms[i].size()-2]); + m_rooms[i][m_rooms[i].size()-1]->set_side(Room::LEFT, side_ptr_temp); + m_rooms[i][m_rooms[i].size()-2]->set_side(Room::RIGHT, side_ptr_temp); + side_ptr_temp = std::make_shared<Pass>(*m_rooms[i][m_rooms[i].size()-1], *m_rooms[i-1][m_rooms[i].size()-1]); + m_rooms[i][m_rooms[i].size()-1]->set_side(Room::UP, side_ptr_temp); + m_rooms[i-1][m_rooms[i].size()-1]->set_side(Room::DOWN, side_ptr_temp); + } + m_rooms[i][m_rooms[i].size()-1]->set_side(Room::RIGHT, std::make_shared<Wall>(*m_rooms[i][m_rooms[i].size()-1])); + } + for (auto& room : m_rooms[m_rooms.size()-1]) + room->set_side(Room::DOWN, std::make_shared<Wall>(*room)); + if (m_rooms.size() % 2 == 0) { + m_rooms[m_rooms.size()-1][0]->set_side(Room::UP, std::make_shared<Wall>(*m_rooms[m_rooms.size()-1][0])); + m_rooms[m_rooms.size()-1][0]->set_side(Room::LEFT, std::make_shared<Wall>(*m_rooms[m_rooms.size()-1][0])); + for (size_t i = 1; i < m_rooms[m_rooms.size()-1].size() - 1; ++i) { + if (i % 2 == 0) { + m_rooms[m_rooms.size()-1][i]->set_side(Room::UP, std::make_shared<Wall>(*m_rooms[m_rooms.size()-1][i])); + continue; + } + auto side_ptr_temp = std::make_shared<Pass>(*m_rooms[m_rooms.size()-1][i], *m_rooms[m_rooms.size()-2][i-i/2-1]); + m_rooms[m_rooms.size()-1][i]->set_side(Room::UP, side_ptr_temp); + m_rooms[m_rooms.size()-2][i-i/2-1]->set_side(Room::DOWN, side_ptr_temp); + side_ptr_temp = std::make_shared<Pass>(*m_rooms[m_rooms.size()-1][i-1], *m_rooms[m_rooms.size()-1][i]); + m_rooms[m_rooms.size()-1][i]->set_side(Room::LEFT, side_ptr_temp); + m_rooms[m_rooms.size()-1][i-1]->set_side(Room::RIGHT, side_ptr_temp); + side_ptr_temp = std::make_shared<Pass>(*m_rooms[m_rooms.size()-1][i+1], *m_rooms[m_rooms.size()-1][i]); + m_rooms[m_rooms.size()-1][i]->set_side(Room::RIGHT, side_ptr_temp); + m_rooms[m_rooms.size()-1][i+1]->set_side(Room::LEFT, side_ptr_temp); + } + if (m_rooms[m_rooms.size()-1].size() % 2 == 1) { + m_rooms[m_rooms.size()-1][m_rooms[m_rooms.size()-1].size()-1]->set_side(Room::UP, std::make_shared<Wall>(*m_rooms[m_rooms.size()-1][m_rooms[m_rooms.size()-1].size()-1])); + } + else { + auto side_ptr_temp = std::make_shared<Pass>(*m_rooms[m_rooms.size()-1][m_rooms[m_rooms.size()-1].size()-1], *m_rooms[m_rooms.size()-2][m_rooms[m_rooms.size()-1].size()-1]); + m_rooms[m_rooms.size()-1][m_rooms[m_rooms.size()-1].size()-1]->set_side(Room::UP, side_ptr_temp); + m_rooms[m_rooms.size()-2][m_rooms[m_rooms.size()-1].size()-1]->set_side(Room::DOWN, side_ptr_temp); + } + m_rooms[m_rooms.size()-1][m_rooms[m_rooms.size()-1].size()-1]->set_side(Room::RIGHT, std::make_shared<Wall>(*m_rooms[m_rooms.size()-1][m_rooms[m_rooms.size()-1].size()-1])); + } +} + +ComplexRandomBuilder::ComplexRandomBuilder(const float width, const float height, const float room_size, const sf::Color room_color) : CommonBuilder(width, height, room_size, room_color), m_rooms_grid(static_cast<size_t>(height / m_room_size), std::vector(static_cast<size_t>(width / m_room_size), false)), m_number_of_rooms_in_row(static_cast<size_t>(width / m_room_size)), m_number_of_rooms_in_col(static_cast<size_t>(height / m_room_size)), gen(rd()) {} -bool ComplexBuilder::is_valid(const int x, const int y) const { +bool ComplexRandomBuilder::is_valid(const int x, const int y) const { if (x >= m_number_of_rooms_in_row || y >= m_number_of_rooms_in_col || x < 0 || y < 0) return false; return true; } -void ComplexBuilder::collapse_function() { +void ComplexRandomBuilder::collapse_function() { std::uniform_int_distribution<size_t> row_dist(0, m_number_of_rooms_in_row-1); std::uniform_int_distribution<size_t> col_dist(0, m_number_of_rooms_in_col-1); std::normal_distribution prob_dist(0.67f, 0.25f); @@ -162,7 +265,7 @@ void ComplexBuilder::collapse_function() { } } -void ComplexBuilder::create_rooms() { +void ComplexRandomBuilder::create_rooms() { collapse_function(); const sf::Vector2f gap( @@ -189,7 +292,7 @@ void ComplexBuilder::create_rooms() { } } -void ComplexBuilder::set_rooms_sides() { +void ComplexRandomBuilder::set_rooms_sides() { for (size_t i = 0; i < m_number_of_rooms_in_col; ++i) { for (size_t j = 0; j < m_number_of_rooms_in_row; ++j) { if (!m_rooms_grid[i][j]) continue; diff --git a/source/States/GameState/GameBuilder/GameBuilder.h b/source/States/GameState/GameBuilder/GameBuilder.h index eee5204..3188076 100644 --- a/source/States/GameState/GameBuilder/GameBuilder.h +++ b/source/States/GameState/GameBuilder/GameBuilder.h @@ -31,15 +31,21 @@ protected: std::unique_ptr<GameState> m_game_state; }; -struct SimpleBuilder : CommonBuilder { +struct SimpleBuilder final : CommonBuilder { using CommonBuilder::CommonBuilder; void create_rooms() override; void set_rooms_sides() override; }; -class ComplexBuilder : public CommonBuilder { +struct ComplexBuilder final : CommonBuilder { + using CommonBuilder::CommonBuilder; + void create_rooms() override; + void set_rooms_sides() override; +}; + +class ComplexRandomBuilder final : public CommonBuilder { public: - ComplexBuilder(float width, float height, float room_size, sf::Color room_color); + ComplexRandomBuilder(float width, float height, float room_size, sf::Color room_color); void create_rooms() override; void set_rooms_sides() override; private: diff --git a/source/States/GameState/GameBuilder/GameBuilderDirector.h b/source/States/GameState/GameBuilder/GameBuilderDirector.h index 0f39088..407f38d 100644 --- a/source/States/GameState/GameBuilder/GameBuilderDirector.h +++ b/source/States/GameState/GameBuilder/GameBuilderDirector.h @@ -1,7 +1,7 @@ #pragma once #include <States/GameState/GameBuilder/GameBuilder.h> -class GameBuilderDirector { +class GameBuilderDirector final { public: GameBuilderDirector(std::unique_ptr<IGameBuilder>&& ptr_builder, const sf::VideoMode& mode, std::string window_title, const float dynamic_object_ratio) : m_window_title(std::move(window_title)), m_mode(mode), m_dynamic_object_ratio(dynamic_object_ratio), m_ptr_builder(std::move(ptr_builder)) {} diff --git a/source/States/GameState/GameState.h b/source/States/GameState/GameState.h index 16359aa..cc5a479 100644 --- a/source/States/GameState/GameState.h +++ b/source/States/GameState/GameState.h @@ -5,7 +5,7 @@ #include <States/GameState/Maze/Maze.h> #include <States/GameState/Context/ContextManager.h> -class GameState : public IState, public IWindowKeeper { +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) { diff --git a/source/States/GameState/Maze/Maze.h b/source/States/GameState/Maze/Maze.h index ee99379..e6d29e6 100644 --- a/source/States/GameState/Maze/Maze.h +++ b/source/States/GameState/Maze/Maze.h @@ -4,7 +4,7 @@ #include <vector> -class Maze : public IDrawable { +class Maze final : public IDrawable { public: Maze() = default; explicit Maze(std::vector<std::unique_ptr<Room>>&& rooms) : m_rooms(std::move(rooms)) {} diff --git a/source/States/GameState/Maze/Room/Room.h b/source/States/GameState/Maze/Room/Room.h index 844107c..a6780f3 100644 --- a/source/States/GameState/Maze/Room/Room.h +++ b/source/States/GameState/Maze/Room/Room.h @@ -7,7 +7,7 @@ struct IRoomSide; -class Room: public IDrawable { +class Room final : public IDrawable { public: enum Direction { INVALID = -1, LEFT, RIGHT, UP, DOWN }; explicit Room(float size); diff --git a/source/States/GameState/Maze/Room/RoomSide/RoomSide.h b/source/States/GameState/Maze/Room/RoomSide/RoomSide.h index 411fc35..07a452b 100644 --- a/source/States/GameState/Maze/Room/RoomSide/RoomSide.h +++ b/source/States/GameState/Maze/Room/RoomSide/RoomSide.h @@ -9,7 +9,7 @@ struct IRoomSide : IPreparable { ~IRoomSide() override = default; }; -class Pass : public IRoomSide { +class Pass final : public IRoomSide { public: explicit Pass(Room& room1, Room& room2) : m_room1(room1), m_room2(room2) {} void enter(IEntity* entity) const override; @@ -20,7 +20,7 @@ private: Room& m_room2; }; -class Wall : public IRoomSide { +class Wall final : public IRoomSide { public: explicit Wall(Room& room) : m_room(room) {} void enter(IEntity* entity) const override {} diff --git a/source/States/SelectState/SelectState.cpp b/source/States/SelectState/SelectState.cpp index 28fa929..8332659 100644 --- a/source/States/SelectState/SelectState.cpp +++ b/source/States/SelectState/SelectState.cpp @@ -4,8 +4,8 @@ Menu::Menu(IStateManager& state_manager) { const float pos_left = (static_cast<float>(config::SELECT_LEVEL_VIDEO_MODE.width) - config::BUTTON_SIZE.x) / 2; - const float pos_diff = (static_cast<float>(config::SELECT_LEVEL_VIDEO_MODE.height) - config::BUTTON_SIZE.y * 4) / 10; - const float pos_top = (static_cast<float>(config::SELECT_LEVEL_VIDEO_MODE.height) - config::BUTTON_SIZE.y*4 - pos_diff*3) / 2; + const float pos_diff = (static_cast<float>(config::SELECT_LEVEL_VIDEO_MODE.height) - config::BUTTON_SIZE.y * 5) / 10; + const float pos_top = (static_cast<float>(config::SELECT_LEVEL_VIDEO_MODE.height) - config::BUTTON_SIZE.y*5 - pos_diff*4) / 2; auto easy_level_command = std::make_unique<GameCommand>( state_manager, @@ -31,6 +31,14 @@ Menu::Menu(IStateManager& state_manager) { config::HARD_GAME_TITLE, config::HARD_GAME_ENEMY_RATIO)); + auto extreme_level_command = std::make_unique<GameCommand>( + state_manager, + std::make_unique<GameBuilderDirector>( + std::make_unique<ComplexRandomBuilder>(config::GAME_VIDEO_MODE.width, config::GAME_VIDEO_MODE.height, config::ROOM_SIZE, config::GAME_COLOR_ROOM), + config::GAME_VIDEO_MODE, + config::HARD_GAME_TITLE, + config::HARD_GAME_ENEMY_RATIO)); + m_buttons[0].set(sf::Vector2f{pos_left, pos_top}, config::BUTTON_SIZE, config::BUTTON_TEXT_EASY, config::BUTTON_FONT_SIZE, std::move(easy_level_command)); m_buttons[1].set(sf::Vector2f{pos_left, pos_top + config::BUTTON_SIZE.y + pos_diff}, config::BUTTON_SIZE, @@ -38,6 +46,8 @@ Menu::Menu(IStateManager& state_manager) { m_buttons[2].set(sf::Vector2f{pos_left, pos_top + 2*(config::BUTTON_SIZE.y + pos_diff)}, config::BUTTON_SIZE, config::BUTTON_TEXT_HARD, config::BUTTON_FONT_SIZE, std::move(hard_level_command)); m_buttons[3].set(sf::Vector2f{pos_left, pos_top + 3*(config::BUTTON_SIZE.y + pos_diff)}, config::BUTTON_SIZE, + config::BUTTON_TEXT_EXTREME, config::BUTTON_FONT_SIZE, std::move(extreme_level_command)); + m_buttons[4].set(sf::Vector2f{pos_left, pos_top + 4*(config::BUTTON_SIZE.y + pos_diff)}, config::BUTTON_SIZE, config::BUTTON_TEXT_EXIT, config::BUTTON_FONT_SIZE, std::make_unique<ExitCommand>(state_manager)); } diff --git a/source/States/SelectState/SelectState.h b/source/States/SelectState/SelectState.h index f94f31c..fd99b81 100644 --- a/source/States/SelectState/SelectState.h +++ b/source/States/SelectState/SelectState.h @@ -5,16 +5,16 @@ #include <BasicAbstractions/IDrawable.h> #include <BasicAbstractions/Button/Button.h> -class Menu: public IDrawable { +class Menu final : public IDrawable { public: explicit Menu(IStateManager& state_manager); void process_mouse(sf::Vector2f pos, bool is_pressed); void draw_into(sf::RenderWindow& window) const override; private: - std::array<Button, 4> m_buttons; + std::array<Button, 5> m_buttons; }; -class SelectState : public IState, public IWindowKeeper { +class SelectState final : public IState, public IWindowKeeper { public: explicit SelectState(IStateManager& state_manager, const sf::VideoMode& video_mode, const sf::String& window_title) : IState(state_manager), IWindowKeeper(video_mode, window_title), m_menu(state_manager) { -- GitLab