From ff5012dce6bf355f58ba9352206e20da9c1e716d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A3=D1=88=D0=BA=D0=BE=D0=B2=D0=B0=20=D0=94=D0=B8=D0=B0?= =?UTF-8?q?=D0=BD=D0=B0=20=D0=9F=D0=B5=D1=82=D1=80=D0=BE=D0=B2=D0=BD=D0=B0?= <dpushkova@edu.hse.ru> Date: Thu, 6 Mar 2025 08:22:54 +0000 Subject: [PATCH] created hardLevel, texture for food and Pacman --- CMakeLists.txt | 3 +- source/application/App/Application.cpp | 3 +- source/application/App/Application.h | 2 +- .../application/BobBuilder/GameBuilders.cpp | 95 +++++++++++++++++- source/application/Context/Context.cpp | 2 +- source/application/Context/Context.h | 7 +- .../application/Drawable/DrawMenu/Font/Font.h | 2 +- .../Drawable/DrawMenu/Menu/Menu.cpp | 2 +- .../application/Drawable/Entity/IEntity.cpp | 18 ++-- source/application/Drawable/Entity/IEntity.h | 9 +- .../application/Drawable/Entity/MyTexture.cpp | 28 ++++++ .../application/Drawable/Entity/MyTexture.h | 35 +++++++ source/application/Drawable/Entity/Pacman.cpp | 19 ++-- source/application/Drawable/Entity/Pacman.h | 6 +- source/application/Drawable/Maze/Maze.h | 3 +- .../SelectCommand/ISelectCommand.cpp | 2 - source/application/State/GameState.cpp | 33 +++--- source/application/State/IState.cpp | 2 - workdir/assets/apple.png | Bin 0 -> 1211 bytes workdir/assets/pacman.png | Bin 0 -> 2732 bytes workdir/assets/pacmanDown.png | Bin 0 -> 2263 bytes workdir/assets/pacmanLeft.png | Bin 0 -> 2247 bytes workdir/assets/pacmanRight.png | Bin 0 -> 2217 bytes workdir/assets/pacmanUp.png | Bin 0 -> 2237 bytes 24 files changed, 214 insertions(+), 57 deletions(-) create mode 100644 source/application/Drawable/Entity/MyTexture.cpp create mode 100644 source/application/Drawable/Entity/MyTexture.h delete mode 100644 source/application/SelectCommand/ISelectCommand.cpp delete mode 100644 source/application/State/IState.cpp create mode 100644 workdir/assets/apple.png create mode 100644 workdir/assets/pacman.png create mode 100644 workdir/assets/pacmanDown.png create mode 100644 workdir/assets/pacmanLeft.png create mode 100644 workdir/assets/pacmanRight.png create mode 100644 workdir/assets/pacmanUp.png diff --git a/CMakeLists.txt b/CMakeLists.txt index cc0696b..6bb6638 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,7 +8,8 @@ FetchContent_Declare(SFML GIT_REPOSITORY https://github.com/SFML/SFML.git GIT_TA FetchContent_MakeAvailable(SFML) file(GLOB_RECURSE SOURCE_CPP source/*.cpp) -add_executable(pacman ${SOURCE_CPP}) +file(GLOB_RECURSE SOURCE_H source/*.h) +add_executable(pacman ${SOURCE_CPP} ${SOURCE_H}) target_link_libraries(pacman PRIVATE sfml-window sfml-graphics sfml-system) target_compile_definitions(pacman PRIVATE ASSETS_PATH="${CMAKE_CURRENT_SOURCE_DIR}/workdir/assets/") diff --git a/source/application/App/Application.cpp b/source/application/App/Application.cpp index 6bac2e1..0c2126a 100644 --- a/source/application/App/Application.cpp +++ b/source/application/App/Application.cpp @@ -28,6 +28,5 @@ void Application::set_next_state(std::unique_ptr<IState>&& ptr_state) { void Application::apply_deffer_state_change() noexcept { if (m_ptr_state_next) - std::swap(m_ptr_state_current, m_ptr_state_next); - m_ptr_state_next.reset(); + m_ptr_state_current = std::exchange(m_ptr_state_next, nullptr); } \ No newline at end of file diff --git a/source/application/App/Application.h b/source/application/App/Application.h index d8c0124..a08c9a4 100644 --- a/source/application/App/Application.h +++ b/source/application/App/Application.h @@ -10,7 +10,7 @@ class Application : public IStateManager { public: Application(); int run(); - ~Application() = default; + ~Application() override = default; private: void set_next_state(std::unique_ptr<IState>&& ptr_state) override; diff --git a/source/application/BobBuilder/GameBuilders.cpp b/source/application/BobBuilder/GameBuilders.cpp index 653f125..5afea2d 100644 --- a/source/application/BobBuilder/GameBuilders.cpp +++ b/source/application/BobBuilder/GameBuilders.cpp @@ -1,9 +1,7 @@ #include "GameBuilders.h" -#include <random> - CommonBuilder::CommonBuilder(float width, float height, float room_size) : - m_width(width), m_height(height), m_room_size(room_size){ + m_width(width), m_height(height), m_room_size(room_size){ } void CommonBuilder::create_context(float dynamic_objects_ratio) { @@ -12,16 +10,28 @@ void CommonBuilder::create_context(float dynamic_objects_ratio) { for (auto& room : row) if (room != nullptr) empty_rooms_buffer.emplace_back(room); + float id = std::rand() % empty_rooms_buffer.size(); + //в рандомное место располагаем пакмана m_context.pacman.set_location(empty_rooms_buffer[id]); auto it = std::next(empty_rooms_buffer.begin(), id); empty_rooms_buffer.erase(it); - //@todo располагать врагов + + //располагаем врагов + size_t rooms_row = static_cast<size_t>(m_width / m_room_size); + size_t rooms_col = static_cast<size_t>(m_height / m_room_size); + for (size_t i = 0; i < rooms_row * rooms_col * dynamic_objects_ratio; i++) { + id = std::rand() % empty_rooms_buffer.size(); + auto enemy = std::make_unique<Enemy>(); + enemy->set_location(empty_rooms_buffer.at(id)); + m_context.dynamic_objects.emplace_back(std::move(enemy)); + } //располагаем еду for (auto it : empty_rooms_buffer) { auto food = std::make_unique<Food>(); food->set_location(it); + food->set_texture(&FoodTexture::instance()); m_context.static_objects.emplace_back(std::move(food)); } empty_rooms_buffer.clear(); @@ -96,9 +106,84 @@ void SimpleBuilder::set_rooms_sides() { } void ComplexBuilder::create_rooms() { + size_t room_quantity_row = (m_height / m_room_size); + size_t room_quantity_col = (m_width / m_room_size); + int room_size = static_cast<int>(m_room_size); + auto starting_point = sf::Vector2f{(m_width - m_room_size*room_quantity_col)/2 + m_room_size/2, (m_height - m_room_size*room_quantity_row)/2 + + m_room_size/2}; + + for (int row = 0; row < room_quantity_row * room_size; row += room_size) { + std::vector<Room*> vector_row; + for (int col = 0; col < room_quantity_col * room_size; col += room_size) { + auto room = new Room(m_room_size); + room->set_position(sf::Vector2f {(col + starting_point.x), (row + starting_point.y)}); + vector_row.emplace_back(std::move(room)); + } + m_rooms.emplace_back(std::move(vector_row)); + } } void ComplexBuilder::set_rooms_sides() { + size_t cols = m_rooms[0].size(); + size_t rows = m_rooms.size(); + for (int j = 0; j < cols; j++) { + m_rooms[0][j]->set_side(Room::Direction::UP, std::make_unique<Wall>(*m_rooms[0][j])); + } + for (int j = 0; j < cols; j++) { + m_rooms[rows - 1][j]->set_side(Room::Direction::DOWN, std::make_unique<Wall>(*m_rooms[rows - 1][j])); + if (j != cols - 1) { + m_rooms[rows - 1][j]->set_side(Room::Direction::RIGHT, std::make_unique<Pass>(*m_rooms[rows - 1][j], *m_rooms[rows - 1][j+1])); + m_rooms[rows - 1][j+1]->set_side(Room::Direction::LEFT, std::make_unique<Pass>(*m_rooms[rows - 1][j+1], *m_rooms[rows - 1][j])); + } + } + for (int i = 0; i < rows ; i++) { + m_rooms[i][0]->set_side(Room::Direction::LEFT, std::make_unique<Wall>(*m_rooms[i][0])); + } + for (int i = 0; i < rows; i++) { + m_rooms[i][cols - 1]->set_side(Room::Direction::RIGHT, std::make_unique<Wall>(*m_rooms[i][cols - 1])); + } -} \ No newline at end of file + std::vector<int> row(cols); + int count = 0; + for (; count < cols; row[count] = count, count++); + for (int i = 0; i < rows - 1; i++) { + for (int j = 0; j < cols - 1; j++) { + if (rand() % 2) { + m_rooms[i][j]->set_side(Room::Direction::RIGHT, std::make_unique<Wall>(*m_rooms[i][j])); + m_rooms[i][j+1]->set_side(Room::Direction::LEFT, std::make_unique<Wall>(*m_rooms[i][j+1])); + } + else { + m_rooms[i][j]->set_side(Room::Direction::RIGHT, std::make_unique<Pass>(*m_rooms[i][j], *m_rooms[i][j+1])); + m_rooms[i][j+1]->set_side(Room::Direction::LEFT, std::make_unique<Pass>(*m_rooms[i][j+1], *m_rooms[i][j])); + int temp = row[j + 1]; + for (int k = 0; k < cols; k++) { + if (row[k] == temp) row[k] = row[j]; + } + } + } + for (int j = 0; j < cols; j++) { + if (rand() % 2) { + int temp = 0; + for (int k = 0; k < cols; k++) { + if (row[k] == row[j] && !m_rooms[i][k]->get_side(Room::Direction::DOWN)) temp++; + } + if (temp > 1) { + m_rooms[i][j]->set_side(Room::Direction::DOWN, std::make_unique<Wall>(*m_rooms[i][j])); + m_rooms[i+1][j]->set_side(Room::Direction::UP, std::make_unique<Wall>(*m_rooms[i+1][j])); + } + else { + m_rooms[i][j]->set_side(Room::Direction::DOWN, std::make_unique<Pass>(*m_rooms[i][j], *m_rooms[i+1][j])); + m_rooms[i+1][j]->set_side(Room::Direction::UP, std::make_unique<Pass>(*m_rooms[i+1][j], *m_rooms[i][j])); + } + } + else { + m_rooms[i][j]->set_side(Room::Direction::DOWN, std::make_unique<Pass>(*m_rooms[i][j], *m_rooms[i+1][j])); + m_rooms[i+1][j]->set_side(Room::Direction::UP, std::make_unique<Pass>(*m_rooms[i+1][j], *m_rooms[i][j])); + } + } + for (int j = 0; j < cols; j++) { + if (m_rooms[i][j]->get_side(Room::Direction::DOWN)) row[j] = count++; + } + } + +} diff --git a/source/application/Context/Context.cpp b/source/application/Context/Context.cpp index fe23398..fe3ae59 100644 --- a/source/application/Context/Context.cpp +++ b/source/application/Context/Context.cpp @@ -14,13 +14,13 @@ GameContext GameContext::clone() { return context; } -//@todo void ContextManager::restore_previous_context() { if (m_history.size() == 1) { m_initial_context = m_history.top().clone(); return; } m_initial_context = std::move(m_history.top()); + m_history.pop(); } void ContextManager::reset(GameContext &&context) { diff --git a/source/application/Context/Context.h b/source/application/Context/Context.h index 456d2e3..785b985 100644 --- a/source/application/Context/Context.h +++ b/source/application/Context/Context.h @@ -4,13 +4,14 @@ #include <istream> #include <list> -class GameContext { -public: +struct GameContext { enum State { INGAME, WIN, LOST } state = INGAME; std::list<std::unique_ptr<IDynamicEntity>> dynamic_objects; std::list<std::unique_ptr<IStaticEntity>> static_objects; + std::vector<MyTexture*> m_textures; + MyTexture* m_pacman_texture; + MyTexture* m_food_texture; Pacman pacman; -public: GameContext clone(); }; diff --git a/source/application/Drawable/DrawMenu/Font/Font.h b/source/application/Drawable/DrawMenu/Font/Font.h index 240f722..689eb11 100644 --- a/source/application/Drawable/DrawMenu/Font/Font.h +++ b/source/application/Drawable/DrawMenu/Font/Font.h @@ -7,7 +7,7 @@ public: MyFont(const MyFont&) = delete; MyFont& operator=(const MyFont&) = delete; static MyFont& Instance(); - operator const sf::Font&() const; //@todo why is this necessary + operator const sf::Font&() const; //приведение типа private: MyFont(); diff --git a/source/application/Drawable/DrawMenu/Menu/Menu.cpp b/source/application/Drawable/DrawMenu/Menu/Menu.cpp index 833f2c6..6ffe566 100644 --- a/source/application/Drawable/DrawMenu/Menu/Menu.cpp +++ b/source/application/Drawable/DrawMenu/Menu/Menu.cpp @@ -21,7 +21,7 @@ Menu::Menu(IStateManager& state_manager) { config::MEDIUM_GAME_TITLE, config::MEDIUM_GAME_ENEMY_RATIO); auto hard_director = std::make_unique<GameBuilderDirector>( - std::make_unique<SimpleBuilder>( + std::make_unique<ComplexBuilder>( config::GAME_VIDEO_MODE.width, config::GAME_VIDEO_MODE.height, config::ROOM_SIZE), config::GAME_VIDEO_MODE, diff --git a/source/application/Drawable/Entity/IEntity.cpp b/source/application/Drawable/Entity/IEntity.cpp index ab32bca..8bb10e2 100644 --- a/source/application/Drawable/Entity/IEntity.cpp +++ b/source/application/Drawable/Entity/IEntity.cpp @@ -7,9 +7,10 @@ void IEntity::set_location(Room* ptr_room) { } Food::Food() { - m_shape = sf::CircleShape(config::GAME_FOOD_SIZE); + m_shape = sf::CircleShape(config::GAME_FOOD_SIZE/2); + m_shape.setOrigin({ config::GAME_FOOD_SIZE/2, config::GAME_FOOD_SIZE/2 }); + set_texture(&FoodTexture::instance()); m_shape.setFillColor(config::GAME_FOOD_COLOR); - m_shape.setOrigin({config::GAME_FOOD_SIZE/2, config::GAME_FOOD_SIZE/2}); } std::unique_ptr<IStaticEntity> Food::clone() const { @@ -17,7 +18,8 @@ std::unique_ptr<IStaticEntity> Food::clone() const { } void Food::prepare_for_drawing() { - m_shape.setPosition(m_ptr_room->get_position()); + m_sprite.setTexture(m_ptr_texture->get_texture()); + m_sprite.setPosition(m_ptr_room->get_position()+sf::Vector2f(-10, -10)); } std::unique_ptr<IGameEvent> Enemy::accept(IVisitor* ptr_visitor) { @@ -28,15 +30,13 @@ std::unique_ptr<IGameEvent> Food::accept(IVisitor* ptr_visitor) { return ptr_visitor->visit(this); } - void Food::draw_into(sf::RenderWindow& window) { - m_shape.setPosition(m_ptr_room->get_position()); - //из класса Room: sf::Vector2f get_position() { return m_rectangle.getPosition(); } - window.draw(m_shape); + prepare_for_drawing(); + window.draw(m_sprite); } Enemy::Enemy() { - m_shape = sf::CircleShape(config::GAME_ENEMY_SIZE); + m_shape = sf::CircleShape(config::GAME_ENEMY_SIZE/2); m_shape.setFillColor(config::GAME_ENEMY_COLOR); m_shape.setOrigin({config::GAME_ENEMY_SIZE / 2, config::GAME_ENEMY_SIZE / 2}); } @@ -49,7 +49,7 @@ void Enemy::prepare_for_drawing() { m_shape.setPosition(m_ptr_room->get_position()); } -void Enemy::draw_into(sf::RenderWindow &window) { +void Enemy::draw_into(sf::RenderWindow& window) { prepare_for_drawing(); window.draw(m_shape); } diff --git a/source/application/Drawable/Entity/IEntity.h b/source/application/Drawable/Entity/IEntity.h index 6a83d09..f0348c7 100644 --- a/source/application/Drawable/Entity/IEntity.h +++ b/source/application/Drawable/Entity/IEntity.h @@ -2,6 +2,7 @@ #include "../IDrawable.h" #include "../../Event/IGameEvent.h" +#include "MyTexture.h" class Room; class Food; @@ -30,6 +31,9 @@ public: class IStaticEntity : public IEntity, public IVisitable { public: virtual std::unique_ptr<IStaticEntity> clone() const = 0; + virtual void set_texture(MyTexture* ptr_texture) {m_ptr_texture = ptr_texture; } +protected: + MyTexture* m_ptr_texture; }; class IDynamicEntity: public IEntity, public IVisitable { @@ -52,14 +56,17 @@ private: sf::Clock m_clock; }; -class Food: public IStaticEntity { +class Food: public IStaticEntity{ public: Food(); void draw_into(sf::RenderWindow& window) override; void prepare_for_drawing() override; + void set_texture(MyTexture* ptr_texture) override { m_ptr_texture = ptr_texture; } std::unique_ptr<IStaticEntity> clone() const override; std::unique_ptr<IGameEvent> accept(IVisitor* ptr_visitor) override; ~Food() override {}; private: sf::CircleShape m_shape; + MyTexture* m_ptr_texture; + sf::Sprite m_sprite; }; \ No newline at end of file diff --git a/source/application/Drawable/Entity/MyTexture.cpp b/source/application/Drawable/Entity/MyTexture.cpp new file mode 100644 index 0000000..a7d4278 --- /dev/null +++ b/source/application/Drawable/Entity/MyTexture.cpp @@ -0,0 +1,28 @@ +#include "MyTexture.h" + +PacmanTexture::PacmanTexture() { + m_texture_up.loadFromFile(std::string(ASSETS_PATH) + "pacmanUp.png"); + m_texture_down.loadFromFile(std::string(ASSETS_PATH) + "pacmanDown.png"); + m_texture_right.loadFromFile(std::string(ASSETS_PATH) + "pacmanRight.png"); + m_texture_left.loadFromFile(std::string(ASSETS_PATH) + "pacmanLeft.png"); +} + +//в зависимости от направления - разные текстуры +sf::Texture& PacmanTexture::get_texture() { + switch (m_direction) { + case Direction::UP: + return m_texture_left; + case Direction::DOWN: + return m_texture_right; + case Direction::RIGHT: + return m_texture_up; + case Direction::LEFT: + return m_texture_down; + } +} + +FoodTexture::FoodTexture() { + if (!m_texture_food.loadFromFile(std::string(ASSETS_PATH) + "apple.png")) + throw std::runtime_error("Can't added Texture for food"); +} + diff --git a/source/application/Drawable/Entity/MyTexture.h b/source/application/Drawable/Entity/MyTexture.h new file mode 100644 index 0000000..4af54f3 --- /dev/null +++ b/source/application/Drawable/Entity/MyTexture.h @@ -0,0 +1,35 @@ +#pragma once + +#include "SFML/Graphics.hpp" + +class MyTexture { +public: + MyTexture() = default; + enum Direction { UP, DOWN, RIGHT, LEFT }; + virtual sf::Texture& get_texture() = 0; + MyTexture(const MyTexture&) = delete; + MyTexture& operator=(const MyTexture&) = delete; + void set_direction(Direction direction) { m_direction = direction; } +protected: + Direction m_direction = UP; +}; + +//texture for Pacman +class PacmanTexture : public MyTexture { +public: + static PacmanTexture& instance() { static PacmanTexture instance; return instance; } + sf::Texture& get_texture() override; +private: + PacmanTexture(); + sf::Texture m_texture_up, m_texture_down, m_texture_right, m_texture_left; +}; + +//texture for Food +class FoodTexture : public MyTexture { +public: + static FoodTexture& instance() { static FoodTexture instance; return instance; } + sf::Texture& get_texture() override { return m_texture_food; } +private: + FoodTexture(); + sf::Texture m_texture_food; +}; diff --git a/source/application/Drawable/Entity/Pacman.cpp b/source/application/Drawable/Entity/Pacman.cpp index e20ab2d..b47166f 100644 --- a/source/application/Drawable/Entity/Pacman.cpp +++ b/source/application/Drawable/Entity/Pacman.cpp @@ -2,30 +2,33 @@ #include "../../../../workdir/config.h" Pacman::Pacman() { - m_shape = sf::CircleShape(config::GAME_PACMAN_SIZE/2); + m_shape = sf::CircleShape(config::GAME_PACMAN_SIZE); m_shape.setFillColor(config::GAME_COLOR_PACMAN); - m_shape.setOrigin({config::GAME_PACMAN_SIZE/2, config::GAME_PACMAN_SIZE/2}); + set_texture(&PacmanTexture::instance()); + m_shape.setOrigin({config::GAME_PACMAN_SIZE, config::GAME_PACMAN_SIZE}); } void Pacman::move(Room::Direction direction) { m_ptr_room->get_side(direction)->enter(this); + m_ptr_texture->set_direction(static_cast<MyTexture::Direction>(direction)); } void Pacman::prepare_for_drawing() { - m_shape.setPosition(m_ptr_room->get_position()); + m_sprite.setTexture(m_ptr_texture->get_texture()); + m_sprite.setPosition(m_ptr_room->get_position()+sf::Vector2f(-20, -20)); } -std::unique_ptr<IGameEvent> Pacman::visit(Food *ptr_food) { +std::unique_ptr<IGameEvent> Pacman::visit(Food* ptr_food) { if (ptr_food->get_location() != this->get_location()) return {}; return std::make_unique<DeleteStaticEntity>(ptr_food); } -std::unique_ptr<IGameEvent> Pacman::visit(Enemy *ptr_enemy) { +std::unique_ptr<IGameEvent> Pacman::visit(Enemy* ptr_enemy) { if (ptr_enemy->get_location() != this->get_location()) return {}; return std::make_unique<LostGame>(); } -void Pacman::draw_into(sf::RenderWindow &window) { +void Pacman::draw_into(sf::RenderWindow& window) { prepare_for_drawing(); - window.draw(m_shape); -} + window.draw(m_sprite); +} \ No newline at end of file diff --git a/source/application/Drawable/Entity/Pacman.h b/source/application/Drawable/Entity/Pacman.h index 8e5f5f6..3f38479 100644 --- a/source/application/Drawable/Entity/Pacman.h +++ b/source/application/Drawable/Entity/Pacman.h @@ -2,16 +2,20 @@ #include "IEntity.h" #include "../Maze/Maze.h" +#include "MyTexture.h" class Pacman : public IEntity, public IVisitor { public: Pacman(); void move(Room::Direction direction); void prepare_for_drawing() override; + void set_texture(MyTexture* ptr_texture) { m_ptr_texture = ptr_texture; } void draw_into(sf::RenderWindow& window) override; std::unique_ptr<IGameEvent> visit(Food* ptr_entity) override; std::unique_ptr<IGameEvent> visit(Enemy* ptr_entity) override; ~Pacman() override {}; private: sf::CircleShape m_shape; -}; \ No newline at end of file + sf::Sprite m_sprite; + MyTexture* m_ptr_texture; +}; diff --git a/source/application/Drawable/Maze/Maze.h b/source/application/Drawable/Maze/Maze.h index 967923d..1b7219a 100644 --- a/source/application/Drawable/Maze/Maze.h +++ b/source/application/Drawable/Maze/Maze.h @@ -13,7 +13,6 @@ public: class Room: public IDrawable { public: enum Direction { INVALID = -1, LEFT, RIGHT, UP, DOWN }; - explicit Room(float size); float get_size() { return m_rectangle.getSize().x; } void set_position(sf::Vector2f pos) { m_rectangle.setPosition(pos); } @@ -31,7 +30,7 @@ public: class Maze: public IDrawable { public: Maze() = default; - Maze(std::vector<Room*>& rooms) : m_rooms(rooms) {}; + explicit Maze(std::vector<Room*>& rooms) : m_rooms(rooms) {}; void draw_into(sf::RenderWindow& m_window) override; private: std::vector<Room*> m_rooms; diff --git a/source/application/SelectCommand/ISelectCommand.cpp b/source/application/SelectCommand/ISelectCommand.cpp deleted file mode 100644 index 4669ecd..0000000 --- a/source/application/SelectCommand/ISelectCommand.cpp +++ /dev/null @@ -1,2 +0,0 @@ -#include "ISelectCommand.h" - diff --git a/source/application/State/GameState.cpp b/source/application/State/GameState.cpp index bab1573..db705ac 100644 --- a/source/application/State/GameState.cpp +++ b/source/application/State/GameState.cpp @@ -23,15 +23,19 @@ void GameState::event_handling() { void GameState::process_key_pressed(sf::Keyboard::Key code) { switch (code) { case sf::Keyboard::W: - m_context_manager.get_current_context().pacman.move(Room::UP); + m_context_manager.save_current_context(); //сохраняем состояние + m_context_manager.get_current_context().pacman.move(Room::UP); //выполнили действие break; case sf::Keyboard::S: + m_context_manager.save_current_context(); m_context_manager.get_current_context().pacman.move(Room::DOWN); break; case sf::Keyboard::A: + m_context_manager.save_current_context(); m_context_manager.get_current_context().pacman.move(Room::LEFT); break; case sf::Keyboard::D: + m_context_manager.save_current_context(); m_context_manager.get_current_context().pacman.move(Room::RIGHT); break; } @@ -41,25 +45,21 @@ void GameState::update() { std::vector<std::unique_ptr<IGameEvent>> game_events; if (m_context_manager.get_current_context().state != GameContext::INGAME) return; GameContext& context = m_context_manager.get_current_context(); - for (auto& entity_ptr : context.dynamic_objects) { - entity_ptr->action(); + for (auto& ptr_entity : context.dynamic_objects) { + ptr_entity->action(); IVisitor* ptr_visitor = &(context.pacman); - game_events.emplace_back(entity_ptr->accept(ptr_visitor)); + auto ptr_event = ptr_entity->accept(ptr_visitor); + if (ptr_event) game_events.emplace_back(std::move(ptr_event)); } for (auto& static_ptr : context.static_objects) { IVisitor* ptr_visitor = &(context.pacman); auto ptr_event = static_ptr->accept(ptr_visitor); - if (ptr_event) - game_events.emplace_back(std::move(ptr_event)); + if (ptr_event) game_events.emplace_back(std::move(ptr_event)); } - for (auto it = context.dynamic_objects.begin(); it != context.dynamic_objects.end(); ++it) { - if (context.pacman.get_location() == (*it)->get_location()) { - game_events.emplace_back(std::move(std::make_unique<LostGame>())); - } - } - for (int i = 0; i < game_events.size(); i++) { + + for (int i = 0; i < game_events.size(); i++) game_events[i]->handle(&m_context_manager.get_current_context()); - } + if (context.static_objects.empty()) { game_events.emplace_back(std::move(std::make_unique<WinGame>())); } @@ -80,10 +80,8 @@ void GameState::render() { } m_maze.draw_into(m_window); context.pacman.draw_into(m_window); - for (auto& obj : context.static_objects) { + for (auto& obj : context.static_objects) obj->draw_into(m_window); - } - for (auto& el : context.dynamic_objects) el->draw_into(m_window); @@ -92,7 +90,8 @@ void GameState::render() { bool GameState::do_step() { event_handling(); - update(); + if (m_context_manager.get_current_context().state == GameContext::INGAME) + update(); render(); return true; } diff --git a/source/application/State/IState.cpp b/source/application/State/IState.cpp deleted file mode 100644 index 528669c..0000000 --- a/source/application/State/IState.cpp +++ /dev/null @@ -1,2 +0,0 @@ -#include "IState.h" - diff --git a/workdir/assets/apple.png b/workdir/assets/apple.png new file mode 100644 index 0000000000000000000000000000000000000000..bc27ccc400f05db3ddff79abddf562bfd8949f70 GIT binary patch literal 1211 zcmeAS@N?(olHy`uVBq!ia0vp^A|TAc3?z4jzqJQa3dtTpz6=aiY77hwEes65fI<x~ z7#K<o7#Ln9FfdrnU|<k0n6oR;hJk_cVt`MGD^P)mfskH~mcukFr2zS$177mpvS(zJ z9e8;>xOmd}1fzNQk4h^Zl2$w=qjW-A=`@g(QQ9FXzfDrUSU@<NPbi63Ae5Ugh?~!y zljpy=%m4rX^Z14TI|k<R3z;_<S#_A2HyT;A8k^Pv-N4|r&e?aX8w7c+cX66y<Fm=t zbB(jx3P-Pvu6{c`e73lO)a-DtY_z&1s&q+K<*>BkItG!nR?Dc>E}<LU0=BzHtaDuv zVRT<c^^Tk>(5YJ`<*&%7Tv1g!W~O;pPW85&>Sb9Kpo6c-s@#-Pyb0zWlu|q{tpt<; zqGQsEC!`gRNrSut^aW7-x}3^2Srs5-i=-ToaaC3Ys26AyklZCD53~Zv1_}aQ0yGxL z0CLaBC;_E_+zYbGmt>WJ!2%2)AR8!>$|qRJFI>bgoWm~!L_kkPt#LhWrZut9B6_vU z4tM>l8XEWHRPR~XJ*cXGU~GNBR(nCB$#pgL`?9Kc<<;&1k+J2yw5)qux8HN|x+krC zZ^GnzD_7q$G{2{)ac}m#dz-f0Q_%vt;a*YMy{6WCN}Bf+)bA;(149EC_?vi+10$ND ztR%=U7)av-%xui8OpFz~x9-T2ToO=n?(gp6_e-K8CHdli{R4sTVO$+g|NVW^B3gCj zV!5#9i>E4@Dw^W0H?B2_E}6gN-+YIuzYnIRANe)O&V1*=f|4C3Oq`soY-JwnO@Y=j zCV9KNNHZl|Spwv67I;J!Gca%qfiUBxyLEqng6t)pzOL*qnb|n_dE_&X>;mdx@pN$v zk+__kaDY!j@`<R3h{((-Q)UV_>1eIWdL=b0>Xy|S4o5T5Slhow%+AWm!okL6D-_t9 zcebYPoVvAl?cBZ1%FOB!6TFX}yt#DIrd7L^UAuaAZlkoyvBwWzhKAq2aO29IOSi5) zd;9n_x5$&vpYz|pc=IZ6C2QB#t*k7cm|0ny{!~}}{*`@OK|vuxK*=KU(UOz7E1DGl z1uyekeN<qM-C|x}fsDXh-58#%i2)fA7BMSym5jV3o&*R^&1gyBY1X*mo}{&L^5a{N z($296O@1tS<Y1E!4`-)m?n%v+nYk||XYx$Cppba})VY&WC!ITeQeU8feV$KZU}2|@ zb7o=SLK$W~1_n09q)L&af7yXSq*~${QIe8al4_M)lnSI6j0}uSbq$Pl4a`CeEUXMo ztqhH{4GgRd3?@3SP(;y?o1c=IR*74~137`YKn)sj8%i>BQ;SOya|>|m+0Jd~1k@t~ x(i5DYR#Ki=l*-_klAn~S;FejGTAp8&U98|7Z1!T$rXHX=22WQ%mvv4FO#mDftU>?) literal 0 HcmV?d00001 diff --git a/workdir/assets/pacman.png b/workdir/assets/pacman.png new file mode 100644 index 0000000000000000000000000000000000000000..9dfa35d9d504f7e413ad1e5180b9821dfab11f3b GIT binary patch literal 2732 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 literal 0 HcmV?d00001 diff --git a/workdir/assets/pacmanDown.png b/workdir/assets/pacmanDown.png new file mode 100644 index 0000000000000000000000000000000000000000..18d63290bb82e97f70b629c745b29e4f8f443d5b GIT binary patch literal 2263 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 Isl}WB1pZ?yv;Y7A literal 0 HcmV?d00001 diff --git a/workdir/assets/pacmanLeft.png b/workdir/assets/pacmanLeft.png new file mode 100644 index 0000000000000000000000000000000000000000..cfad9cd3a0718cf3fe8a89621fe84d0254911c10 GIT binary patch literal 2247 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 F{{z&(I+_3g literal 0 HcmV?d00001 diff --git a/workdir/assets/pacmanRight.png b/workdir/assets/pacmanRight.png new file mode 100644 index 0000000000000000000000000000000000000000..9613050a23c47f95d5e51ed3bcf44514e85e68ad GIT binary patch literal 2217 zcmcImc~I0=9A2rkirNB#V3jcwEQ*rNZZ_-@SsB~~L0uG~fZ&x)-Yyw-lXVl8l~P-; z7LV$vt<xe_v9;EUI!GNYRVpf2FVJf79O=-hC-s<WWt@tAfo1D-tiwNjGfCci`QG>Y zen)<jWz*6p4hniRNTE;+N=r3QhtJXS)$dh!U)j0e2_OAksWU`{V!&Ye>Z2&Hh*T&7 z&vIG0Qm$nR#RyI%%?eha^g3M-txzN+dR;VA2qeS`>>O`I?|uIRig2tE&55_DEG`o$ z;8IK6AhRSrizz8&3@n;B9!c<0kiZEf8u2<EyhwSCXcsR9=khj=B3%%v(1<3<29aFL zG{hvh0TQp&VvL%MM|1|ITB{)qhB$;!sr9%@kE=D9T1$~CiXaf*K%q4^Yon%{Q+&4I z%7_+7l8eIe;^Jauu|_Gl?YP=tFyJZzCkPB8FmXOF(O!%fqk9<4KxEvUOX36`kr`>L zP$U^qsI=P!r^`>vi@q?yfZ<-+g{ze+*`*$!#qx5f)9FWxQnCkH@#%dbv6waA1@P%W z6pGvoNcI3;itaJSGXAr!BDbT<Q<lMj12`c}gu>K*Q?3F*62t=GKm72&_Iu-^Om09+ zf;&qP96gDe*299BOmboj$mkr7XN6)hRu<(u1I)Apj3}WZNK6%vY1CP2k|Ib-LylEx zD3z)kYJsJ|(h}V}u)uP*`MrT!EL0jVN;J=aG_w(fqLduRQU;)7RW>WY3_2)@(2)dY z)mn9!Mx}|@X;__(U_qBIc-|~9MREk?^WBxp3Jm1%2Z>@yJ#Ezj0wYP%im^75#PkN6 z7Gnt&96Ca;156LwR5u4d9@_CdtE`HJjD$g_i6>bdW&kQZq#)r<r=>B1wb?XQn}LA) zD8e$7O>jGDSSp;8wgcS7+fn2nH73C!xGe$;W3G`48nQz#QaKT3Z@%vn$prI!GY5xs z)g47Ma=9B(M$R)}QQtQAg6Q>5XE$we0f3}0Nq#p>6l_v4?FLD980p^B7ye)RMcVUn z^}Wme|Et~?T&95L?ErRA9F_gS<zCaB8vNf`>w5QGU+RIwW+zYmT^26<eH!qP+6}w# z<NQGf6^eibY38J?+@+^484JTQ!Wtj6^0vW)!;3P4lfvp7FHD^anAop#%ldg1ypqvg zg`J<2A2RH$a%oFmY~7I1uodt3iy7JIm|e`w8^u<%H{ETjUH2DVKF;2hP*L;vs%V=$ zHnSE)u66~5WY?C~EmF^{-{xt|*mv9N*|L0LMRQJIrSo`bE{|>w8OPro?@qhjzm=<e zbTM%>__8B(7ZZGP*(2glrtj8@fC%-fy!O?>RYMaRqn0&fx7Sx!1YA~^nJg_gs`2lp zr4Jq0kt3O^$<TXM$fRu@+NPlGJFLRI%fUx2Z65|#-IA8S(N<8uW$nk+<LWlAPk*qb z?Ob_7Y2GhiF*O6?wg$H7%qfK*pb5u3m60QIO0(>)5mT$9i-g$2LkEV(jXA#P40(X_ z)U3QT;kPP#s(wcK+I<^tE!pHP%W!aX<`7ihaw07;u;u>iyG!Q%)I2Dp|7mA)dM)U) zZ^_NL!fWnNmiAk4dS_hB>O<7*V>zvNY}djfvd_Ti#4Ks~CUgD$zO8|kr>76618_+d z3D%5i2%mZP5I^(g?<JuZn`a$Z(t41(Wsj-~T6`g7=fqP#CvjmT@`gTK5v7lqGvoaI z$paRGJLAf>d=_rjzIE7A+1C6kntmej-gSCdQ~rj%>rQRmR{PriG0#SQ^vq&BxFWhC zWp~uM4e!QWdT2UFEj(gr(XQQji|WYkC^&zp&+zPaVUKe7nmI?46Yl(RCH`t=`>M|y zW?jvl_2Z-)Wo;)dBi|lSv#M6`##Vf><7w-1<Vj!8@lBnE(xcz*Ma&(Go70X|h3&IO zHoNjVYf1-3+^^e6UyI5=d*%9e>B-##A)khppFQxNX-d#jYkp_I9{Qc4l>93j<)4YP M<aG0{33C_y4Uiff=Kufz literal 0 HcmV?d00001 diff --git a/workdir/assets/pacmanUp.png b/workdir/assets/pacmanUp.png new file mode 100644 index 0000000000000000000000000000000000000000..62ba3dcdcaed1efe5e18561316b57dd2f7b39b95 GIT binary patch literal 2237 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 Awg3PC literal 0 HcmV?d00001 -- GitLab