diff --git a/Sources/Entities/Entities.cpp b/Sources/Entities/Entities.cpp index 04dc3374fcbec99f4f20ed37dca0a400d30bbeec..c0dbbeb0e22d704925ad0d14184cb60ee3158657 100644 --- a/Sources/Entities/Entities.cpp +++ b/Sources/Entities/Entities.cpp @@ -1,6 +1,4 @@ #include "Entities.h" - -//#include "../Room/Room.h" #include "Pacman.h" //IENTITY @@ -52,52 +50,59 @@ std::unique_ptr<IDynamicEntity> Enemy::clone() const { return std::make_unique<Enemy>(*this); } +void Enemy::try_to_follow(sf::Vector2f& diff, const Room::Direction& dir, const Maze& maze) { + sf::Vector2f enemy_pos = this->get_position(); + sf::Vector2f gap; + switch (dir){ //в зависимости от направления задаем вектор перемещения + case Room::Direction::RIGHT: + gap = { config::ROOM_SIZE, 0 }; + break; + + case Room::Direction::LEFT: + gap = { -config::ROOM_SIZE, 0 }; + break; + + case Room::Direction::DOWN: + gap = { 0, config::ROOM_SIZE }; + break; + + case Room::Direction::UP: + gap = { 0, -config::ROOM_SIZE }; + break; + } + + while (1) { + if (std::abs(diff.x + diff.y) > 0) { + enemy_pos += gap; //двигаем врага + diff -= gap; //уменьшаем разницу расстояний между пакменом и врагом + if (!maze.is_room(enemy_pos)) { break; } + } + else { m_ptr_room->get_side(dir)->enter(this); break; } + } +} + void Enemy::action(const Maze& maze, const Pacman& pacman) { - auto milliseconds = static_cast<size_t>(m_stopwatch.getElapsedTime().asMilliseconds()); //получаем сколько прошло времени - if (milliseconds < 500) return;//если время меньше, чем случайное число до 10000 мс, то бездействие + auto milliseconds = static_cast<size_t>(m_stopwatch.getElapsedTime().asMilliseconds()); + if (milliseconds < 500) return; - sf::Vector2f enemy_pos = this->get_position(), pacman_pos = pacman.get_position(), diff = pacman_pos - enemy_pos; + sf::Vector2f diff = pacman.get_position() - this->get_position(), prev_pos = this->get_position(); if (pacman.is_visible() && std::pow(diff.x, 2) + std::pow(diff.y, 2) <= std::pow(config::ENEMY_VISIBILITY_DISTANCE, 2)) { if (diff.y == 0 && diff.x > 0) { - while (1) { - if ((pacman_pos - enemy_pos).x > 0) { - enemy_pos += {config::ROOM_SIZE, 0}; - if (!maze.is_room(enemy_pos)) { break; } - } - else { m_ptr_room->get_side(Room::Direction::RIGHT)->enter(this); break; } - } + try_to_follow(diff, Room::Direction::RIGHT, maze); //враг попытается дойти до пакмена в этом направлении } else if (diff.y == 0 && diff.x < 0) { - while (1) { - if ((pacman_pos - enemy_pos).x < 0) { - enemy_pos -= {config::ROOM_SIZE, 0}; - if (!maze.is_room(enemy_pos)) { break; } - } - else { m_ptr_room->get_side(Room::Direction::LEFT)->enter(this); break; } - } + try_to_follow(diff, Room::Direction::LEFT, maze); } else if (diff.x == 0 && diff.y > 0) { - while (1) { - if ((pacman_pos - enemy_pos).y > 0) { - enemy_pos += {0, config::ROOM_SIZE}; - if (!maze.is_room(enemy_pos)) { break; } - } - else { m_ptr_room->get_side(Room::Direction::DOWN)->enter(this); break; } - } + try_to_follow(diff, Room::Direction::DOWN, maze); } else if (diff.x == 0 && diff.y < 0) { - while (1) { - if ((pacman_pos - enemy_pos).y < 0) { - enemy_pos -= {0, config::ROOM_SIZE}; - if (!maze.is_room(enemy_pos)) { break; } - } - else { m_ptr_room->get_side(Room::Direction::UP)->enter(this); break; } - } + try_to_follow(diff, Room::Direction::UP, maze); } } - if (pacman_pos - diff == this->get_position()) { //если враг не сдвинулся + if (prev_pos == this->get_position()) { //если враг не сдвинулся if (milliseconds < 500 + rand() % 10000) //если время меньше, чем случайное число до 10000 мс, то бездействие return; auto direction = static_cast<Room::Direction>(rand() % 4); diff --git a/Sources/Entities/Entities.h b/Sources/Entities/Entities.h index 88ff5efe8f1a4022f3e7f83f24a52453e209a999..0561a6ee7b48b423741ed5269e22c3d698e0f976 100644 --- a/Sources/Entities/Entities.h +++ b/Sources/Entities/Entities.h @@ -3,13 +3,12 @@ #include "../IDraw_n_IPrep/IDraw_n_IPrep.h" #include "../Textures/Texture.h" #include "../Events/Events.h" +#include "../Room/Room.h" -class Room; class Enemy; class Food; class InvisPotion; class Inventory; -class Maze; class Pacman; class IEntity: public IPreparable { //мб entity отсюда надо убрать @@ -63,6 +62,7 @@ public: void draw_into(sf::RenderWindow& window) const override; void prepare_for_drawing() override; std::unique_ptr<IDynamicEntity> clone() const override; + void try_to_follow(sf::Vector2f& pacman_pos, const Room::Direction& dir, const Maze& maze); void action(const Maze& maze, const Pacman& pacman) override; std::unique_ptr<IGameEvent> accept(IVisitor* ptr_visitor) override; diff --git a/Sources/Entities/Pacman.h b/Sources/Entities/Pacman.h index 2f8b7484be3246a52066e8d2f28d9d526a4f9384..faf5e4af75bbacd970e38cbd6f2db5254f65c55e 100644 --- a/Sources/Entities/Pacman.h +++ b/Sources/Entities/Pacman.h @@ -3,6 +3,7 @@ #include "../Room/Room.h" #include "../Inventory/Inventory.h" #include "../Events/Events.h" +#include "../Entities/Entities.h" class IStaticEntity; @@ -23,6 +24,6 @@ public: private: sf::CircleShape m_circle; - int m_ticks; + int m_ticks = 0; bool m_visible = 1; }; \ No newline at end of file diff --git a/Sources/Inventory/Inventory.cpp b/Sources/Inventory/Inventory.cpp index 25f48f18787972016315507df88526b9e78a494a..f34582f6da1fb9c3455505585c3b226366bf9a68 100644 --- a/Sources/Inventory/Inventory.cpp +++ b/Sources/Inventory/Inventory.cpp @@ -4,7 +4,7 @@ Inventory::Inventory() { const float CS = config::CELL_SIZE; - //background и cells + //background auto background = sf::RectangleShape({ config::INVENTORY_WIDTH, config::INVENTORY_HEIGHT + config::INVENTORY_FONT_SIZE * 1.5f }); background.setFillColor(config::INVENTORY_COLOR); background.setPosition({ config::INVENTORY_WIDTH * 0.1f, config::INVENTORY_HEIGHT * 0.3f }); @@ -13,6 +13,7 @@ Inventory::Inventory() { m_rects.emplace_back(background); + //cells sf::Vector2f pos = background.getPosition(); float gap = (config::INVENTORY_WIDTH - CS * 3) / 4; for (size_t i = 0; i < config::NUMBER_OF_CELLS; ++i) { //создаем ячейки инвентаря @@ -46,7 +47,7 @@ Inventory::Inventory() { m_texts.emplace_back(V_text); - //текст подсказки [C] + //текст подсказки [C]->[Q] sf::Vector2f pos_cell3 = m_rects.at(3).getPosition(); sf::Text Q_text = sf::Text("[C]->[Q]", MyFont::Instance(), FS); Q_text.setPosition({ pos_cell3.x - CS / 2, pos_cell3.y - CS / 2 - 0.2f * FS }); diff --git a/Sources/Room/Maze_generator.cpp b/Sources/Room/Maze_generator.cpp index c604ad09a48b4134519d0b09e2dd23d4424b1c33..2ac0d2ded8b83069c60d427811105e9b1463e3aa 100644 --- a/Sources/Room/Maze_generator.cpp +++ b/Sources/Room/Maze_generator.cpp @@ -11,6 +11,37 @@ static void pop(std::vector<std::vector<size_t>>& coords, size_t y, size_t x) { } } +static void wall_builder(std::vector<std::vector<bool>>& field, std::vector<std::vector<size_t>>& coords, const size_t& dir, size_t& x, size_t& y) { + do { //0 - верх, 1 - право, 2 - низ, 3 - влево + switch (dir) { + case 0: + field.at(y - 1).at(x) = 1; + y -= 2; + break; + case 1: + field.at(y).at(x + 1) = 1; + x += 2; + break; + case 2: + field.at(y + 1).at(x) = 1; + y += 2; + break; + case 3: + field.at(y).at(x - 1) = 1; + x -= 2; + break; + } + + if (x <= 0 || y <= 0 || x > field.at(0).size() - 2 || y > field.size() - 2 || field.at(y).at(x) == 1) { + break; + } + else { + field.at(y).at(x) = 1; + pop(coords, y, x); + } + } while (rand() % 100 < 50); +} + static auto generate(size_t height, size_t width) { std::vector<std::vector<bool>> field(height + 2, std::vector<bool>(width + 2)); for (size_t i = 0; i < height + 2; ++i) { @@ -41,35 +72,7 @@ static auto generate(size_t height, size_t width) { size_t dir = rand() % 4; - do { //0 - верх, 1 - право, 2 - низ, 3 - влево - - switch (dir) { - case 0: - field.at(y - 1).at(x) = 1; - y -= 2; - break; - case 1: - field.at(y).at(x + 1) = 1; - x += 2; - break; - case 2: - field.at(y + 1).at(x) = 1; - y += 2; - break; - case 3: - field.at(y).at(x - 1) = 1; - x -= 2; - break; - } - - if (x <= 0 || y <= 0 || x > width || y > height || field.at(y).at(x) == 1) { - break; - } - else { - field.at(y).at(x) = 1; - pop(coords, y, x); - } - } while (rand() % 100 < 50); + wall_builder(field, coords, dir, x, y); //строим стену в этом направлении } return field; } diff --git a/Sources/Room/Room.cpp b/Sources/Room/Room.cpp index 40f9fdb259022884b7dbd6c6582bdf5f02c50fa0..7b527148e623713bc9176b2de69caf5a55aa29f4 100644 --- a/Sources/Room/Room.cpp +++ b/Sources/Room/Room.cpp @@ -1,5 +1,5 @@ #include "Room.h" - +#include "../Entities/Entities.h" //MAZE Maze::Maze(std::vector<std::unique_ptr<Room>> rooms): m_rooms(std::move(rooms)) {} //move потому что вектор с unique diff --git a/Sources/Room/Room.h b/Sources/Room/Room.h index d411b6303d7cbf27f1caf3812952fb09e57f46f7..5a411778fff8cd5aafaa907b4c6631b0ed4d7cad 100644 --- a/Sources/Room/Room.h +++ b/Sources/Room/Room.h @@ -4,10 +4,10 @@ #include <vector> #include "../IDraw_n_IPrep/IDraw_n_IPrep.h" -#include "../Entities/Entities.h" #include "../../Config.h" class Room; +class IEntity; class Maze: public IDrawable { public: