Commit 0789859a authored by Дорожкин Дмитрий Михайлович's avatar Дорожкин Дмитрий Михайлович :speech_balloon:
Browse files

added some more templates

parent fd7eeff8
No related merge requests found
Showing with 272 additions and 122 deletions
+272 -122
......@@ -13,7 +13,11 @@ add_executable(application source/main.cpp source/application.cpp
source/preparable.cpp
source/room.cpp
source/gamecontext.cpp
source/gamestate.cpp)
source/gamestate.cpp
source/builders.cpp
source/events.cpp
source/visitor.cpp
source/buttonmenu.cpp)
include(FetchContent)
set(BUILD_SHARED_LIBS OFF) # Отключаем динамическую линковку (будет статическая)
......
#include "builders.hpp"
#pragma once
#include "states.hpp"
#include "gamestate.hpp"
class IGameBuilder {
public:
virtual ~IGameBuilder() = default;
virtual void create_rooms() = 0;
virtual void set_room_sides() = 0;
virtual void create_context(float dynamic_object_ratio) = 0;
virtual void create_state(IStateManager& state_manager, sf::VideoMode mode,
std::string window_title) = 0;
virtual void set_all_to_state() = 0;
virtual std::unique_ptr<GameState> get_game() = 0;
};
class GameBuilderDirector {
public:
~GameBuilderDirector() = default;
GameBuilderDirector(std::shared_ptr<IGameBuilder> ptr_builder, sf::VideoMode mode,
std::string title, float dynamic_object_ratio);
std::unique_ptr<GameState> build();
private:
std::string m_video_title;
sf::VideoMode m_mode;
float m_dynamic_object_ratio;
std::unique_ptr<IGameBuilder> m_ptr_builder;
};
class CommonBuilder : public IGameBuilder {
public:
~CommonBuilder() override = default;
void create_context(float dynamic_object_ratio) override;
void create_state(IStateManager& state_manager,
sf::VideoMode mode, std::string window_title) override;
void set_all_to_state() override;
std::unique_ptr<GameState> get_game() override;
private:
float m_width;
float m_height;
float m_room_size;
std::vector<std::vector<std::unique_ptr<Room>>> m_rooms;
GameContext m_context;
std::unique_ptr<GameState> m_state;
};
class SimpleBuilder : public CommonBuilder {
public:
~SimpleBuilder() override = default;
void create_rooms() override;
void set_room_sides() override;
};
class ComplexBuilder : public CommonBuilder {
public:
~ComplexBuilder() override = default;
void create_rooms() override;
void set_room_sides() override;
};
\ No newline at end of file
#include "buttonmenu.hpp"
#include "config.hpp"
void Button::draw_into(sf::RenderWindow& window) const {
window.draw(m_rectangle);
window.draw(m_text);
}
void Button::set(sf::Vector2f pos, sf::Vector2f button_size, std::string text,
size_t font_size, std::unique_ptr<ISelectCommand> ptr_command) {
m_rectangle.setSize(button_size);
m_rectangle.setOrigin(button_size / 2.0f);
m_rectangle.setPosition(pos);
m_rectangle.setOutlineThickness(config::BUTTON_FRAME_THICKNESS);
m_rectangle.setOutlineColor(config::BUTTON_COLOR_FRAME);
m_rectangle.setFillColor(config::BUTTON_COLOR_FILL); //TODO:
m_text.setString(text);
m_text.setFont(MyFont::Instance());
m_text.setFillColor(config::BUTTON_COLOR_TEXT);
m_text.setCharacterSize(font_size);
auto bounds = m_text.getLocalBounds();
m_text.setOrigin(bounds.getPosition() + bounds.getSize() / 2.0f);
m_text.setPosition(pos);
m_ptr_command = std::move(ptr_command);
}
void Button::select() {
m_rectangle.setFillColor(config::BUTTON_COLOR_SELECTION);
}
void Button::unselect() {
m_rectangle.setFillColor(config::BUTTON_COLOR_FILL);
}
bool Button::is_position_in(sf::Vector2f pos) {
sf::Vector2f diff = pos - m_rectangle.getPosition();
return abs(diff.x) < m_rectangle.getSize().x / 2.0f && abs(diff.y) < m_rectangle.getSize().y / 2.0f;
}
void Button::push() {
m_ptr_command->execute();
}
Menu::Menu(IStateManager& stateManager): m_state_manager(stateManager) {
float vertical_padding = config::BUTTON_SIZE.x / 10.0f;
float first_pos = (config::SELECT_LEVEL_VIDEO_MODE.height - (m_buttons.size() - 1) * vertical_padding - m_buttons.size() * config::BUTTON_SIZE.y) / 2 + config::BUTTON_SIZE.y / 2;
float hor_pos = config::SELECT_LEVEL_VIDEO_MODE.width / 2.0f;
sf::Vector2f pos = sf::Vector2f(hor_pos, first_pos);
m_buttons[0].set(pos, config::BUTTON_SIZE, config::BUTTON_TEXT_EASY,
config::BUTTON_FONT_SIZE, std::make_unique<ExitCommand>(stateManager));
pos.y += vertical_padding + config::BUTTON_SIZE.y;
m_buttons[1].set(pos, config::BUTTON_SIZE, config::BUTTON_TEXT_MEDIUM,
config::BUTTON_FONT_SIZE, std::make_unique<ExitCommand>(stateManager));
pos.y += vertical_padding + config::BUTTON_SIZE.y;
m_buttons[2].set(pos, config::BUTTON_SIZE, config::BUTTON_TEXT_HARD,
config::BUTTON_FONT_SIZE, std::make_unique<ExitCommand>(stateManager));
pos.y += vertical_padding + config::BUTTON_SIZE.y;
m_buttons[3].set(pos, config::BUTTON_SIZE, config::BUTTON_TEXT_EXIT,
config::BUTTON_FONT_SIZE, std::make_unique<ExitCommand>(stateManager));
}
void Menu::draw_into(sf::RenderWindow& window) const {
for (auto& button: m_buttons) {
button.draw_into(window);
}
}
void Menu::process_mouse(sf::Vector2f pos, bool is_pressed) {
for (auto& button: m_buttons) {
if (button.is_position_in(pos)) {
button.select();
if (is_pressed) {
button.push();
}
} else {
button.unselect();
}
}
}
\ No newline at end of file
#pragma once
#include "drawable.hpp"
#include "commands.hpp"
class Button: IDrawable {
public:
~Button() override = default;
void draw_into(sf::RenderWindow& window) const override;
Button() = default;
void set(sf::Vector2f pos, sf::Vector2f button_size, std::string text,
size_t font_size, std::unique_ptr<ISelectCommand> ptr_command);
void select();
void unselect();
bool is_position_in(sf::Vector2f pos);
void push();
private:
sf::RectangleShape m_rectangle {};
sf::Text m_text {};
std::unique_ptr<ISelectCommand> m_ptr_command {};
};
class Menu: public IDrawable {
public:
~Menu() override = default;
Menu(IStateManager& stateManager);
void draw_into(sf::RenderWindow& window) const override;
void process_mouse(sf::Vector2f pos, bool is_pressed);
private:
std::array<Button, 4> m_buttons {};
IStateManager& m_state_manager;
};
\ No newline at end of file
......@@ -9,4 +9,3 @@ void ExitCommand::execute() {
ExitCommand::ExitCommand(IStateManager& state_manager): ChangeStateCommand(state_manager) {}
void GameCommand::execute() {}
GameCommand::GameCommand(IStateManager& state_manager): ChangeStateCommand(state_manager) {}
#pragma once
#include "builders.hpp"
#include "states.hpp"
class ISelectCommand {
......@@ -26,5 +27,8 @@ class GameCommand : public ChangeStateCommand {
public:
~GameCommand() = default;
void execute() override;
GameCommand(IStateManager& state_manager);
GameCommand(IStateManager& state_manager,
std::unique_ptr<GameBuilderDirector> ptr_director);
private:
std::unique_ptr<GameBuilderDirector> m_ptr_director;
};
\ No newline at end of file
......@@ -12,83 +12,3 @@ MyFont::MyFont() {
throw std::runtime_error("Failed to load font");
}
void Button::draw_into(sf::RenderWindow& window) const {
window.draw(m_rectangle);
window.draw(m_text);
}
void Button::set(sf::Vector2f pos, sf::Vector2f button_size, std::string text,
size_t font_size, std::unique_ptr<ISelectCommand> ptr_command) {
m_rectangle.setSize(button_size);
m_rectangle.setOrigin(button_size / 2.0f);
m_rectangle.setPosition(pos);
m_rectangle.setOutlineThickness(config::BUTTON_FRAME_THICKNESS);
m_rectangle.setOutlineColor(config::BUTTON_COLOR_FRAME);
m_rectangle.setFillColor(config::BUTTON_COLOR_FILL); //TODO:
m_text.setString(text);
m_text.setFont(MyFont::Instance());
m_text.setFillColor(config::BUTTON_COLOR_TEXT);
m_text.setCharacterSize(font_size);
auto bounds = m_text.getLocalBounds();
m_text.setOrigin(bounds.getPosition() + bounds.getSize() / 2.0f);
m_text.setPosition(pos);
m_ptr_command = std::move(ptr_command);
}
void Button::select() {
m_rectangle.setFillColor(config::BUTTON_COLOR_SELECTION);
}
void Button::unselect() {
m_rectangle.setFillColor(config::BUTTON_COLOR_FILL);
}
bool Button::is_position_in(sf::Vector2f pos) {
sf::Vector2f diff = pos - m_rectangle.getPosition();
return abs(diff.x) < m_rectangle.getSize().x / 2.0f && abs(diff.y) < m_rectangle.getSize().y / 2.0f;
}
void Button::push() {
m_ptr_command->execute();
}
Menu::Menu(IStateManager& stateManager): m_state_manager(stateManager) {
float vertical_padding = config::BUTTON_SIZE.x / 10.0f;
float first_pos = (config::SELECT_LEVEL_VIDEO_MODE.height - (m_buttons.size() - 1) * vertical_padding - m_buttons.size() * config::BUTTON_SIZE.y) / 2 + config::BUTTON_SIZE.y / 2;
float hor_pos = config::SELECT_LEVEL_VIDEO_MODE.width / 2.0f;
sf::Vector2f pos = sf::Vector2f(hor_pos, first_pos);
m_buttons[0].set(pos, config::BUTTON_SIZE, config::BUTTON_TEXT_EASY,
config::BUTTON_FONT_SIZE, std::make_unique<ExitCommand>(stateManager));
pos.y += vertical_padding + config::BUTTON_SIZE.y;
m_buttons[1].set(pos, config::BUTTON_SIZE, config::BUTTON_TEXT_MEDIUM,
config::BUTTON_FONT_SIZE, std::make_unique<ExitCommand>(stateManager));
pos.y += vertical_padding + config::BUTTON_SIZE.y;
m_buttons[2].set(pos, config::BUTTON_SIZE, config::BUTTON_TEXT_HARD,
config::BUTTON_FONT_SIZE, std::make_unique<ExitCommand>(stateManager));
pos.y += vertical_padding + config::BUTTON_SIZE.y;
m_buttons[3].set(pos, config::BUTTON_SIZE, config::BUTTON_TEXT_EXIT,
config::BUTTON_FONT_SIZE, std::make_unique<ExitCommand>(stateManager));
}
void Menu::draw_into(sf::RenderWindow& window) const {
for (auto& button: m_buttons) {
button.draw_into(window);
}
}
void Menu::process_mouse(sf::Vector2f pos, bool is_pressed) {
for (auto& button: m_buttons) {
if (button.is_position_in(pos)) {
button.select();
if (is_pressed) {
button.push();
}
} else {
button.unselect();
}
}
}
#pragma once
#include <SFML/Graphics.hpp>
#include <array>
#include "commands.hpp"
class MyFont {
public:
......@@ -14,32 +14,4 @@ private:
struct IDrawable {
virtual void draw_into(sf::RenderWindow& window) const = 0;
virtual ~IDrawable() = default;
};
class Button: IDrawable {
public:
~Button() override = default;
void draw_into(sf::RenderWindow& window) const override;
Button() = default;
void set(sf::Vector2f pos, sf::Vector2f button_size, std::string text,
size_t font_size, std::unique_ptr<ISelectCommand> ptr_command);
void select();
void unselect();
bool is_position_in(sf::Vector2f pos);
void push();
private:
sf::RectangleShape m_rectangle {};
sf::Text m_text {};
std::unique_ptr<ISelectCommand> m_ptr_command {};
};
class Menu: public IDrawable {
public:
~Menu() = default;
Menu(IStateManager& stateManager);
void draw_into(sf::RenderWindow& window) const override;
void process_mouse(sf::Vector2f pos, bool is_pressed);
private:
std::array<Button, 4> m_buttons {};
IStateManager& m_state_manager;
};
\ No newline at end of file
#pragma once
#include "preparable.hpp"
#include "room.hpp"
#include "visitor.hpp"
class IEntity: public IPreparable {
public:
......@@ -11,37 +12,44 @@ protected:
std::shared_ptr<Room> m_ptr_room;
};
class Pacman: public IEntity {
class Pacman: public IEntity, public IVisitor {
public:
~Pacman() override = default;
void prepare_for_drawing() override;
void draw_into(sf::RenderWindow& window) const override;
void move(Room::Direction direction);
std::unique_ptr<IGameEvent> visit(std::unique_ptr<Food> ptr_food) override;
std::unique_ptr<IGameEvent> visit(std::unique_ptr<Enemy> ptr_enemy) override;
};
class IStaticEntity: public IEntity {
class IStaticEntity: public IEntity, public IVisitable {
public:
~IStaticEntity() override = default;
virtual std::unique_ptr<IStaticEntity> clone() = 0;
};
class IDynamicEntity: public IEntity {
class IDynamicEntity: public IEntity, public IVisitable {
public:
~IDynamicEntity() override = default;
virtual std::unique_ptr<IDynamicEntity> clone() = 0;
virtual void action() = 0;
};
class Food: public IStaticEntity {
public:
~Food() override = default;
void prepare_for_drawing() override;
void draw_into(sf::RenderWindow& window) const override;
std::unique_ptr<IStaticEntity> clone() override;
std::unique_ptr<IGameEvent> accept(std::unique_ptr<IVisitor> ptr_visitor) override;
};
class Enemy: public IDynamicEntity {
public:
~Enemy() override = default;
void prepare_for_drawing() override;
void draw_into(sf::RenderWindow& window) const override;
std::unique_ptr<IDynamicEntity> clone() override;
void action() override;
std::unique_ptr<IGameEvent> accept(std::unique_ptr<IVisitor> ptr_visitor) override;
};
\ No newline at end of file
#include "events.hpp"
#pragma once
#include "gamecontext.hpp"
class IGameEvent {
public:
virtual ~IGameEvent() = default;
virtual void handle(std::unique_ptr<GameContext> context) = 0;
};
class DeleteStaticEntity: public IGameEvent {
public:
~DeleteStaticEntity() override = default;
void handle(std::unique_ptr<GameContext> context) override;
DeleteStaticEntity(std::shared_ptr<IStaticEntity> ptr_entity);
private:
std::shared_ptr<IStaticEntity> ptr_entity;
};
class LostGame: public IGameEvent {
public:
~LostGame() override = default;
void handle(std::unique_ptr<GameContext> context) override;
};
\ No newline at end of file
#pragma once
#include "entities.hpp"
#include <stack>
class GameContext {
public:
......@@ -9,4 +10,15 @@ public:
std::vector<std::unique_ptr<IStaticEntity>> static_objects;
std::vector<std::unique_ptr<IDynamicEntity>> dynamic_objects;
enum State { INGAME, WIN, LOST } state = INGAME;
};
class ContextManager {
public:
void reset(GameContext&& context);
GameContext& get_current_context();
void save_current_context();
void restore_previous_context();
private:
GameContext m_initial_context;
std::stack<GameContext> m_context_stack;
};
\ No newline at end of file
#pragma once
#include "gamecontext.hpp"
#include "maze.hpp"
#include "states.hpp"
class GameState : public IState, public IWindowKeeper {
public:
~GameState() override = default;
GameState(IStateManager& state_manager,
sf::VideoMode video_mode, std::string window_title);
bool do_step() override;
void set_maze(Maze&& maze);
void set_context(GameContext&& context);
private:
void event_handling() override;
void update() override;
void render() override;
Maze m_maze;
ContextManager m_context_manager;
};
#pragma once
#include "states.hpp"
#include "drawable.hpp"
// #include "drawable.hpp"
#include "buttonmenu.hpp"
class SelectState: public IState, public IWindowKeeper {
public:
......
......@@ -18,12 +18,6 @@ protected:
IStateManager& m_state_manager;
};
class GameState : public IState, public IWindowKeeper {
public:
GameState(IStateManager& state_manager,
sf::VideoMode video_mode, std::string window_title);
};
class ExitState: public IState {
public:
~ExitState() override = default;
......
#include "visitor.hpp"
#pragma once
#include <memory>
class IGameEvent;
class Food;
class Enemy;
class IVisitor {
public:
virtual ~IVisitor() = default;
virtual std::unique_ptr<IGameEvent> visit(std::unique_ptr<Food> ptr_food) = 0;
virtual std::unique_ptr<IGameEvent> visit(std::unique_ptr<Enemy> ptr_enemy) = 0;
};
class IVisitable {
public:
virtual ~IVisitable() = default;
virtual std::unique_ptr<IGameEvent> accept(std::unique_ptr<IVisitor> ptr_visitor) = 0;
};
\ No newline at end of file
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment