diff --git a/.github/workflows/build_and_run_tests.yml b/.github/workflows/build_and_run_tests.yml index 5c2592d..1ca2c07 100644 --- a/.github/workflows/build_and_run_tests.yml +++ b/.github/workflows/build_and_run_tests.yml @@ -4,9 +4,9 @@ name: CI on: push: - branches: [ main ] + branches: [ main, release_branch ] pull_request: - branches: [ main ] + branches: [ main, release_branch ] jobs: diff --git a/.gitmodules b/.gitmodules index c319e98..952393c 100644 --- a/.gitmodules +++ b/.gitmodules @@ -19,3 +19,6 @@ [submodule "deps/libpqxx"] path = deps/libpqxx url = https://github.com/jtv/libpqxx +[submodule "deps/cpp-httplib"] + path = deps/cpp-httplib + url = https://github.com/yhirose/cpp-httplib diff --git a/CMakeLists.txt b/CMakeLists.txt index 928f804..b76a67f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -86,6 +86,13 @@ add_subdirectory(${DIRECTORY_PQXX}) message(STATUS "PostgreSQL include: ${INCLUDE_PQXX}") message(STATUS "PostgreSQL library: ${LIBRARY_PQXX}") +# HTTP library +set(DIRECTORY_HTTP ${PROJECT_SOURCE_DIR}/deps/cpp-httplib) +set(INCLUDE_HTTP ${DIRECTORY_HTTP}) + +add_subdirectory(${DIRECTORY_HTTP}) +message(STATUS "HTTP include: ${INCLUDE_HTTP}") + # Core library set(DIRECTORY_CORE ${PROJECT_SOURCE_DIR}/core) set(INCLUDE_CORE ${DIRECTORY_CORE}) @@ -100,11 +107,21 @@ set(DIRECTORY_GAME ${PROJECT_SOURCE_DIR}/game) set(EXECUTABLE_GAME example) set(EXECUTABLE_GAME_RUNNER game_runner_example) set(EXECUTABLE_GAME_DATABASE game_database_example) +set(EXECUTABLE_LOADER_FROM_SERVER game_loader_from_server_example) add_subdirectory(${DIRECTORY_GAME}) message(STATUS "Game executable: ${EXECUTABLE_GAME}") message(STATUS "Game-runner executable ${EXECUTABLE_GAME_RUNNER}") +# Network binaries +set(DIRECTORY_NETWORK ${PROJECT_SOURCE_DIR}/network) +set(EXECUTABLE_SIMPLE_SERVER simple-server) +set(EXECUTABLE_SIMPLE_CLIENT simple-client) + +add_subdirectory(${DIRECTORY_NETWORK}) +message(STATUS "Server executable: ${EXECUTABLE_SERVER}") +message(STATUS "Client executable ${EXECUTABLE_GAME_CLIENT}") + # Tests set(DIRECTORY_TEST ${PROJECT_SOURCE_DIR}/test) set(EXECUTABLE_TEST test) diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt index a778899..88f510e 100644 --- a/core/CMakeLists.txt +++ b/core/CMakeLists.txt @@ -78,6 +78,7 @@ set( runner/GameRunner.hpp runner/GameRunner.cpp loader/LevelLoader.hpp loader/LevelLoaderFromFile.cpp loader/LevelLoaderFromFile.hpp + loader/LevelLoaderFromServer.hpp loader/LevelLoaderFromServer.cpp visual/image/Image.hpp visual/image/static/RenderableStatic.cpp visual/image/static/RenderableStatic.hpp @@ -103,7 +104,7 @@ set( event/management/condition/KeyDownCondition.hpp event/management/condition/KeyDownCondition.cpp event/management/condition/TimerCondition.hpp event/management/condition/TimerCondition.cpp event/management/condition/CollisionCondition.hpp event/management/condition/CollisionCondition.cpp - event/WorldUpdate.hpp event/WorldUpdate.cpp) + event/WorldUpdate.hpp event/WorldUpdate.cpp ../game/mobs/hero/Hero.hpp ../game/mobs/hero/Hero.cpp event/management/condition/KeyReleasedCondition.hpp event/management/condition/KeyReleasedCondition.cpp event/management/controller/JumpImpulse.hpp event/management/controller/JumpImpulse.cpp event/management/condition/LastStateCondition.hpp event/management/condition/LastStateCondition.cpp event/management/controller/Movement.hpp event/management/controller/Movement.cpp event/management/controller/StartJump.hpp event/management/controller/StartJump.cpp event/management/controller/FlyUp.hpp event/management/controller/FlyUp.cpp event/management/controller/Fall.hpp event/management/controller/Fall.cpp event/management/controller/GroundMovement.hpp event/management/controller/GroundMovement.cpp event/management/condition/EndAnimationCondition.hpp event/management/condition/EndAnimationCondition.cpp event/management/condition/FallCondition.hpp event/management/condition/FallCondition.cpp event/physics/SensorCollision.hpp event/physics/SensorCollision.cpp event/management/condition/SensorCondition.hpp event/management/condition/SensorCondition.cpp event/management/controller/Attack.cpp event/management/controller/Attack.hpp event/physics/SensorCollisionEnd.hpp event/physics/SensorCollisionEnd.cpp event/management/condition/SensorEndCondition.hpp event/management/condition/SensorEndCondition.cpp event/management/controller/statemachine/HeroStateMachine.hpp event/management/controller/statemachine/HeroStateMachine.cpp event/management/controller/statemachine/EnemyStateMachine.hpp event/management/controller/statemachine/EnemyStateMachine.cpp event/management/controller/EnemyAttack.hpp event/management/controller/EnemyAttack.cpp event/management/controller/Die.hpp event/management/controller/Die.cpp event/management/controller/Destroy.hpp event/management/controller/Destroy.cpp world/filter/RadiusFilter.hpp event/management/controller/DealDamage.hpp event/management/controller/DealDamage.cpp event/physics/TakeDamage.hpp event/physics/TakeDamage.cpp event/management/condition/TakeDamageCondition.hpp event/management/condition/TakeDamageCondition.cpp event/management/controller/Hurt.hpp event/management/controller/Hurt.cpp event/management/condition/Counter.hpp event/management/condition/Counter.cpp event/management/condition/EnemyAttackCondition.hpp event/management/condition/EnemyAttackCondition.cpp event/physics/Death.hpp event/physics/Death.cpp event/management/condition/FallDownCondition.hpp event/management/condition/FallDownCondition.cpp) add_library( ${LIBRARY_CORE} STATIC diff --git a/core/common/FVec2D.cpp b/core/common/FVec2D.cpp index db3689d..46925cb 100644 --- a/core/common/FVec2D.cpp +++ b/core/common/FVec2D.cpp @@ -51,4 +51,6 @@ namespace mad::core { Vec2d operator*(float k, Vec2d v) { return v *= k; } + + } diff --git a/core/common/FVec2D.hpp b/core/common/FVec2D.hpp index 0a3ee2b..0418226 100644 --- a/core/common/FVec2D.hpp +++ b/core/common/FVec2D.hpp @@ -14,7 +14,6 @@ namespace mad::core { operator sf::Vector2() const; - [[nodiscard]] float get_x() const noexcept; [[nodiscard]] float get_y() const noexcept; diff --git a/core/database/database/Database.cpp b/core/database/database/Database.cpp index 98eb45c..ad52ef7 100644 --- a/core/database/database/Database.cpp +++ b/core/database/database/Database.cpp @@ -25,6 +25,11 @@ namespace mad::core { "levels_completed SMALLINT NOT NULL);"; w.exec(m_query); + m_query = "CREATE TABLE IF NOT EXISTS levels(" + "id SERIAL PRIMARY KEY," + "name TEXT NOT NULL UNIQUE);"; + w.exec(m_query); + w.commit(); SPDLOG_DEBUG("Tables created successfully"); @@ -33,6 +38,10 @@ namespace mad::core { } } + Database::~Database() { + drop_levels(); + } + bool Database::is_user_exists(const std::string &username) { pqxx::work W(m_connector); m_query = "SELECT * FROM users WHERE name = '" + W.esc(username) + "';"; @@ -40,10 +49,17 @@ namespace mad::core { return !rows_found.empty(); } + bool Database::is_level_exists(const std::string &levelname) { + pqxx::work W(m_connector); + m_query = "SELECT * FROM levels WHERE name = '" + W.esc(levelname) + "';"; + pqxx::result rows_found = W.exec(m_query); + return !rows_found.empty(); + } + void Database::registry_user(const std::string &username) { pqxx::work W(m_connector); - m_query = "SELECT id FROM users"; + m_query = "SELECT id FROM users;"; pqxx::result total_rows = W.exec(m_query); std::size_t id = total_rows.size(); @@ -56,6 +72,15 @@ namespace mad::core { W.commit(); } + void Database::append_level(const std::string &levelname) { + pqxx::work W(m_connector); + + m_query = "INSERT INTO levels(name) VALUES('" + levelname + "');"; + W.exec(m_query); + + W.commit(); + } + std::size_t Database::get_id(const std::string &username) { pqxx::work W(m_connector); m_query = "SELECT * FROM users WHERE name = '" + W.esc(username) + "';"; @@ -99,4 +124,25 @@ namespace mad::core { void Database::reset_progress(const std::string &username) { reset_progress(get_id(username)); } + + std::string Database::get_levelname(std::size_t id) { + pqxx::work W(m_connector); + m_query = "SELECT * FROM levels WHERE id = " + std::to_string(id) + ";"; + auto found_row = W.exec1(m_query); + return found_row["name"].as(); + } + + std::size_t Database::get_levels_total() { + pqxx::work W(m_connector); + m_query = "SELECT id FROM levels;"; + auto total_rows = W.exec(m_query); + return total_rows.size(); + } + + void Database::drop_levels() { + pqxx::work W(m_connector); + m_query = "DROP TABLE levels;"; + W.exec(m_query); + W.commit(); + } } diff --git a/core/database/database/Database.hpp b/core/database/database/Database.hpp index 5db0168..d72e45d 100644 --- a/core/database/database/Database.hpp +++ b/core/database/database/Database.hpp @@ -3,6 +3,7 @@ #include #include +#include namespace mad::core { @@ -13,19 +14,31 @@ namespace mad::core { bool is_user_exists(const std::string &username); - void registry_user(const std::string &username); + bool is_level_exists(const std::string &levelname); std::size_t get_id(const std::string &username); std::size_t get_progress(std::size_t id); std::size_t get_progress(const std::string &username); + std::string get_levelname(std::size_t id); + + std::size_t get_levels_total(); + + void registry_user(const std::string &username); + + void append_level(const std::string &levelname); + void increment_progress(std::size_t id); void increment_progress(const std::string &username); void reset_progress(std::size_t id); void reset_progress(const std::string &username); + void drop_levels(); + + ~Database(); + private: pqxx::connection m_connector; std::string m_query; diff --git a/core/event/Event.hpp b/core/event/Event.hpp index c6d231a..10fdf9f 100644 --- a/core/event/Event.hpp +++ b/core/event/Event.hpp @@ -17,7 +17,11 @@ namespace mad::core { LevelPause, Runner, WorldUpdate, - EndOfRenderAction + EndOfRenderAction, + SensorCollision, + SensorCollisionEnd, + TakeDamage, + Death, }; explicit Event(Type new_type); diff --git a/core/event/management/condition/Condition.hpp b/core/event/management/condition/Condition.hpp index 8a5fa05..dd3904b 100644 --- a/core/event/management/condition/Condition.hpp +++ b/core/event/management/condition/Condition.hpp @@ -18,6 +18,8 @@ namespace mad::core { virtual void on_start() = 0; virtual ~Condition() = default; + + bool triggered; }; } diff --git a/core/event/management/condition/Counter.cpp b/core/event/management/condition/Counter.cpp new file mode 100644 index 0000000..0b8c5a2 --- /dev/null +++ b/core/event/management/condition/Counter.cpp @@ -0,0 +1,11 @@ +#include "Counter.hpp" +mad::core::Counter::Counter(int *c, int mx) : c(c), mx(mx){ +} +bool mad::core::Counter::is_triggered_by(const mad::core::Event &event) { + return *c >= mx; +} +std::unordered_set mad::core::Counter::triggers() { + return {Event::Type::WorldUpdate}; +} +void mad::core::Counter::on_start() { +} diff --git a/core/event/management/condition/Counter.hpp b/core/event/management/condition/Counter.hpp new file mode 100644 index 0000000..2a6c5ae --- /dev/null +++ b/core/event/management/condition/Counter.hpp @@ -0,0 +1,20 @@ +#ifndef MAD_COUNTER_HPP +#define MAD_COUNTER_HPP + +#include "Condition.hpp" +namespace mad::core { + struct Counter : Condition { + public: + Counter(int *c, int mx); + bool is_triggered_by(const mad::core::Event &event) override; + std::unordered_set triggers() override; + void on_start() override; + + private: + int *c; + int mx; + }; +}// namespace mad::core + + +#endif//MAD_COUNTER_HPP diff --git a/core/event/management/condition/EndAnimationCondition.cpp b/core/event/management/condition/EndAnimationCondition.cpp new file mode 100644 index 0000000..a7f09eb --- /dev/null +++ b/core/event/management/condition/EndAnimationCondition.cpp @@ -0,0 +1,21 @@ +#include "EndAnimationCondition.hpp" +#include "common/Cast.hpp" +#include "spdlog/spdlog.h" +#include +mad::core::EndAnimationCondition::EndAnimationCondition(Entity::Id m_entity_id, ImageStorage::TypeAction m_type_action, int *stage) : m_entity_id(m_entity_id), m_type_action(m_type_action), stage(stage){ +} +bool mad::core::EndAnimationCondition::is_triggered_by(const mad::core::Event &event) { + auto e = const_cast_to(event); + if(m_entity_id == e.get_entity_id() && m_type_action == e.get_type_action()){ + (*stage)++; + //SPDLOG_DEBUG("current attack_stage {}", *stage); + } + //SPDLOG_DEBUG("current attack_stage {}", *stage); + return m_entity_id == e.get_entity_id() && m_type_action == e.get_type_action(); +} +std::unordered_set mad::core::EndAnimationCondition::triggers() { + return {mad::core::Event::Type::EndOfRenderAction}; +} +void mad::core::EndAnimationCondition::on_start() { + +} diff --git a/core/event/management/condition/EndAnimationCondition.hpp b/core/event/management/condition/EndAnimationCondition.hpp new file mode 100644 index 0000000..0b9514c --- /dev/null +++ b/core/event/management/condition/EndAnimationCondition.hpp @@ -0,0 +1,22 @@ +#ifndef MAD_ENDANIMATIONCONDITION_HPP +#define MAD_ENDANIMATIONCONDITION_HPP + +#include "Condition.hpp" +#include "visual/image/storage/ImageStorage.hpp" +#include "world/entity/Entity.hpp" +namespace mad::core { + struct EndAnimationCondition : Condition { + public: + explicit EndAnimationCondition(Entity::Id m_entity_id, ImageStorage::TypeAction m_type_action, int *stage = new int(0)); + bool is_triggered_by(const mad::core::Event &event) override; + std::unordered_set triggers() override; + void on_start() override; + + private: + Entity::Id m_entity_id; + ImageStorage::TypeAction m_type_action; + int* stage; + }; +}// namespace mad::core + +#endif//MAD_ENDANIMATIONCONDITION_HPP diff --git a/core/event/management/condition/EnemyAttackCondition.cpp b/core/event/management/condition/EnemyAttackCondition.cpp new file mode 100644 index 0000000..6e05449 --- /dev/null +++ b/core/event/management/condition/EnemyAttackCondition.cpp @@ -0,0 +1,20 @@ +#include "EnemyAttackCondition.hpp" +#include "world/filter/RadiusFilter.hpp" +mad::core::EnemyAttackCondition::EnemyAttackCondition(std::shared_ptr world, Entity::Id hero_id, Entity::Id enemy_id) : world(world), hero_id(hero_id), enemy_id(enemy_id) { + hero_entity = cast_to_or_null(world->get_storage().get_entity(hero_id)); + enemy_entity = cast_to_or_null(world->get_storage().get_entity(enemy_id)); + +} +std::unordered_set mad::core::EnemyAttackCondition::triggers() { + return {Event::Type::WorldUpdate}; +} +bool mad::core::EnemyAttackCondition::is_triggered_by(const mad::core::Event &event) { + for(auto id : world->get_storage().extract(RadiusFilter(hero_entity->get_position(), 6.0f))){ + if(id == enemy_id){ + return true; + } + } + return false; +} +void mad::core::EnemyAttackCondition::on_start() { +} diff --git a/core/event/management/condition/EnemyAttackCondition.hpp b/core/event/management/condition/EnemyAttackCondition.hpp new file mode 100644 index 0000000..131a4ba --- /dev/null +++ b/core/event/management/condition/EnemyAttackCondition.hpp @@ -0,0 +1,27 @@ +#ifndef MAD_ENEMYATTACKCONDITION_HPP +#define MAD_ENEMYATTACKCONDITION_HPP + +#include "Condition.hpp" +#include "world/LocalWorld.hpp" +#include "world/entity/Entity.hpp" +#include +namespace mad::core { + struct EnemyAttackCondition : Condition { + public: + EnemyAttackCondition(std::shared_ptr world, Entity::Id hero_id, Entity::Id enemy_id); + bool is_triggered_by(const mad::core::Event &event) override; + std::unordered_set triggers() override; + void on_start() override; + + private: + Entity::Id hero_id; + Entity::Id enemy_id; + PhysicalEntity* hero_entity; + PhysicalEntity* enemy_entity; + std::shared_ptr world; + + }; +}// namespace mad::core + + +#endif//MAD_ENEMYATTACKCONDITION_HPP diff --git a/core/event/management/condition/FallCondition.cpp b/core/event/management/condition/FallCondition.cpp new file mode 100644 index 0000000..ce13ed6 --- /dev/null +++ b/core/event/management/condition/FallCondition.cpp @@ -0,0 +1,15 @@ +#include "FallCondition.hpp" + + + +bool mad::core::FallCondition::is_triggered_by(const mad::core::Event &event) { + return m_entity->get_linear_velocity().get_y() >= vel; +} +std::unordered_set mad::core::FallCondition::triggers() { + return {mad::core::Event::Type::WorldUpdate}; +} +void mad::core::FallCondition::on_start() { +} +mad::core::FallCondition::FallCondition(std::shared_ptr world, mad::core::Entity::Id entity_id, float vel) : m_world(world), m_entity_id(entity_id), vel(vel) { + m_entity = cast_to_or_null(m_world->get_storage().get_entity(m_entity_id)); +} diff --git a/core/event/management/condition/FallCondition.hpp b/core/event/management/condition/FallCondition.hpp new file mode 100644 index 0000000..2c54d13 --- /dev/null +++ b/core/event/management/condition/FallCondition.hpp @@ -0,0 +1,25 @@ +#ifndef MAD_FALLCONDITION_HPP +#define MAD_FALLCONDITION_HPP + +#include "Condition.hpp" +#include "visual/image/storage/ImageStorage.hpp" +#include "world/LocalWorld.hpp" +#include "world/entity/Entity.hpp" +#include "world/entity/PhysicalEntity.hpp" +namespace mad::core { + struct FallCondition : Condition { + public: + explicit FallCondition(std::shared_ptr world, Entity::Id entity_id, float vel); + bool is_triggered_by(const mad::core::Event &event) override; + std::unordered_set triggers() override; + void on_start() override; + + private: + std::shared_ptr m_world; + Entity::Id m_entity_id; + PhysicalEntity *m_entity; + float vel; + }; +}// namespace mad::core + +#endif//MAD_FALLCONDITION_HPP diff --git a/core/event/management/condition/FallDownCondition.cpp b/core/event/management/condition/FallDownCondition.cpp new file mode 100644 index 0000000..6ed3870 --- /dev/null +++ b/core/event/management/condition/FallDownCondition.cpp @@ -0,0 +1,15 @@ +#include "FallDownCondition.hpp" +mad::core::FallDownCondition::FallDownCondition(std::shared_ptr world, Entity::Id m_entity_id) : m_entity_id(m_entity_id){ + enemy_entity = cast_to_or_null(world->get_storage().get_entity(m_entity_id)); +} +std::unordered_set mad::core::FallDownCondition::triggers() { + return {Event::Type::WorldUpdate}; +} +bool mad::core::FallDownCondition::is_triggered_by(const mad::core::Event &event) { + if(enemy_entity->get_position().get_y() < 450) cnt = 0; + if(enemy_entity->get_position().get_y() > 450) cnt++; + if(enemy_entity->get_position().get_y() > 450 && cnt >= 10000) return true; + return false; +} +void mad::core::FallDownCondition::on_start() { +} diff --git a/core/event/management/condition/FallDownCondition.hpp b/core/event/management/condition/FallDownCondition.hpp new file mode 100644 index 0000000..a74333b --- /dev/null +++ b/core/event/management/condition/FallDownCondition.hpp @@ -0,0 +1,23 @@ +#ifndef MAD_FALLDOWNCONDITION_HPP +#define MAD_FALLDOWNCONDITION_HPP +#include "Condition.hpp" +#include "world/LocalWorld.hpp" +#include "world/entity/Entity.hpp" +#include "world/entity/PhysicalEntity.hpp" +#include +namespace mad::core { + struct FallDownCondition : Condition { + public: + explicit FallDownCondition(std::shared_ptr world, Entity::Id m_entity_id); + bool is_triggered_by(const mad::core::Event &event) override; + std::unordered_set triggers() override; + void on_start() override; + + private: + Entity::Id m_entity_id; + PhysicalEntity* enemy_entity; + int cnt = 0; + + }; +}// namespace mad::core +#endif//MAD_FALLDOWNCONDITION_HPP diff --git a/core/event/management/condition/KeyReleasedCondition.cpp b/core/event/management/condition/KeyReleasedCondition.cpp new file mode 100644 index 0000000..fd9df64 --- /dev/null +++ b/core/event/management/condition/KeyReleasedCondition.cpp @@ -0,0 +1,15 @@ +#include "KeyReleasedCondition.hpp" +#include +#include +std::unordered_set mad::core::KeyReleasedCondition::triggers() { + return {mad::core::Event::Type::KeyReleased}; +} +bool mad::core::KeyReleasedCondition::is_triggered_by(const mad::core::Event &event) { + const auto &keystroke = const_cast_to(event); + return keystroke.key_id == m_key_id; +} + +mad::core::KeyReleasedCondition::KeyReleasedCondition(const int m_key_id) : m_key_id(m_key_id){ +} +void mad::core::KeyReleasedCondition::on_start() { +} diff --git a/core/event/management/condition/KeyReleasedCondition.hpp b/core/event/management/condition/KeyReleasedCondition.hpp new file mode 100644 index 0000000..ec846c9 --- /dev/null +++ b/core/event/management/condition/KeyReleasedCondition.hpp @@ -0,0 +1,18 @@ +#ifndef MAD_KEYRELEASEDCONDITION_HPP +#define MAD_KEYRELEASEDCONDITION_HPP + +#include "Condition.hpp" +namespace mad::core { + struct KeyReleasedCondition : Condition { + public: + explicit KeyReleasedCondition(int m_key_id); + bool is_triggered_by(const mad::core::Event &event) override; + std::unordered_set triggers() override; + void on_start() override; + + private: + const int m_key_id; + }; +}// namespace mad::core + +#endif//MAD_KEYRELEASEDCONDITION_HPP diff --git a/core/event/management/condition/LastStateCondition.cpp b/core/event/management/condition/LastStateCondition.cpp new file mode 100644 index 0000000..a2fb453 --- /dev/null +++ b/core/event/management/condition/LastStateCondition.cpp @@ -0,0 +1,13 @@ +#include "LastStateCondition.hpp" + +bool mad::core::LastStateCondition::is_triggered_by(const mad::core::Event &event) { + return m_to_state_id == m_machine->get_previous_state_id(); +} +std::unordered_set mad::core::LastStateCondition::triggers() { + return {mad::core::Event::Type::KeyPressed, mad::core::Event::Type::Collision, mad::core::Event::Type::KeyHeld, mad::core::Event::Type::KeyReleased, mad::core::Event::Type::LevelPause, mad::core::Event::Type::Menu, mad::core::Event::Type::Movement, mad::core::Event::Type::Runner, mad::core::Event::Type::Visual, mad::core::Event::Type::WindowClose}; +} +void mad::core::LastStateCondition::on_start() { +} +mad::core::LastStateCondition::LastStateCondition(std::shared_ptr m_machine, mad::core::StateMachine::StateId m_to_state_id) : m_machine(m_machine), m_to_state_id(m_to_state_id){ + +} diff --git a/core/event/management/condition/LastStateCondition.hpp b/core/event/management/condition/LastStateCondition.hpp new file mode 100644 index 0000000..89ec58e --- /dev/null +++ b/core/event/management/condition/LastStateCondition.hpp @@ -0,0 +1,20 @@ +#ifndef MAD_LASTSTATECONDITION_HPP +#define MAD_LASTSTATECONDITION_HPP + +#include "Condition.hpp" +#include "event/management/controller/statemachine/StateMachine.hpp" +namespace mad::core { + struct LastStateCondition : Condition { + public: + LastStateCondition(std::shared_ptr m_machine, StateMachine::StateId m_to_state_id); + bool is_triggered_by(const mad::core::Event &event) override; + std::unordered_set triggers() override; + void on_start() override; + + private: + std::shared_ptr m_machine; + StateMachine::StateId m_to_state_id; + }; +}// namespace mad::core + +#endif//MAD_LASTSTATECONDITION_HPP diff --git a/core/event/management/condition/SensorCondition.cpp b/core/event/management/condition/SensorCondition.cpp new file mode 100644 index 0000000..24a25b1 --- /dev/null +++ b/core/event/management/condition/SensorCondition.cpp @@ -0,0 +1,14 @@ +#include "SensorCondition.hpp" +#include "common/Cast.hpp" +#include "event/physics/SensorCollision.hpp" +mad::core::SensorCondition::SensorCondition(Entity::Id m_entity_id) : m_entity_id(m_entity_id){ +} +bool mad::core::SensorCondition::is_triggered_by(const mad::core::Event &event) { + const auto &e = const_cast_to(event); + return e.m_id == m_entity_id; +} +std::unordered_set mad::core::SensorCondition::triggers() { + return {mad::core::Event::Type::SensorCollision}; +} +void mad::core::SensorCondition::on_start() { +} diff --git a/core/event/management/condition/SensorCondition.hpp b/core/event/management/condition/SensorCondition.hpp new file mode 100644 index 0000000..31ab53a --- /dev/null +++ b/core/event/management/condition/SensorCondition.hpp @@ -0,0 +1,19 @@ +#ifndef MAD_SENSORCONDITION_HPP +#define MAD_SENSORCONDITION_HPP +#include "Condition.hpp" +#include "world/entity/Entity.hpp" +namespace mad::core { + struct SensorCondition : Condition { + public: + explicit SensorCondition(Entity::Id m_entity_id); + bool is_triggered_by(const mad::core::Event &event) override; + std::unordered_set triggers() override; + void on_start() override; + + private: + Entity::Id m_entity_id; + }; +}// namespace mad::core + + +#endif//MAD_SENSORCONDITION_HPP diff --git a/core/event/management/condition/SensorEndCondition.cpp b/core/event/management/condition/SensorEndCondition.cpp new file mode 100644 index 0000000..3462a9e --- /dev/null +++ b/core/event/management/condition/SensorEndCondition.cpp @@ -0,0 +1,24 @@ + +#include "SensorEndCondition.hpp" +#include "common/Cast.hpp" +#include "event/physics/SensorCollisionEnd.hpp" +#include + +mad::core::SensorEndCondition::SensorEndCondition(Entity::Id m_entity_id, float delta_time) : m_entity_id(m_entity_id), m_dt(delta_time){ +} +bool mad::core::SensorEndCondition::is_triggered_by(const mad::core::Event &event) { + if(event.type == Event::Type::SensorCollisionEnd){ + const auto &e = const_cast_to(event); + if(e.m_id == m_entity_id){ + sf::Time time = clock.getElapsedTime(); + timerStart = time.asSeconds(); + } + } + return clock.getElapsedTime().asSeconds() - timerStart < m_dt; + +} +std::unordered_set mad::core::SensorEndCondition::triggers() { + return {mad::core::Event::Type::SensorCollisionEnd, mad::core::Event::Type::WorldUpdate}; +} +void mad::core::SensorEndCondition::on_start() { +} diff --git a/core/event/management/condition/SensorEndCondition.hpp b/core/event/management/condition/SensorEndCondition.hpp new file mode 100644 index 0000000..efc7c2c --- /dev/null +++ b/core/event/management/condition/SensorEndCondition.hpp @@ -0,0 +1,23 @@ +#ifndef MAD_SENSORENDCONDITION_HPP +#define MAD_SENSORENDCONDITION_HPP + +#include "Condition.hpp" +#include "world/entity/Entity.hpp" +#include +namespace mad::core { + struct SensorEndCondition : Condition { + public: + explicit SensorEndCondition(Entity::Id m_entity_id, float delta_time); + bool is_triggered_by(const mad::core::Event &event) override; + std::unordered_set triggers() override; + void on_start() override; + + private: + Entity::Id m_entity_id; + sf::Clock clock; + float timerStart; + float m_dt; + }; +}// namespace mad::core + +#endif//MAD_SENSORENDCONDITION_HPP diff --git a/core/event/management/condition/TakeDamageCondition.cpp b/core/event/management/condition/TakeDamageCondition.cpp new file mode 100644 index 0000000..48955b6 --- /dev/null +++ b/core/event/management/condition/TakeDamageCondition.cpp @@ -0,0 +1,19 @@ +#include "TakeDamageCondition.hpp" +#include "common/Cast.hpp" +#include "event/physics/TakeDamage.hpp" +mad::core::TakeDamageCondition::TakeDamageCondition(Entity::Id m_entity_id) : m_entity_id(m_entity_id) { +} +bool mad::core::TakeDamageCondition::is_triggered_by(const mad::core::Event &event) { + if(event.type == Event::Type::TakeDamage){ + const auto &e = const_cast_to(event); + if(e.entity_id == m_entity_id){ + return true; + } + } + return false; +} +std::unordered_set mad::core::TakeDamageCondition::triggers() { + return {mad::core::Event::Type::TakeDamage}; +} +void mad::core::TakeDamageCondition::on_start() { +} diff --git a/core/event/management/condition/TakeDamageCondition.hpp b/core/event/management/condition/TakeDamageCondition.hpp new file mode 100644 index 0000000..22bd041 --- /dev/null +++ b/core/event/management/condition/TakeDamageCondition.hpp @@ -0,0 +1,22 @@ +#ifndef MAD_TAKEDAMAGECONDITION_HPP +#define MAD_TAKEDAMAGECONDITION_HPP + +#include "Condition.hpp" +#include "world/entity/Entity.hpp" +#include +namespace mad::core { + struct TakeDamageCondition : Condition { + public: + explicit TakeDamageCondition(Entity::Id m_entity_id); + bool is_triggered_by(const mad::core::Event &event) override; + std::unordered_set triggers() override; + void on_start() override; + + private: + Entity::Id m_entity_id; + + }; +}// namespace mad::core + + +#endif//MAD_TAKEDAMAGECONDITION_HPP diff --git a/core/event/management/controller/Attack.cpp b/core/event/management/controller/Attack.cpp new file mode 100644 index 0000000..e3eff90 --- /dev/null +++ b/core/event/management/controller/Attack.cpp @@ -0,0 +1,75 @@ +#include "Attack.hpp" +#include "event/physics/TakeDamage.hpp" +#include "world/filter/RadiusFilter.hpp" +mad::core::Attack::Attack(std::shared_ptr world, std::shared_ptr level_dispatcher, mad::core::Entity::Id entity_id, mad::core::Movement::Direction dir, int *attack_stage, float velocity) : Movement(world, entity_id, dir, velocity), world(world), level_dispatcher(level_dispatcher), entity_id(entity_id), attack_stage(attack_stage) { + Move_animation = ImageStorage::TypeAction::Attack_1_beg; + Idle_animation = ImageStorage::TypeAction::Attack_1_beg; + m_entity = cast_to_or_null(world->get_storage().get_entity(entity_id)); +} +void mad::core::Attack::control() { + if ((*attack_stage) % 6 == 0) { + if (Move_animation != ImageStorage::TypeAction::Attack_1_beg) { + SPDLOG_DEBUG("changed to Attack_1_beg"); + } + Move_animation = ImageStorage::TypeAction::Attack_1_beg; + Idle_animation = ImageStorage::TypeAction::Attack_1_beg; + } + if ((*attack_stage) % 6 == 1) { + if (Move_animation != ImageStorage::TypeAction::Attack_1_end) { + SPDLOG_DEBUG("changed to Attack_1_end"); + } + for (auto id : world->get_storage().extract(RadiusFilter(m_entity->get_position(), 10.0f))) { + if (id != entity_id) { + level_dispatcher->dispatch(std::make_shared(id)); + } + } + Move_animation = ImageStorage::TypeAction::Attack_1_end; + Idle_animation = ImageStorage::TypeAction::Attack_1_end; + } + if ((*attack_stage) % 6 == 2) { + for (auto id : world->get_storage().extract(RadiusFilter(m_entity->get_position(), 10.0f))) { + if (id != entity_id) { + level_dispatcher->dispatch(std::make_shared(id)); + } + } + Move_animation = ImageStorage::TypeAction::Attack_2_beg; + Idle_animation = ImageStorage::TypeAction::Attack_2_beg; + } + if ((*attack_stage) % 6 == 3) { + if (Move_animation != ImageStorage::TypeAction::Attack_2_end) { + SPDLOG_DEBUG("changed to Attack_2_end"); + } + for (auto id : world->get_storage().extract(RadiusFilter(m_entity->get_position(), 10.0f))) { + if (id != entity_id) { + level_dispatcher->dispatch(std::make_shared(id)); + } + } + Move_animation = ImageStorage::TypeAction::Attack_2_end; + Idle_animation = ImageStorage::TypeAction::Attack_2_end; + } + if ((*attack_stage) % 6 == 4) { + if (Move_animation != ImageStorage::TypeAction::Attack_3_beg) { + SPDLOG_DEBUG("changed to Attack_3_beg"); + } + for (auto id : world->get_storage().extract(RadiusFilter(m_entity->get_position(), 10.0f))) { + if (id != entity_id) { + level_dispatcher->dispatch(std::make_shared(id)); + } + } + Move_animation = ImageStorage::TypeAction::Attack_3_beg; + Idle_animation = ImageStorage::TypeAction::Attack_3_beg; + } + if ((*attack_stage) % 6 == 5) { + if (Move_animation != ImageStorage::TypeAction::Attack_3_end) { + SPDLOG_DEBUG("changed to Attack_3_end"); + } + for (auto id : world->get_storage().extract(RadiusFilter(m_entity->get_position(), 10.0f))) { + if (id != entity_id) { + level_dispatcher->dispatch(std::make_shared(id)); + } + } + Move_animation = ImageStorage::TypeAction::Attack_3_end; + Idle_animation = ImageStorage::TypeAction::Attack_3_end; + } + Movement::control(); +} diff --git a/core/event/management/controller/Attack.hpp b/core/event/management/controller/Attack.hpp new file mode 100644 index 0000000..f6ded2a --- /dev/null +++ b/core/event/management/controller/Attack.hpp @@ -0,0 +1,24 @@ +#ifndef MAD_ATTACK_HPP +#define MAD_ATTACK_HPP + +#include "Movement.hpp" +#include "world/LocalWorld.hpp" +#include "world/World.hpp" + +namespace mad::core { + + class Attack : public Movement { + public: + Attack(std::shared_ptr world, std::shared_ptr level_dispatcher, Entity::Id entity_id, Direction dir, int* attack_stage, float velocity = 0); + void control() override; + int *attack_stage; + private: + std::shared_ptr world; + Entity::Id entity_id; + PhysicalEntity* m_entity; + std::shared_ptr level_dispatcher; + }; + +} + +#endif//MAD_ATTACK_HPP diff --git a/core/event/management/controller/DealDamage.cpp b/core/event/management/controller/DealDamage.cpp new file mode 100644 index 0000000..8c26051 --- /dev/null +++ b/core/event/management/controller/DealDamage.cpp @@ -0,0 +1,14 @@ + +#include "DealDamage.hpp" +#include "event/physics/TakeDamage.hpp" +#include "world/filter/RadiusFilter.hpp" + +mad::core::DealDamage::DealDamage(std::shared_ptr world, Entity::Id entity_id, std::shared_ptr level_dispatcher) : world(world), entity_id(entity_id), level_dispatcher(level_dispatcher) { + m_entity = cast_to_or_null(world->get_storage().get_entity(entity_id)); +} +void mad::core::DealDamage::control() { + for (auto id : world->get_storage().extract(RadiusFilter(m_entity->get_position(), 10.0f))) { + level_dispatcher->dispatch(std::make_shared(id)); + } + +} diff --git a/core/event/management/controller/DealDamage.hpp b/core/event/management/controller/DealDamage.hpp new file mode 100644 index 0000000..acde1ab --- /dev/null +++ b/core/event/management/controller/DealDamage.hpp @@ -0,0 +1,26 @@ +#ifndef MAD_DEALDAMAGE_HPP +#define MAD_DEALDAMAGE_HPP + + +#include "Controller.hpp" +#include "world/LocalWorld.hpp" +#include "world/World.hpp" + +namespace mad::core { + + class DealDamage : public Controller { + public: + explicit DealDamage(std::shared_ptr world, Entity::Id entity_id, std::shared_ptr level_dispatcher); + + void control() override; + private: + std::shared_ptr world; + Entity::Id entity_id; + PhysicalEntity* m_entity; + std::shared_ptr level_dispatcher; + }; + +} + + +#endif//MAD_DEALDAMAGE_HPP diff --git a/core/event/management/controller/Destroy.cpp b/core/event/management/controller/Destroy.cpp new file mode 100644 index 0000000..a439e4f --- /dev/null +++ b/core/event/management/controller/Destroy.cpp @@ -0,0 +1,16 @@ +#include "Destroy.hpp" +#include "event/physics/Death.hpp" +#include "world/intent/LambdaIntent.hpp" +mad::core::Destroy::Destroy(std::shared_ptr world, std::shared_ptr level_dispatcher, mad::core::Entity::Id entity_id) : world(world), level_dispatcher(level_dispatcher), entity_id(entity_id) { + m_entity = cast_to_or_null(world->get_storage().get_entity(entity_id)); +} +void mad::core::Destroy::control() { + auto set_position = []() { + return mad::core::LambdaIntent( + [=](mad::core::Entity &entity, mad::core::EventDispatcher &event_dispatcher) { + mad::core::cast_to(entity).set_image_position({-10000, -10000}); + }); + }; + level_dispatcher->dispatch(std::make_shared(entity_id)); + world->manipulate_entity_id(entity_id, set_position()); +} diff --git a/core/event/management/controller/Destroy.hpp b/core/event/management/controller/Destroy.hpp new file mode 100644 index 0000000..56a104b --- /dev/null +++ b/core/event/management/controller/Destroy.hpp @@ -0,0 +1,27 @@ +#ifndef MAD_DESTROY_HPP +#define MAD_DESTROY_HPP + + +#include "Movement.hpp" +#include "world/LocalWorld.hpp" +#include "world/World.hpp" + +namespace mad::core { + + class Destroy : public Controller { + public: + Destroy(std::shared_ptr world, std::shared_ptr level_dispatcher, Entity::Id entity_id); + void control() override; + private: + std::shared_ptr world; + std::shared_ptr level_dispatcher; + Entity::Id entity_id; + PhysicalEntity* m_entity; + + }; + +} + + + +#endif//MAD_DESTROY_HPP diff --git a/core/event/management/controller/Die.cpp b/core/event/management/controller/Die.cpp new file mode 100644 index 0000000..0f129f9 --- /dev/null +++ b/core/event/management/controller/Die.cpp @@ -0,0 +1,5 @@ +#include "Die.hpp" +mad::core::Die::Die(std::shared_ptr world, Entity::Id entity_id, Direction dir, float velocity) : Movement(world, entity_id, dir, velocity) { + Move_animation = ImageStorage::TypeAction::Die; + Idle_animation = ImageStorage::TypeAction::Die; +} \ No newline at end of file diff --git a/core/event/management/controller/Die.hpp b/core/event/management/controller/Die.hpp new file mode 100644 index 0000000..e0d8ea6 --- /dev/null +++ b/core/event/management/controller/Die.hpp @@ -0,0 +1,17 @@ +#ifndef MAD_DIE_HPP +#define MAD_DIE_HPP + +#include "Movement.hpp" +#include "world/LocalWorld.hpp" +#include "world/World.hpp" + +namespace mad::core { + + class Die : public Movement { + public: + Die(std::shared_ptr world, Entity::Id entity_id, Direction dir, float velocity = 0); + }; + +} + +#endif//MAD_DIE_HPP diff --git a/core/event/management/controller/EnemyAttack.cpp b/core/event/management/controller/EnemyAttack.cpp new file mode 100644 index 0000000..a27ac44 --- /dev/null +++ b/core/event/management/controller/EnemyAttack.cpp @@ -0,0 +1,31 @@ +#include "EnemyAttack.hpp" +#include "event/physics/TakeDamage.hpp" +#include "world/filter/RadiusFilter.hpp" +mad::core::EnemyAttack::EnemyAttack(std::shared_ptr world, std::shared_ptr level_dispatcher, mad::core::Entity::Id entity_id, mad::core::Movement::Direction dir, int* attack_stage, float velocity) : Movement(world, entity_id, dir, velocity), world(world), level_dispatcher(level_dispatcher), entity_id(entity_id), attack_stage(attack_stage){ + Move_animation = ImageStorage::TypeAction::Attack_1_beg; + Idle_animation = ImageStorage::TypeAction::Attack_1_beg; + m_entity = cast_to_or_null(world->get_storage().get_entity(entity_id)); +} +void mad::core::EnemyAttack::control() { + Movement::control(); + if((*attack_stage) % 2 == 0){ + if(Move_animation != ImageStorage::TypeAction::Attack_1_beg){ + SPDLOG_DEBUG("changed to Attack_1_beg"); + } + for (auto id : world->get_storage().extract(RadiusFilter(m_entity->get_position(), 6.0f))) { + if(id != entity_id){ + level_dispatcher->dispatch(std::make_shared(id)); + + } + } + Move_animation = ImageStorage::TypeAction::Attack_1_beg; + Idle_animation = ImageStorage::TypeAction::Attack_1_beg; + } + if((*attack_stage) % 2 == 1){ + if(Move_animation != ImageStorage::TypeAction::Attack_1_end){ + SPDLOG_DEBUG("changed to Attack_1_end"); + } + Move_animation = ImageStorage::TypeAction::Attack_1_end; + Idle_animation = ImageStorage::TypeAction::Attack_1_end; + } +} diff --git a/core/event/management/controller/EnemyAttack.hpp b/core/event/management/controller/EnemyAttack.hpp new file mode 100644 index 0000000..dda7038 --- /dev/null +++ b/core/event/management/controller/EnemyAttack.hpp @@ -0,0 +1,26 @@ +#ifndef MAD_ENEMYATTACK_HPP +#define MAD_ENEMYATTACK_HPP + + +#include "Movement.hpp" +#include "world/LocalWorld.hpp" +#include "world/World.hpp" + +namespace mad::core { + + class EnemyAttack : public Movement { + public: + EnemyAttack(std::shared_ptr world, std::shared_ptr level_dispatcher, Entity::Id entity_id, Direction dir, int* attack_stage, float velocity = 0); + void control() override; + int *attack_stage; + private: + std::shared_ptr world; + Entity::Id entity_id; + PhysicalEntity* m_entity; + std::shared_ptr level_dispatcher; + }; + +} + + +#endif//MAD_ENEMYATTACK_HPP diff --git a/core/event/management/controller/Fall.cpp b/core/event/management/controller/Fall.cpp new file mode 100644 index 0000000..ed817e6 --- /dev/null +++ b/core/event/management/controller/Fall.cpp @@ -0,0 +1,6 @@ +#include "Fall.hpp" + +mad::core::Fall::Fall(std::shared_ptr world, Entity::Id entity_id, Direction dir, float velocity) : Movement(world, entity_id, dir, velocity) { + Move_animation = ImageStorage::TypeAction::Fall; + Idle_animation = ImageStorage::TypeAction::Fall; +} diff --git a/core/event/management/controller/Fall.hpp b/core/event/management/controller/Fall.hpp new file mode 100644 index 0000000..4e8274d --- /dev/null +++ b/core/event/management/controller/Fall.hpp @@ -0,0 +1,17 @@ +#ifndef MAD_FALL_HPP +#define MAD_FALL_HPP + +#include "Movement.hpp" +#include "world/LocalWorld.hpp" +#include "world/World.hpp" + +namespace mad::core { + + class Fall : public Movement { + public: + Fall(std::shared_ptr world, Entity::Id entity_id, Direction dir, float velocity = 0); + }; + +} + +#endif//MAD_FALL_HPP diff --git a/core/event/management/controller/FlyUp.cpp b/core/event/management/controller/FlyUp.cpp new file mode 100644 index 0000000..969d7e2 --- /dev/null +++ b/core/event/management/controller/FlyUp.cpp @@ -0,0 +1,6 @@ +#include "FlyUp.hpp" + +mad::core::FlyUp::FlyUp(std::shared_ptr world, Entity::Id entity_id, Direction dir, float velocity) : Movement(world, entity_id, dir, velocity) { + Move_animation = ImageStorage::TypeAction::Fly_up; + Idle_animation = ImageStorage::TypeAction::Fly_up; +} diff --git a/core/event/management/controller/FlyUp.hpp b/core/event/management/controller/FlyUp.hpp new file mode 100644 index 0000000..e87bc4a --- /dev/null +++ b/core/event/management/controller/FlyUp.hpp @@ -0,0 +1,18 @@ +#ifndef MAD_FLYUP_HPP +#define MAD_FLYUP_HPP + + +#include "Movement.hpp" +#include "world/LocalWorld.hpp" +#include "world/World.hpp" + +namespace mad::core { + + class FlyUp : public Movement { + public: + FlyUp(std::shared_ptr world, Entity::Id entity_id, Direction dir, float velocity = 0); + }; + +} + +#endif//MAD_FLYUP_HPP diff --git a/core/event/management/controller/GroundMovement.cpp b/core/event/management/controller/GroundMovement.cpp new file mode 100644 index 0000000..b8e127e --- /dev/null +++ b/core/event/management/controller/GroundMovement.cpp @@ -0,0 +1,7 @@ + +#include "GroundMovement.hpp" + +mad::core::GroundMovement::GroundMovement(std::shared_ptr world, Entity::Id entity_id, Direction dir, float velocity) : Movement(world, entity_id, dir, velocity) { + Move_animation = ImageStorage::TypeAction::Run; + Idle_animation = ImageStorage::TypeAction::Idle; +} diff --git a/core/event/management/controller/GroundMovement.hpp b/core/event/management/controller/GroundMovement.hpp new file mode 100644 index 0000000..339fe34 --- /dev/null +++ b/core/event/management/controller/GroundMovement.hpp @@ -0,0 +1,17 @@ +#ifndef MAD_GROUNDMOVEMENT_HPP +#define MAD_GROUNDMOVEMENT_HPP + +#include "Movement.hpp" +#include "world/LocalWorld.hpp" +#include "world/World.hpp" + +namespace mad::core { + + class GroundMovement : public Movement { + public: + GroundMovement(std::shared_ptr world, Entity::Id entity_id, Direction dir, float velocity = 0); + }; + +} + +#endif//MAD_GROUNDMOVEMENT_HPP diff --git a/core/event/management/controller/Hurt.cpp b/core/event/management/controller/Hurt.cpp new file mode 100644 index 0000000..3ae477a --- /dev/null +++ b/core/event/management/controller/Hurt.cpp @@ -0,0 +1,5 @@ +#include "Hurt.hpp" +mad::core::Hurt::Hurt(std::shared_ptr world, Entity::Id entity_id, Direction dir, float velocity) : Movement(world, entity_id, dir, velocity) { + Move_animation = ImageStorage::TypeAction::Hurt; + Idle_animation = ImageStorage::TypeAction::Hurt; +} \ No newline at end of file diff --git a/core/event/management/controller/Hurt.hpp b/core/event/management/controller/Hurt.hpp new file mode 100644 index 0000000..a37e0e1 --- /dev/null +++ b/core/event/management/controller/Hurt.hpp @@ -0,0 +1,21 @@ +#ifndef MAD_HURT_HPP +#define MAD_HURT_HPP + + +#include "Movement.hpp" +#include "world/LocalWorld.hpp" +#include "world/World.hpp" + +namespace mad::core { + + class Hurt : public Movement { + public: + Hurt(std::shared_ptr world, Entity::Id entity_id, Direction dir, float velocity = 0); + }; + +} + + + + +#endif//MAD_HURT_HPP diff --git a/core/event/management/controller/JumpImpulse.cpp b/core/event/management/controller/JumpImpulse.cpp new file mode 100644 index 0000000..8ef771f --- /dev/null +++ b/core/event/management/controller/JumpImpulse.cpp @@ -0,0 +1,15 @@ +#include "JumpImpulse.hpp" +#include "world/intent/LambdaIntent.hpp" +mad::core::JumpImpulse::JumpImpulse(std::shared_ptr world, Entity::Id entity_id, float m_impulse) : m_world(world), m_entity_id(entity_id), m_impulse(m_impulse) { +} +void mad::core::JumpImpulse::control() { + + auto impulse = [](mad::core::Vec2d dir) { + return mad::core::LambdaIntent( + [=](mad::core::Entity &entity, mad::core::EventDispatcher &event_dispatcher) { + mad::core::cast_to(entity).apply_linear_impulse_to_center(dir, event_dispatcher); + }); + }; + + m_world->manipulate_entity_id(m_entity_id, impulse(mad::core::Vec2d{0.0f, -m_impulse})); +} diff --git a/core/event/management/controller/JumpImpulse.hpp b/core/event/management/controller/JumpImpulse.hpp new file mode 100644 index 0000000..4d3a654 --- /dev/null +++ b/core/event/management/controller/JumpImpulse.hpp @@ -0,0 +1,26 @@ +#ifndef MAD_JUMPIMPULSE_HPP +#define MAD_JUMPIMPULSE_HPP + +#include "Controller.hpp" +#include "world/LocalWorld.hpp" +#include "world/World.hpp" +namespace mad::core { + + class JumpImpulse : public Controller { + public: + + explicit JumpImpulse(std::shared_ptr world, Entity::Id entity_id, float m_impulse); + + void control() override; + + private: + std::shared_ptr m_world; + Entity::Id m_entity_id; + std::shared_ptr key; + float m_impulse; + + }; + +} + +#endif//MAD_JUMPIMPULSE_HPP diff --git a/core/event/management/controller/Movement.cpp b/core/event/management/controller/Movement.cpp new file mode 100644 index 0000000..ec235af --- /dev/null +++ b/core/event/management/controller/Movement.cpp @@ -0,0 +1,29 @@ +#include "Movement.hpp" +#include "world/intent/LambdaIntent.hpp" +mad::core::Movement::Movement(std::shared_ptr world, Entity::Id entity_id, mad::core::Movement::Direction dir, float velocity) : m_world(world), m_entity_id(entity_id), dir(dir), velocity(velocity){ + m_entity = cast_to_or_null(m_world->get_storage().get_entity(m_entity_id)); +} +void mad::core::Movement::control() { + auto set_horizontal_velocity = [](float vel) { + return mad::core::LambdaIntent( + [=](mad::core::Entity &entity, mad::core::EventDispatcher &event_dispatcher) { + mad::core::cast_to(entity).set_linear_horizontal_velocity(vel, event_dispatcher); + }); + }; + if(dir == Direction::Right || dir == Direction::Left){ + m_entity->set_action(Move_animation); + if(dir == Direction::Right){ + m_entity->flip_over(Image::Orientation::Right); + m_world->manipulate_entity_id(m_entity_id, set_horizontal_velocity(velocity)); + } + else if(dir == Direction::Left){ + m_entity->flip_over(Image::Orientation::Left); + m_world->manipulate_entity_id(m_entity_id, set_horizontal_velocity(-velocity)); + } + } + else if(dir == Direction::Idle){ + m_entity->set_action(Idle_animation); + } + float k = 0.8; + m_world->manipulate_entity_id(m_entity_id, set_horizontal_velocity(m_entity->get_linear_velocity().get_x() * k)); +} diff --git a/core/event/management/controller/Movement.hpp b/core/event/management/controller/Movement.hpp new file mode 100644 index 0000000..2bac02d --- /dev/null +++ b/core/event/management/controller/Movement.hpp @@ -0,0 +1,35 @@ +#ifndef MAD_MOVEMENT_HPP +#define MAD_MOVEMENT_HPP + + +#include "Controller.hpp" +#include "world/LocalWorld.hpp" +#include "world/World.hpp" + +namespace mad::core { + + class Movement : public Controller { + public: + enum class Direction { + Right, + Left, + Idle, + }; + explicit Movement(std::shared_ptr world, Entity::Id entity_id, Direction dir, float velocity = 0); + + void control() override; + + private: + std::shared_ptr m_world; + Entity::Id m_entity_id; + Direction dir; + PhysicalEntity* m_entity; + float velocity; + protected: + ImageStorage::TypeAction Move_animation; + ImageStorage::TypeAction Idle_animation; + }; + +} + +#endif//MAD_MOVEMENT_HPP diff --git a/core/event/management/controller/StartJump.cpp b/core/event/management/controller/StartJump.cpp new file mode 100644 index 0000000..c124a52 --- /dev/null +++ b/core/event/management/controller/StartJump.cpp @@ -0,0 +1,6 @@ +#include "StartJump.hpp" + +mad::core::StartJump::StartJump(std::shared_ptr world, Entity::Id entity_id, Direction dir, float velocity) : Movement(world, entity_id, dir, velocity) { + Move_animation = ImageStorage::TypeAction::Jump; + Idle_animation = ImageStorage::TypeAction::Jump; +} diff --git a/core/event/management/controller/StartJump.hpp b/core/event/management/controller/StartJump.hpp new file mode 100644 index 0000000..ea4df13 --- /dev/null +++ b/core/event/management/controller/StartJump.hpp @@ -0,0 +1,17 @@ +#ifndef MAD_STARTJUMP_HPP +#define MAD_STARTJUMP_HPP + +#include "Movement.hpp" +#include "world/LocalWorld.hpp" +#include "world/World.hpp" + +namespace mad::core { + + class StartJump : public Movement { + public: + StartJump(std::shared_ptr world, Entity::Id entity_id, Direction dir, float velocity = 0); + }; + +} + +#endif//MAD_STARTJUMP_HPP diff --git a/core/event/management/controller/statemachine/EnemyStateMachine.cpp b/core/event/management/controller/statemachine/EnemyStateMachine.cpp new file mode 100644 index 0000000..2416c7a --- /dev/null +++ b/core/event/management/controller/statemachine/EnemyStateMachine.cpp @@ -0,0 +1,93 @@ +#include "EnemyStateMachine.hpp" +#include "event/management/condition/Counter.hpp" +#include "event/management/condition/EndAnimationCondition.hpp" +#include "event/management/condition/EnemyAttackCondition.hpp" +#include "event/management/condition/FallCondition.hpp" +#include "event/management/condition/KeyDownCondition.hpp" +#include "event/management/condition/KeyPressedCondition.hpp" +#include "event/management/condition/KeyReleasedCondition.hpp" +#include "event/management/condition/LastStateCondition.hpp" +#include "event/management/condition/SensorCondition.hpp" +#include "event/management/condition/SensorEndCondition.hpp" +#include "event/management/condition/TakeDamageCondition.hpp" +#include "event/management/condition/TimerCondition.hpp" +#include "event/management/condition/TrueCondition.hpp" +#include "event/management/controller/Attack.hpp" +#include "event/management/controller/Destroy.hpp" +#include "event/management/controller/Die.hpp" +#include "event/management/controller/EnemyAttack.hpp" +#include "event/management/controller/Fall.hpp" +#include "event/management/controller/FlyUp.hpp" +#include "event/management/controller/GroundMovement.hpp" +#include "event/management/controller/Hurt.hpp" +#include "event/management/controller/JumpImpulse.hpp" +#include "event/management/controller/Movement.hpp" +#include "event/management/controller/StartJump.hpp" +#include "event/management/controller/statemachine/StateMachine.hpp" + +mad::core::EnemyStateMachine::EnemyStateMachine(std::shared_ptr world, mad::core::Vec2d position, int hero_id, std::shared_ptr level_dispatcher, float m_impulse, float horizontal_velocity, int real_hero_id) : StateMachine(level_dispatcher){ + auto machine = this; + + + StateMachine::StateId ground_idle = machine->add_state(std::make_shared(world, hero_id, Movement::Direction::Idle)); + StateMachine::StateId ground_idle1 = machine->add_state(std::make_shared(world, hero_id, Movement::Direction::Idle)); + StateMachine::StateId ground_idle2 = machine->add_state(std::make_shared(world, hero_id, Movement::Direction::Idle)); + StateMachine::StateId ground_right = machine->add_state(std::make_shared(world, hero_id, Movement::Direction::Right, horizontal_velocity)); + StateMachine::StateId ground_left = machine->add_state(std::make_shared(world, hero_id, Movement::Direction::Left, horizontal_velocity)); + StateMachine::StateId die_idle = machine->add_state(std::make_shared(world, hero_id, Movement::Direction::Idle)); + StateMachine::StateId hurt_idle = machine->add_state(std::make_shared(world, hero_id, Movement::Direction::Idle)); + StateMachine::StateId destroy = machine->add_state(std::make_shared(world, level_dispatcher, hero_id)); + + int *attack_stage = new int(0); + StateMachine::StateId attack_idle = machine->add_state(std::make_shared(world, level_dispatcher, hero_id, Movement::Direction::Idle, attack_stage, horizontal_velocity)); + + machine->add_transition(ground_idle, ground_right, std::make_shared(1 + rand() % 2)); + machine->add_transition(ground_right, ground_idle1, std::make_shared(1 + rand() % 2)); + machine->add_transition(ground_idle1, ground_left, std::make_shared(1 + rand() % 2)); + machine->add_transition(ground_left, ground_idle, std::make_shared(1 + rand() % 2)); + + machine->add_transition(ground_left, attack_idle, std::make_shared(world, hero_id, real_hero_id)); + machine->add_transition(ground_idle, attack_idle, std::make_shared(world, hero_id, real_hero_id)); + machine->add_transition(ground_idle1, attack_idle, std::make_shared(world, hero_id, real_hero_id)); + + machine->add_transition(ground_right, attack_idle, std::make_shared(world, hero_id, real_hero_id)); + + machine->add_transition(attack_idle, attack_idle, std::make_shared(hero_id, ImageStorage::TypeAction::Attack_1_beg, attack_stage)); + machine->add_transition(attack_idle, ground_idle2, std::make_shared(hero_id, ImageStorage::TypeAction::Attack_1_end, attack_stage)); + machine->add_transition(ground_idle2, ground_idle, std::make_shared(0.7)); + + + machine->add_transition(ground_idle, hurt_idle, std::make_shared(hero_id)); + machine->add_transition(ground_idle2, hurt_idle, std::make_shared(hero_id)); + machine->add_transition(ground_idle1, hurt_idle, std::make_shared(hero_id)); + + machine->add_transition(ground_left, hurt_idle, std::make_shared(hero_id)); + machine->add_transition(ground_right, hurt_idle, std::make_shared(hero_id)); + machine->add_transition(attack_idle, hurt_idle, std::make_shared(hero_id)); + + int *attack_count= new int(0); + + machine->add_transition(hurt_idle, ground_idle, std::make_shared(hero_id, ImageStorage::TypeAction::Hurt, attack_count)); + + machine->add_transition(ground_idle, die_idle, std::make_shared(attack_count, 3)); + machine->add_transition(ground_idle1, die_idle, std::make_shared(attack_count, 3)); + + machine->add_transition(ground_idle2, die_idle, std::make_shared(attack_count, 3)); + + machine->add_transition(ground_left, die_idle, std::make_shared(attack_count, 3)); + machine->add_transition(ground_right, die_idle, std::make_shared(attack_count, 3)); + + + + machine->add_transition(die_idle, destroy, std::make_shared(hero_id, ImageStorage::TypeAction::Die)); + + + + + + + + + machine->set_initial_state(0); + //controllers.push_back(machine); +} diff --git a/core/event/management/controller/statemachine/EnemyStateMachine.hpp b/core/event/management/controller/statemachine/EnemyStateMachine.hpp new file mode 100644 index 0000000..bd4759a --- /dev/null +++ b/core/event/management/controller/statemachine/EnemyStateMachine.hpp @@ -0,0 +1,17 @@ +#ifndef MAD_ENEMYSTATEMACHINE_HPP +#define MAD_ENEMYSTATEMACHINE_HPP + +#include "StateMachine.hpp" +#include "world/LocalWorld.hpp" +namespace mad::core{ + class EnemyStateMachine : public StateMachine { + + public: + explicit EnemyStateMachine(std::shared_ptr world, Vec2d position, int hero_id, std::shared_ptr level_dispatcher, float m_impulse, float horizontal_velocity, int real_hero_id); + private: + float health = 30; + }; +} + + +#endif//MAD_ENEMYSTATEMACHINE_HPP diff --git a/core/event/management/controller/statemachine/HeroStateMachine.cpp b/core/event/management/controller/statemachine/HeroStateMachine.cpp new file mode 100644 index 0000000..fdbed62 --- /dev/null +++ b/core/event/management/controller/statemachine/HeroStateMachine.cpp @@ -0,0 +1,182 @@ +#include "HeroStateMachine.hpp" +#include "event/management/condition/Counter.hpp" +#include "event/management/condition/EndAnimationCondition.hpp" +#include "event/management/condition/FallCondition.hpp" +#include "event/management/condition/FallDownCondition.hpp" +#include "event/management/condition/KeyDownCondition.hpp" +#include "event/management/condition/KeyPressedCondition.hpp" +#include "event/management/condition/KeyReleasedCondition.hpp" +#include "event/management/condition/LastStateCondition.hpp" +#include "event/management/condition/SensorCondition.hpp" +#include "event/management/condition/SensorEndCondition.hpp" +#include "event/management/condition/TakeDamageCondition.hpp" +#include "event/management/condition/TimerCondition.hpp" +#include "event/management/condition/TrueCondition.hpp" +#include "event/management/controller/Attack.hpp" +#include "event/management/controller/DealDamage.hpp" +#include "event/management/controller/Destroy.hpp" +#include "event/management/controller/Die.hpp" +#include "event/management/controller/Fall.hpp" +#include "event/management/controller/FlyUp.hpp" +#include "event/management/controller/GroundMovement.hpp" +#include "event/management/controller/Hurt.hpp" +#include "event/management/controller/JumpImpulse.hpp" +#include "event/management/controller/Movement.hpp" +#include "event/management/controller/StartJump.hpp" +#include "event/management/controller/statemachine/StateMachine.hpp" + +mad::core::HeroStateMachine::HeroStateMachine(std::shared_ptr world, mad::core::Vec2d position, int hero_id, std::shared_ptr level_dispatcher, float m_impulse, float horizontal_velocity) : StateMachine(level_dispatcher){ + auto machine = this; + + + StateMachine::StateId ground_idle = machine->add_state(std::make_shared(world, hero_id, Movement::Direction::Idle)); + StateMachine::StateId ground_right = machine->add_state(std::make_shared(world, hero_id, Movement::Direction::Right, horizontal_velocity)); + StateMachine::StateId ground_left = machine->add_state(std::make_shared(world, hero_id, Movement::Direction::Left, horizontal_velocity)); + StateMachine::StateId jump_impulse = machine->add_state(std::make_shared(world, hero_id, m_impulse)); + StateMachine::StateId start_jump_left = machine->add_state(std::make_shared(world, hero_id, Movement::Direction::Left, horizontal_velocity)); + StateMachine::StateId start_jump_idle = machine->add_state(std::make_shared(world, hero_id, Movement::Direction::Idle, horizontal_velocity)); + StateMachine::StateId start_jump_right = machine->add_state(std::make_shared(world, hero_id, Movement::Direction::Right, horizontal_velocity)); + StateMachine::StateId fly_up_left = machine->add_state(std::make_shared(world, hero_id, Movement::Direction::Left, horizontal_velocity)); /// 7 + StateMachine::StateId fly_up_idle = machine->add_state(std::make_shared(world, hero_id, Movement::Direction::Idle, horizontal_velocity)); + StateMachine::StateId fly_up_right = machine->add_state(std::make_shared(world, hero_id, Movement::Direction::Right, horizontal_velocity)); + StateMachine::StateId fall_left = machine->add_state(std::make_shared(world, hero_id, Movement::Direction::Left, horizontal_velocity)); /// 10 + StateMachine::StateId fall_idle = machine->add_state(std::make_shared(world, hero_id, Movement::Direction::Idle, horizontal_velocity)); + StateMachine::StateId fall_right= machine->add_state(std::make_shared(world, hero_id, Movement::Direction::Right, horizontal_velocity)); + int *attack_stage = new int(0); + int *attack_count= new int(0); + StateMachine::StateId attack_left = machine->add_state(std::make_shared(world, level_dispatcher, hero_id, Movement::Direction::Left, attack_stage, horizontal_velocity)); + StateMachine::StateId attack_idle= machine->add_state(std::make_shared(world, level_dispatcher, hero_id, Movement::Direction::Idle, attack_stage, horizontal_velocity)); + StateMachine::StateId attack_right = machine->add_state(std::make_shared(world, level_dispatcher, hero_id, Movement::Direction::Right, attack_stage, horizontal_velocity)); + StateMachine::StateId deal_damage = machine->add_state(std::make_shared(world, hero_id, level_dispatcher)); + StateMachine::StateId hurt_idle = machine->add_state(std::make_shared(world, hero_id, Movement::Direction::Idle)); + StateMachine::StateId die_idle = machine->add_state(std::make_shared(world, hero_id, Movement::Direction::Idle)); + StateMachine::StateId destroy = machine->add_state(std::make_shared(world, level_dispatcher, hero_id)); + + + machine->add_transition(ground_idle, hurt_idle, std::make_shared(hero_id)); + machine->add_transition(ground_left, hurt_idle, std::make_shared(hero_id)); + machine->add_transition(ground_right, hurt_idle, std::make_shared(hero_id)); + machine->add_transition(attack_idle, hurt_idle, std::make_shared(hero_id)); + machine->add_transition(attack_left, hurt_idle, std::make_shared(hero_id)); + machine->add_transition(attack_right, hurt_idle, std::make_shared(hero_id)); + machine->add_transition(fall_idle, hurt_idle, std::make_shared(hero_id)); + machine->add_transition(fall_left, hurt_idle, std::make_shared(hero_id)); + machine->add_transition(fall_right, hurt_idle, std::make_shared(hero_id)); + machine->add_transition(hurt_idle, ground_idle, std::make_shared(hero_id, ImageStorage::TypeAction::Hurt, attack_count)); + + machine->add_transition(ground_idle, die_idle, std::make_shared(attack_count, 5)); + machine->add_transition(ground_left, die_idle, std::make_shared(attack_count, 5)); + machine->add_transition(ground_right, die_idle, std::make_shared(attack_count, 5)); + + machine->add_transition(fall_idle, die_idle, std::make_shared(world, hero_id)); + machine->add_transition(fall_left, die_idle, std::make_shared(world, hero_id)); + machine->add_transition(fall_right, die_idle, std::make_shared(world, hero_id)); + + + + machine->add_transition(die_idle, destroy, std::make_shared(hero_id, ImageStorage::TypeAction::Die)); + machine->add_transition(destroy, ground_idle, std::make_shared()); + + + + + + + + + machine->add_transition(ground_idle, ground_right, std::make_shared(sf::Keyboard::Right)); + machine->add_transition(ground_idle, ground_left, std::make_shared(sf::Keyboard::Left)); + machine->add_transition(ground_right, ground_idle, std::make_shared(sf::Keyboard::Right)); + machine->add_transition(ground_left, ground_idle, std::make_shared(sf::Keyboard::Left)); + machine->add_transition(ground_right, ground_left, std::make_shared(sf::Keyboard::Left)); + machine->add_transition(ground_left, ground_right, std::make_shared(sf::Keyboard::Right)); + machine->add_transition(ground_idle, jump_impulse, std::make_shared(sf::Keyboard::Space)); + machine->add_transition(ground_right, jump_impulse, std::make_shared(sf::Keyboard::Space)); + machine->add_transition(ground_left, jump_impulse, std::make_shared(sf::Keyboard::Space)); + + machine->add_transition(jump_impulse, start_jump_idle, std::make_shared()); + machine->add_transition(start_jump_idle, start_jump_left , std::make_shared(sf::Keyboard::Left)); + machine->add_transition(start_jump_idle, start_jump_right, std::make_shared(sf::Keyboard::Right)); + machine->add_transition(start_jump_left , start_jump_idle, std::make_shared(sf::Keyboard::Left)); + machine->add_transition(start_jump_right, start_jump_idle, std::make_shared(sf::Keyboard::Right)); + + + machine->add_transition(start_jump_left , fly_up_idle, std::make_shared(hero_id, ImageStorage::TypeAction::Jump)); + machine->add_transition(start_jump_idle, fly_up_idle, std::make_shared(hero_id, ImageStorage::TypeAction::Jump)); + machine->add_transition(start_jump_right, fly_up_idle, std::make_shared(hero_id, ImageStorage::TypeAction::Jump)); + + machine->add_transition(fly_up_idle, fly_up_left, std::make_shared(sf::Keyboard::Left)); + machine->add_transition(fly_up_idle, fly_up_right, std::make_shared(sf::Keyboard::Right)); + machine->add_transition(fly_up_left, fly_up_idle, std::make_shared(sf::Keyboard::Left)); + machine->add_transition(fly_up_right, fly_up_idle, std::make_shared(sf::Keyboard::Right)); + + machine->add_transition(fly_up_left, fall_idle, std::make_shared(world, hero_id, 0)); + machine->add_transition(fly_up_idle, fall_idle, std::make_shared(world, hero_id, 0)); + machine->add_transition(fly_up_right, fall_idle, std::make_shared(world, hero_id, 0)); + + machine->add_transition(ground_left, fall_idle, std::vector>{std::make_shared(world, hero_id, 0.1), std::make_shared(hero_id, 0.2)}); + machine->add_transition(ground_idle, fall_idle, std::vector>{std::make_shared(world, hero_id, 0.1), std::make_shared(hero_id, 0.2)}); + machine->add_transition(ground_right, fall_idle, std::vector>{std::make_shared(world, hero_id, 0.1), std::make_shared(hero_id, 0.2)}); + + machine->add_transition(fall_idle, fall_left, std::make_shared(sf::Keyboard::Left)); + machine->add_transition(fall_idle, fall_right, std::make_shared(sf::Keyboard::Right)); + machine->add_transition(fall_left, fall_idle, std::make_shared(sf::Keyboard::Left)); + machine->add_transition(fall_right, fall_idle, std::make_shared(sf::Keyboard::Right)); + + machine->add_transition(fall_left, ground_idle, std::make_shared(hero_id)); + machine->add_transition(fall_idle, ground_idle, std::make_shared(hero_id)); + machine->add_transition(fall_right, ground_idle, std::make_shared(hero_id)); + + + machine->add_transition(ground_left, attack_idle, std::make_shared(sf::Keyboard::Q)); + machine->add_transition(ground_idle, attack_idle, std::make_shared(sf::Keyboard::Q)); + machine->add_transition(ground_right, attack_idle, std::make_shared(sf::Keyboard::Q)); + machine->add_transition(start_jump_left, attack_idle, std::make_shared(sf::Keyboard::Q)); + machine->add_transition(start_jump_idle, attack_idle, std::make_shared(sf::Keyboard::Q)); + machine->add_transition(start_jump_right, attack_idle, std::make_shared(sf::Keyboard::Q)); + machine->add_transition(fly_up_left, attack_idle, std::make_shared(sf::Keyboard::Q)); + machine->add_transition(fly_up_idle, attack_idle, std::make_shared(sf::Keyboard::Q)); + machine->add_transition(fly_up_right, attack_idle, std::make_shared(sf::Keyboard::Q)); + machine->add_transition(fall_left, attack_idle, std::make_shared(sf::Keyboard::Q)); + machine->add_transition(fall_idle, attack_idle, std::make_shared(sf::Keyboard::Q)); + machine->add_transition(fall_right, attack_idle, std::make_shared(sf::Keyboard::Q)); + + machine->add_transition(attack_idle, attack_left, std::make_shared(sf::Keyboard::Left)); + machine->add_transition(attack_left, attack_idle, std::make_shared(sf::Keyboard::Left)); + machine->add_transition(attack_idle, attack_right, std::make_shared(sf::Keyboard::Right)); + machine->add_transition(attack_right, attack_idle, std::make_shared(sf::Keyboard::Right)); + + machine->add_transition(attack_idle, attack_idle, std::make_shared(hero_id, ImageStorage::TypeAction::Attack_1_beg, attack_stage)); + machine->add_transition(attack_left, attack_idle, std::make_shared(hero_id, ImageStorage::TypeAction::Attack_1_beg, attack_stage)); + machine->add_transition(attack_right, attack_idle, std::make_shared(hero_id, ImageStorage::TypeAction::Attack_1_beg, attack_stage)); + + machine->add_transition(attack_left, ground_idle, std::make_shared(hero_id, ImageStorage::TypeAction::Attack_1_end, attack_stage)); + machine->add_transition(attack_idle, ground_idle, std::make_shared(hero_id, ImageStorage::TypeAction::Attack_1_end, attack_stage)); + machine->add_transition(attack_right, ground_idle, std::make_shared(hero_id, ImageStorage::TypeAction::Attack_1_end, attack_stage)); + + machine->add_transition(attack_idle, attack_idle, std::make_shared(hero_id, ImageStorage::TypeAction::Attack_2_beg, attack_stage)); + machine->add_transition(attack_left, attack_idle, std::make_shared(hero_id, ImageStorage::TypeAction::Attack_2_beg, attack_stage)); + machine->add_transition(attack_right, attack_idle, std::make_shared(hero_id, ImageStorage::TypeAction::Attack_2_beg, attack_stage)); + + machine->add_transition(attack_left, ground_idle, std::make_shared(hero_id, ImageStorage::TypeAction::Attack_2_end, attack_stage)); + machine->add_transition(attack_idle, ground_idle, std::make_shared(hero_id, ImageStorage::TypeAction::Attack_2_end, attack_stage)); + machine->add_transition(attack_right, ground_idle, std::make_shared(hero_id, ImageStorage::TypeAction::Attack_2_end, attack_stage)); + + machine->add_transition(attack_idle, attack_idle, std::make_shared(hero_id, ImageStorage::TypeAction::Attack_3_beg, attack_stage)); + machine->add_transition(attack_left, attack_idle, std::make_shared(hero_id, ImageStorage::TypeAction::Attack_3_beg, attack_stage)); + machine->add_transition(attack_right, attack_idle, std::make_shared(hero_id, ImageStorage::TypeAction::Attack_3_beg, attack_stage)); + + machine->add_transition(attack_left, ground_idle, std::make_shared(hero_id, ImageStorage::TypeAction::Attack_3_end, attack_stage)); + machine->add_transition(attack_idle, ground_idle, std::make_shared(hero_id, ImageStorage::TypeAction::Attack_3_end, attack_stage)); + machine->add_transition(attack_right, ground_idle, std::make_shared(hero_id, ImageStorage::TypeAction::Attack_3_end, attack_stage)); + + + + + + + + + machine->set_initial_state(0); + //controllers.push_back(machine); +} diff --git a/core/event/management/controller/statemachine/HeroStateMachine.hpp b/core/event/management/controller/statemachine/HeroStateMachine.hpp new file mode 100644 index 0000000..98a12cc --- /dev/null +++ b/core/event/management/controller/statemachine/HeroStateMachine.hpp @@ -0,0 +1,19 @@ +#ifndef MAD_HEROSTATEMACHINE_HPP +#define MAD_HEROSTATEMACHINE_HPP + +#include "StateMachine.hpp" +#include "world/LocalWorld.hpp" +namespace mad::core { + class HeroStateMachine : public StateMachine { + + public: + explicit HeroStateMachine(std::shared_ptr world, Vec2d position, int hero_id, std::shared_ptr level_dispatcher, float m_impulse, float horizontal_velocity); + private: + float health = 30; + + }; + +}// namespace mad::core + + +#endif//MAD_HEROSTATEMACHINE_HPP diff --git a/core/event/management/controller/statemachine/StateMachine.cpp b/core/event/management/controller/statemachine/StateMachine.cpp index b986148..d5bd2d1 100644 --- a/core/event/management/controller/statemachine/StateMachine.cpp +++ b/core/event/management/controller/statemachine/StateMachine.cpp @@ -7,12 +7,28 @@ std::unordered_set mad::core::Transition::handled_types() { - return m_condition->triggers(); + std::unordered_set res; + for(auto const &i : m_conditions){ + res.insert(i->triggers().begin(), i->triggers().end()); + } + return res; } void mad::core::Transition::handle(const mad::core::Event &event) { if (!is_active || m_state_machine->has_made_transition) return; - if (m_condition->is_triggered_by(event)) { + for(auto &i : m_conditions){ + if(i->triggers().find(event.type) != i->triggers().end()){ + if(i->is_triggered_by(event)){ + i->triggered = true; + } + } + } + bool flag = true; + for(auto &i : m_conditions){ + flag &= i->triggered; + } + if (flag) { m_state_machine->has_made_transition = true; + m_state_machine->m_previous_state_id = m_state_machine->m_current_state_id; m_state_machine->m_current_state_id = next_state; SPDLOG_DEBUG("current state {}", m_state_machine->m_current_state_id); for (auto &i : m_state_machine->m_transitions[current_state]) { @@ -20,17 +36,26 @@ void mad::core::Transition::handle(const mad::core::Event &event) { } for (auto &i : m_state_machine->m_transitions[next_state]) { i->is_active = true; - i->m_condition->on_start(); + for(auto &el : i->m_conditions){ + el->on_start(); + } } } } -mad::core::Transition::Transition(mad::core::StateMachine *m_state_machine, mad::core::StateMachine::StateId current_state, mad::core::StateMachine::StateId next_state, std::shared_ptr m_condition) : m_state_machine(m_state_machine), current_state(current_state), next_state(next_state), m_condition(std::move(m_condition)) { +mad::core::Transition::Transition(mad::core::StateMachine *m_state_machine, mad::core::StateMachine::StateId current_state, mad::core::StateMachine::StateId next_state, std::shared_ptr m_condition) : m_state_machine(m_state_machine), current_state(current_state), next_state(next_state), m_conditions({std::move(m_condition)}) { +} +mad::core::Transition::Transition(mad::core::StateMachine *m_state_machine, mad::core::StateMachine::StateId current_state, mad::core::StateMachine::StateId next_state, std::vector> m_conditions) : m_state_machine(m_state_machine), current_state(current_state), next_state(next_state), m_conditions(m_conditions) { } /// StateMachine void mad::core::StateMachine::control() { //SPDLOG_DEBUG("current state {}", m_current_state_id); + for(auto &i : m_transitions[m_current_state_id]){ + for(auto &j : i->m_conditions){ + j->triggered = false; + } + } has_made_transition = false; m_states[m_current_state_id]->control(); } @@ -41,6 +66,7 @@ mad::core::StateMachine::StateId mad::core::StateMachine::add_state(const std::s } void mad::core::StateMachine::set_initial_state(mad::core::StateMachine::StateId state_id) { m_current_state_id = state_id; + m_previous_state_id = state_id; for (auto &i : m_transitions[state_id]) { i->is_active = true; } @@ -50,5 +76,13 @@ void mad::core::StateMachine::add_transition(mad::core::StateMachine::StateId st m_transitions[state_id_from].push_back(transition); m_dispatcher->registry(transition); } +void mad::core::StateMachine::add_transition(mad::core::StateMachine::StateId state_id_from, mad::core::StateMachine::StateId state_id_to, std::vector> transition_conditions) { + auto transition = std::make_shared(this, state_id_from, state_id_to, transition_conditions); + m_transitions[state_id_from].push_back(transition); + m_dispatcher->registry(transition); +} mad::core::StateMachine::StateMachine(std::shared_ptr m_dispatcher) : m_dispatcher(std::move(m_dispatcher)){ } +mad::core::StateMachine::StateId mad::core::StateMachine::get_previous_state_id() { + return m_previous_state_id; +} diff --git a/core/event/management/controller/statemachine/StateMachine.hpp b/core/event/management/controller/statemachine/StateMachine.hpp index 733e029..e9629da 100644 --- a/core/event/management/controller/statemachine/StateMachine.hpp +++ b/core/event/management/controller/statemachine/StateMachine.hpp @@ -19,11 +19,15 @@ namespace mad::core { StateId add_state(const std::shared_ptr &state); void add_transition(StateId state_id_from, StateId state_id_to, std::shared_ptr transition_condition); + void add_transition(StateId state_id_from, StateId state_id_to, std::vector> transition_conditions); void set_initial_state(StateId state_id); void control() override; + StateId get_previous_state_id(); + private: StateId m_current_state_id = -1; + StateId m_previous_state_id = -1; std::vector> m_states; std::vector>> m_transitions; std::shared_ptr m_dispatcher; @@ -32,17 +36,20 @@ namespace mad::core { }; struct Transition : EventHandler { + std::vector> m_conditions; + public: Transition(StateMachine *m_state_machine, StateMachine::StateId current_state, StateMachine::StateId next_state, std::shared_ptr m_condition); + Transition(StateMachine *m_state_machine, StateMachine::StateId current_state, StateMachine::StateId next_state, std::vector> m_conditions); std::unordered_set handled_types() override; void handle(const Event &event) override; bool is_active = false; + int cnt = 0; private: StateMachine *m_state_machine; StateMachine::StateId current_state; StateMachine::StateId next_state; - std::shared_ptr m_condition; }; }// namespace mad::core diff --git a/core/event/management/handler/CollisionHandler.cpp b/core/event/management/handler/CollisionHandler.cpp index 1c80ba1..569f9ab 100644 --- a/core/event/management/handler/CollisionHandler.cpp +++ b/core/event/management/handler/CollisionHandler.cpp @@ -14,7 +14,7 @@ void mad::core::CollisionHandler::handle(const mad::core::Event &event) { const auto &collision = const_cast_to(event); Entity::Id id_A = collision.first_object_id; Entity::Id id_B = collision.second_object_id; -// SPDLOG_INFO("handle collision {0} {1}", id_A, id_B); + SPDLOG_INFO("handle collision {0} {1}", id_A, id_B); } std::unordered_set mad::core::CollisionHandler::handled_types() { return {Event::Type::Collision}; diff --git a/core/event/physics/Collision.cpp b/core/event/physics/Collision.cpp index cc9d138..b932ed2 100644 --- a/core/event/physics/Collision.cpp +++ b/core/event/physics/Collision.cpp @@ -1,4 +1,5 @@ #include "Collision.hpp" +#include "spdlog/spdlog.h" mad::core::Collision::Collision(int new_first_object_id, int new_second_object_id) : Event(Event::Type::Collision), first_object_id(new_first_object_id), second_object_id(new_second_object_id) { - + //SPDLOG_INFO("handle collision {0} {1}", first_object_id, second_object_id); } diff --git a/core/event/physics/Death.cpp b/core/event/physics/Death.cpp new file mode 100644 index 0000000..bc3d6d2 --- /dev/null +++ b/core/event/physics/Death.cpp @@ -0,0 +1,3 @@ +#include "Death.hpp" +mad::core::Death::Death(int entity_id) : Event(Event::Type::Death), entity_id(entity_id) { +} diff --git a/core/event/physics/Death.hpp b/core/event/physics/Death.hpp new file mode 100644 index 0000000..ee74d70 --- /dev/null +++ b/core/event/physics/Death.hpp @@ -0,0 +1,17 @@ +#ifndef MAD_DEATH_HPP +#define MAD_DEATH_HPP + +#include "event/Event.hpp" +namespace mad::core { + + struct Death : public Event { + explicit Death(int entity_id); + + const int entity_id; + }; + +} + + + +#endif//MAD_DEATH_HPP diff --git a/core/event/physics/SensorCollision.cpp b/core/event/physics/SensorCollision.cpp new file mode 100644 index 0000000..24ec6bb --- /dev/null +++ b/core/event/physics/SensorCollision.cpp @@ -0,0 +1,5 @@ +#include "SensorCollision.hpp" +#include "spdlog/spdlog.h" +mad::core::SensorCollision::SensorCollision(int m_id) : Event(Event::Type::SensorCollision), m_id(m_id) { + //SPDLOG_INFO("sensor {}", m_id); +} diff --git a/core/event/physics/SensorCollision.hpp b/core/event/physics/SensorCollision.hpp new file mode 100644 index 0000000..762bb90 --- /dev/null +++ b/core/event/physics/SensorCollision.hpp @@ -0,0 +1,15 @@ +#ifndef MAD_SENSORCOLLISION_HPP +#define MAD_SENSORCOLLISION_HPP + +#include "event/Event.hpp" +namespace mad::core { + + struct SensorCollision : public Event { + explicit SensorCollision(int m_id); + + const int m_id; + }; + +} + +#endif//MAD_SENSORCOLLISION_HPP diff --git a/core/event/physics/SensorCollisionEnd.cpp b/core/event/physics/SensorCollisionEnd.cpp new file mode 100644 index 0000000..7da112c --- /dev/null +++ b/core/event/physics/SensorCollisionEnd.cpp @@ -0,0 +1,3 @@ +#include "SensorCollisionEnd.hpp" +mad::core::SensorCollisionEnd::SensorCollisionEnd(int m_id) : Event(Event::Type::SensorCollisionEnd), m_id(m_id) { +} diff --git a/core/event/physics/SensorCollisionEnd.hpp b/core/event/physics/SensorCollisionEnd.hpp new file mode 100644 index 0000000..6b936b1 --- /dev/null +++ b/core/event/physics/SensorCollisionEnd.hpp @@ -0,0 +1,16 @@ +#ifndef MAD_SENSORCOLLISIONEND_HPP +#define MAD_SENSORCOLLISIONEND_HPP + +#include "event/Event.hpp" +namespace mad::core { + + struct SensorCollisionEnd : public Event { + explicit SensorCollisionEnd(int m_id); + + const int m_id; + }; + +} + + +#endif//MAD_SENSORCOLLISIONEND_HPP diff --git a/core/event/physics/TakeDamage.cpp b/core/event/physics/TakeDamage.cpp new file mode 100644 index 0000000..bcda05c --- /dev/null +++ b/core/event/physics/TakeDamage.cpp @@ -0,0 +1,5 @@ +#include "TakeDamage.hpp" + +mad::core::TakeDamage::TakeDamage(int entity_id) : Event(Event::Type::TakeDamage), entity_id(entity_id) { + //SPDLOG_INFO("handle collision {0} {1}", first_object_id, second_object_id); +} diff --git a/core/event/physics/TakeDamage.hpp b/core/event/physics/TakeDamage.hpp new file mode 100644 index 0000000..c0a0b33 --- /dev/null +++ b/core/event/physics/TakeDamage.hpp @@ -0,0 +1,19 @@ +#ifndef MAD_TAKEDAMAGE_HPP +#define MAD_TAKEDAMAGE_HPP + +#include + + +namespace mad::core { + + struct TakeDamage : public Event { + explicit TakeDamage(int entity_id); + + const int entity_id; + }; + +} + + + +#endif//MAD_TAKEDAMAGE_HPP diff --git a/core/loader/LevelLoaderFromFile.cpp b/core/loader/LevelLoaderFromFile.cpp index 056ea07..6cd2e05 100644 --- a/core/loader/LevelLoaderFromFile.cpp +++ b/core/loader/LevelLoaderFromFile.cpp @@ -1,10 +1,13 @@ #include "LevelLoaderFromFile.hpp" -#include #include "event/management/condition/KeyDownCondition.hpp" #include "event/management/condition/KeyPressedCondition.hpp" #include "event/management/condition/TimerCondition.hpp" #include "event/management/condition/TrueCondition.hpp" +#include "event/management/controller/statemachine/EnemyStateMachine.hpp" +#include "event/management/controller/statemachine/HeroStateMachine.hpp" #include "event/management/controller/statemachine/StateMachine.hpp" +#include <../../game/mobs/hero/Hero.hpp> +#include #include @@ -19,7 +22,7 @@ namespace mad::core { std::unique_ptr LevelLoaderFromFile::load(std::shared_ptr global_dispatcher, std::shared_ptr system_listener) { - auto level_dispatcher = std::make_shared(); + level_dispatcher = std::make_shared(); auto world = std::make_shared(*level_dispatcher); @@ -29,20 +32,31 @@ namespace mad::core { Camera::FollowType camera_type = m_config_json["camera"]["follow_type"] == "forward" ? Camera::FollowType::Forward : Camera::FollowType::Backward; float minimal_distance = m_config_json["camera"]["minimal_distance"]; + float zoom = m_config_json["camera"]["zoom"]; + float part_of_window = m_config_json["camera"]["part_of_window"]; +#if defined(DEBUG_MODE) auto camera = std::make_shared(camera_position, world, true); +#else + auto camera = std::make_shared(camera_position, world, false); +#endif + controllers = {std::make_shared( + camera)}; + + //Entity::Id hero_id = create_world(world); auto keys = create_world(world); - camera->turn_on(*level_dispatcher, keys[LevelLoaderFromFile::IdKeys::Hero], camera_smoothness, camera_type, minimal_distance); + camera->turn_on(*level_dispatcher, keys[LevelLoaderFromFile::IdKeys::Hero], camera_smoothness, + camera_type, minimal_distance, part_of_window); level_dispatcher->registry(camera); - level_dispatcher->registry(std::make_shared(world, keys[LevelLoaderFromFile::IdKeys::Hero])); + //level_dispatcher->registry(std::make_shared(world, keys[LevelLoaderFromFile::IdKeys::Hero])); /* std::vector> controllers { std::make_shared(camera) };*/ - ///State Machine + /*///State Machine struct C1 : mad::core::Controller { void control() override { //SPDLOG_DEBUG("controller 1"); @@ -62,7 +76,10 @@ namespace mad::core { machine->set_initial_state(0); std::vector> controllers{machine, std::make_shared( - camera)}; + camera)};*/ + + camera->set_zoom(zoom); + auto level_runner = std::make_unique( system_listener, @@ -71,8 +88,7 @@ namespace mad::core { global_dispatcher, level_dispatcher, world, - controllers - ); + controllers); level_dispatcher->registry(std::make_shared(*level_runner, std::make_shared(keys[LevelLoaderFromFile::IdKeys::Hero], keys[LevelLoaderFromFile::IdKeys::FinishBlock]))); level_dispatcher->registry(std::make_shared(*level_runner)); @@ -86,12 +102,13 @@ namespace mad::core { float current_position_x = object_size / 2; float current_position_y = object_size / 2; std::unordered_map keys; + Entity::Id hero_id = 0; std::string map_line; create_background(world); while (std::getline(m_level_map, map_line)) { - for (char object: map_line) { + for (char object : map_line) { switch (m_objects[object]) { case Objects::UnstableBlock: { create_block(world, @@ -149,6 +166,13 @@ namespace mad::core { m_objects[object]); break; } + case Objects::Decoration3: { + create_decoration(world, + {current_position_x, + current_position_y}, + m_objects[object]); + break; + } case Objects::FinishBlock: { keys[LevelLoaderFromFile::IdKeys::FinishBlock] = create_finish_block( world, @@ -157,15 +181,16 @@ namespace mad::core { break; } case Objects::Hero: { - keys[LevelLoaderFromFile::IdKeys::Hero] = create_hero(world, - {current_position_x, - current_position_y}); + // Hero hero(world, {current_position_x, current_position_y}, m_config_json, level_dispatcher, controllers); + hero_id = create_hero(world, {current_position_x, current_position_y}); + r_hero_id = keys[LevelLoaderFromFile::IdKeys::Hero] = hero_id; break; } case Objects::Enemy1: { break; } case Objects::Enemy2: { + create_mob(world, {current_position_x, current_position_y}); break; } case Objects::Empty: { @@ -225,8 +250,7 @@ namespace mad::core { position, 0, image_storage, - is_stable - ); + is_stable); } void LevelLoaderFromFile::create_decoration(std::shared_ptr world, Vec2d position, Objects object) { @@ -251,7 +275,15 @@ namespace mad::core { delta_y = m_config_json["decoration"]["decoration_02"]["delta_y"]; break; } + case Objects::Decoration3 : { + source /= m_config_json["decoration"]["decoration_03"]["source"]; + decoration_scale = m_config_json["decoration"]["decoration_03"]["scale"]; + delta_x = m_config_json["decoration"]["decoration_03"]["delta_x"]; + delta_y = m_config_json["decoration"]["decoration_03"]["delta_y"]; + break; + } } + decoration_scale *= static_cast(m_config_json["camera"]["zoom"]); auto image_storage = std::make_shared( std::unordered_map>( @@ -284,34 +316,197 @@ namespace mad::core { image_storage = std::make_shared( std::unordered_map>( - {{ImageStorage::TypeAction::Idle, - std::make_shared( - source / m_config_json["hero"]["animated"]["actions"]["idle"]["source"], - m_config_json["hero"]["animated"]["actions"]["idle"]["delta_time"], - physical_size_width, physical_size_height, size_scale, - delta_x, delta_y) - }, + {{ImageStorage::TypeAction::Jump, + std::make_shared( + source / m_config_json["hero"]["animated"]["actions"]["jump"]["source"], + + m_config_json["hero"]["animated"]["actions"]["jump"]["delta_time"], + physical_size_width, physical_size_height, size_scale, + delta_x, delta_y)}, + {ImageStorage::TypeAction::Idle, + std::make_shared( + source / m_config_json["hero"]["animated"]["actions"]["idle"]["source"], + + m_config_json["hero"]["animated"]["actions"]["idle"]["delta_time"], + physical_size_width, physical_size_height, size_scale, + delta_x, delta_y)}, {ImageStorage::TypeAction::Run, - std::make_shared( - source / m_config_json["hero"]["animated"]["actions"]["run"]["source"], - m_config_json["hero"]["animated"]["actions"]["run"]["delta_time"], - physical_size_width, physical_size_height, size_scale, - delta_x, delta_y) - }} - ) - ); + std::make_shared( + source / m_config_json["hero"]["animated"]["actions"]["run"]["source"], + + m_config_json["hero"]["animated"]["actions"]["run"]["delta_time"], + physical_size_width, physical_size_height, size_scale, + delta_x, delta_y)}, + {ImageStorage::TypeAction::Fly_up, + std::make_shared( + source / m_config_json["hero"]["animated"]["actions"]["fly_up"]["source"], + + m_config_json["hero"]["animated"]["actions"]["fly_up"]["delta_time"], + physical_size_width, physical_size_height, size_scale, + delta_x, delta_y)}, + {ImageStorage::TypeAction::Fall, + std::make_shared( + source / m_config_json["hero"]["animated"]["actions"]["fall"]["source"], + + m_config_json["hero"]["animated"]["actions"]["fall"]["delta_time"], + physical_size_width, physical_size_height, size_scale, + delta_x, delta_y)}, + {ImageStorage::TypeAction::Attack_1_beg, + std::make_shared( + source / m_config_json["hero"]["animated"]["actions"]["attack_1_beg"]["source"], + + m_config_json["hero"]["animated"]["actions"]["attack_1_beg"]["delta_time"], + physical_size_width, physical_size_height, size_scale, + delta_x, delta_y)}, + {ImageStorage::TypeAction::Attack_1_end, + std::make_shared( + source / m_config_json["hero"]["animated"]["actions"]["attack_1_end"]["source"], + + m_config_json["hero"]["animated"]["actions"]["attack_1_end"]["delta_time"], + physical_size_width, physical_size_height, size_scale, + delta_x, delta_y)}, + {ImageStorage::TypeAction::Attack_2_beg, + std::make_shared( + source / m_config_json["hero"]["animated"]["actions"]["attack_2_beg"]["source"], + + m_config_json["hero"]["animated"]["actions"]["attack_2_beg"]["delta_time"], + physical_size_width, physical_size_height, size_scale, + delta_x, delta_y)}, + {ImageStorage::TypeAction::Attack_2_end, + std::make_shared( + source / m_config_json["hero"]["animated"]["actions"]["attack_2_end"]["source"], + + m_config_json["hero"]["animated"]["actions"]["attack_2_end"]["delta_time"], + physical_size_width, physical_size_height, size_scale, + delta_x, delta_y)}, + {ImageStorage::TypeAction::Attack_3_beg, + std::make_shared( + source / m_config_json["hero"]["animated"]["actions"]["attack_3_beg"]["source"], + + m_config_json["hero"]["animated"]["actions"]["attack_3_beg"]["delta_time"], + physical_size_width, physical_size_height, size_scale, + delta_x, delta_y)}, + {ImageStorage::TypeAction::Attack_3_end, + std::make_shared( + source / m_config_json["hero"]["animated"]["actions"]["attack_3_end"]["source"], + + m_config_json["hero"]["animated"]["actions"]["attack_3_end"]["delta_time"], + physical_size_width, physical_size_height, size_scale, + delta_x, delta_y)}, + {ImageStorage::TypeAction::Hurt, + std::make_shared( + source / m_config_json["hero"]["animated"]["actions"]["hurt"]["source"], + + m_config_json["hero"]["animated"]["actions"]["hurt"]["delta_time"], + physical_size_width, physical_size_height, size_scale, + delta_x, delta_y)}, + {ImageStorage::TypeAction::Die, + std::make_shared( + source / m_config_json["hero"]["animated"]["actions"]["die"]["source"], + + m_config_json["hero"]["animated"]["actions"]["die"]["delta_time"], + physical_size_width, physical_size_height, size_scale, + delta_x, delta_y)} + })); hero_id = world->create_physical_entity( 2, position, 0, image_storage, - false, false - ); + false, false, + 0x0004, 0x0002); + + /// add sensor + auto m_entity = cast_to_or_null(world->get_storage().get_entity(hero_id)); + m_entity->add_sensor({0, 6}, 2.65, 0.05); + + float m_impulse = 2000; + float horizontal_velocity = 20; + + auto machine = std::make_shared(world, position, hero_id, level_dispatcher, m_impulse, horizontal_velocity); + controllers.push_back(machine); return hero_id; } + + void LevelLoaderFromFile::create_mob(std::shared_ptr world, Vec2d position) { + std::filesystem::path source(m_config_json["animated_resources"]); + source /= m_config_json["enemy"]["source"]; + + std::shared_ptr image_storage; + + float physical_size_width = m_config_json["enemy"]["animated"]["size_width"]; + float physical_size_height = m_config_json["enemy"]["animated"]["size_height"]; + float size_scale = m_config_json["enemy"]["animated"]["size_scale"]; + float delta_x = m_config_json["enemy"]["animated"]["delta_x"]; + float delta_y = m_config_json["enemy"]["animated"]["delta_y"]; + + + image_storage = std::make_shared( + std::unordered_map>( + {{ImageStorage::TypeAction::Idle, + std::make_shared( + source / m_config_json["enemy"]["animated"]["actions"]["idle"]["source"], + + m_config_json["enemy"]["animated"]["actions"]["idle"]["delta_time"], + physical_size_width, physical_size_height, size_scale, + delta_x, delta_y)}, + {ImageStorage::TypeAction::Run, + std::make_shared( + source / m_config_json["enemy"]["animated"]["actions"]["run"]["source"], + + m_config_json["enemy"]["animated"]["actions"]["run"]["delta_time"], + physical_size_width, physical_size_height, size_scale, + delta_x, delta_y)}, + {ImageStorage::TypeAction::Attack_1_beg, + std::make_shared( + source / m_config_json["enemy"]["animated"]["actions"]["attack_beg"]["source"], + + m_config_json["enemy"]["animated"]["actions"]["attack_beg"]["delta_time"], + physical_size_width, physical_size_height, size_scale, + delta_x, delta_y)}, + {ImageStorage::TypeAction::Attack_1_end, + std::make_shared( + source / m_config_json["enemy"]["animated"]["actions"]["attack_end"]["source"], + + m_config_json["enemy"]["animated"]["actions"]["attack_end"]["delta_time"], + physical_size_width, physical_size_height, size_scale, + delta_x, delta_y)}, + {ImageStorage::TypeAction::Die, + std::make_shared( + source / m_config_json["enemy"]["animated"]["actions"]["die"]["source"], + + m_config_json["enemy"]["animated"]["actions"]["die"]["delta_time"], + physical_size_width, physical_size_height, size_scale, + delta_x, delta_y)}, + {ImageStorage::TypeAction::Hurt, + std::make_shared( + source / m_config_json["enemy"]["animated"]["actions"]["hurt"]["source"], + + m_config_json["enemy"]["animated"]["actions"]["hurt"]["delta_time"], + physical_size_width, physical_size_height, size_scale, + delta_x, delta_y)} + })); + + Entity::Id enemy_id = world->create_physical_entity( + 2, + position, + 0, + image_storage, + false, false, + 0x0004, 0x0002); + + + float m_impulse = 2000; + float horizontal_velocity = 5.5f; + auto m_entity = cast_to_or_null(world->get_storage().get_entity(enemy_id)); + m_entity->add_sensor({6, 0}, 2.65, 0.05); + + auto machine = std::make_shared(world, position, enemy_id, level_dispatcher, m_impulse, horizontal_velocity, r_hero_id); + controllers.push_back(machine); + } Entity::Id LevelLoaderFromFile::create_finish_block(std::shared_ptr world, Vec2d position, float block_size) { std::filesystem::path source(m_config_json["static_resources"]); source /= static_cast(m_config_json["texture"]["finish_block"]); @@ -321,16 +516,14 @@ namespace mad::core { {{ImageStorage::TypeAction::Idle, std::make_shared(source, block_size, block_size, - StaticImage::TransformType::Fit) - }})); + StaticImage::TransformType::Fit)}})); return world->create_physical_entity( 1, position, 0, image_storage, - true - ); + true); } void LevelLoaderFromFile::create_background(std::shared_ptr world) { @@ -344,18 +537,14 @@ namespace mad::core { {{ImageStorage::TypeAction::Idle, std::make_shared( source, - parallax_ratios, - m_config_json["background"]["scale"] - ) - }} - ) - ); + parallax_ratios) + }})); world->create_viewable_entity( -1, {0, 0}, 0, - image_storage - ); + image_storage); } -} \ No newline at end of file + +}// namespace mad::core diff --git a/core/loader/LevelLoaderFromFile.hpp b/core/loader/LevelLoaderFromFile.hpp index c03338b..a368d01 100644 --- a/core/loader/LevelLoaderFromFile.hpp +++ b/core/loader/LevelLoaderFromFile.hpp @@ -29,61 +29,7 @@ using json = nlohmann::json; namespace mad::core { - class ArrowController : public mad::core::EventHandler { - public: - explicit ArrowController(std::shared_ptr world, - mad::core::Entity::Id entity_id) - : m_world(std::move(world)), - m_entity_id(entity_id) {} - - void handle(const mad::core::Event &event) override { - //SPDLOG_INFO("handle arrow event"); - - auto make_move_intent = [](mad::core::Vec2d dir) { - return mad::core::LambdaIntent( - [=](mad::core::Entity &entity, mad::core::EventDispatcher &event_dispatcher) { - mad::core::cast_to(entity).move(dir); - }); - }; - - auto impulse = [](mad::core::Vec2d dir) { - return mad::core::LambdaIntent( - [=](mad::core::Entity &entity, mad::core::EventDispatcher &event_dispatcher) { - mad::core::cast_to(entity).apply_linear_impulse_to_center(dir, event_dispatcher); - }); - }; - - auto force = [](mad::core::Vec2d dir) { - return mad::core::LambdaIntent( - [=](mad::core::Entity &entity, mad::core::EventDispatcher &event_dispatcher) { - mad::core::cast_to(entity).apply_force_to_center(dir, event_dispatcher); - }); - }; - - if (event.type == mad::core::Event::Type::KeyPressed) { - const auto &keystroke = mad::core::const_cast_to(event); - if (keystroke.key_id == sf::Keyboard::Key::Space) { - m_world->manipulate_entity_id(m_entity_id, impulse(mad::core::Vec2d{0.0f, -200000.0f})); - } - } else if (event.type == mad::core::Event::Type::KeyHeld) { - const auto &keystroke = mad::core::const_cast_to(event); - if (keystroke.key_id == sf::Keyboard::Key::Right) { - m_world->manipulate_entity_id(m_entity_id, force(mad::core::Vec2d{100000.0f, 0.0f})); - } - if (keystroke.key_id == sf::Keyboard::Key::Left) { - m_world->manipulate_entity_id(m_entity_id, force(mad::core::Vec2d{-100000.0f, 0.0f})); - } - } - } - - std::unordered_set handled_types() override { - return {mad::core::Event::Type::KeyPressed, mad::core::Event::Type::KeyHeld}; - } - private: - std::shared_ptr m_world; - mad::core::Entity::Id m_entity_id; - }; class LevelLoaderFromFile : public LevelLoader { @@ -110,6 +56,8 @@ namespace mad::core { Entity::Id create_hero(std::shared_ptr world, Vec2d position); + void create_mob(std::shared_ptr world, Vec2d position); + void create_background(std::shared_ptr world); Entity::Id create_finish_block(std::shared_ptr world, Vec2d position, float block_size); @@ -127,6 +75,7 @@ namespace mad::core { SeparateBlock, Decoration1, Decoration2, + Decoration3, Hero, Enemy1, Enemy2, @@ -139,6 +88,10 @@ namespace mad::core { std::ifstream m_level_map; + std::vector> controllers; + + std::shared_ptr level_dispatcher; + std::unordered_map m_objects = { {'.', Objects::Empty}, {'#', Objects::GroundBlock}, @@ -150,10 +103,13 @@ namespace mad::core { {'+', Objects::SeparateBlock}, {'*', Objects::Decoration1}, {'&', Objects::Decoration2}, + {'^', Objects::Decoration3}, {'H', Objects::Hero}, {'Z', Objects::Enemy1}, {'E', Objects::Enemy2} }; + + int r_hero_id; }; } diff --git a/core/loader/LevelLoaderFromServer.cpp b/core/loader/LevelLoaderFromServer.cpp new file mode 100644 index 0000000..ed7e74d --- /dev/null +++ b/core/loader/LevelLoaderFromServer.cpp @@ -0,0 +1,547 @@ +#include "LevelLoaderFromServer.hpp" +#include "event/management/condition/KeyDownCondition.hpp" +#include "event/management/condition/KeyPressedCondition.hpp" +#include "event/management/condition/TimerCondition.hpp" +#include "event/management/condition/TrueCondition.hpp" +#include "event/management/controller/statemachine/EnemyStateMachine.hpp" +#include "event/management/controller/statemachine/HeroStateMachine.hpp" +#include "event/management/controller/statemachine/StateMachine.hpp" +#include <../../game/mobs/hero/Hero.hpp> +#include + +#include + +namespace mad::core { + + LevelLoaderFromServer::LevelLoaderFromServer(std::string map, json config) : m_level_map(std::move(map)), m_config_json(std::move(config)) { } + + std::unique_ptr LevelLoaderFromServer::load(std::shared_ptr global_dispatcher, + std::shared_ptr system_listener) { + level_dispatcher = std::make_shared(); + + auto world = std::make_shared(*level_dispatcher); + + Vec2d camera_position = {m_config_json["camera"]["position"]["x"], + m_config_json["camera"]["position"]["y"]}; + float camera_smoothness = m_config_json["camera"]["smoothness"]; + Camera::FollowType camera_type = m_config_json["camera"]["follow_type"] == "forward" ? + Camera::FollowType::Forward : Camera::FollowType::Backward; + float minimal_distance = m_config_json["camera"]["minimal_distance"]; + float zoom = m_config_json["camera"]["zoom"]; + float part_of_window = m_config_json["camera"]["part_of_window"]; + +#if defined(DEBUG_MODE) + auto camera = std::make_shared(camera_position, world, true); +#else + auto camera = std::make_shared(camera_position, world, false); +#endif + + controllers = {std::make_shared( + camera)}; + + + //Entity::Id hero_id = create_world(world); + auto keys = create_world(world); + + camera->turn_on(*level_dispatcher, keys[LevelLoaderFromServer::IdKeys::Hero], camera_smoothness, + camera_type, minimal_distance, part_of_window); + level_dispatcher->registry(camera); + //level_dispatcher->registry(std::make_shared(world, keys[LevelLoaderFromServer::IdKeys::Hero])); + + /* std::vector> controllers { + std::make_shared(camera) + };*/ + + /*///State Machine + struct C1 : mad::core::Controller { + void control() override { + //SPDLOG_DEBUG("controller 1"); + }; + }; + struct C2 : mad::core::Controller { + void control() override { + //SPDLOG_DEBUG("controller 2"); + }; + }; + auto machine = std::make_shared( + std::shared_ptr(level_dispatcher)); + machine->add_state(std::make_shared()); + machine->add_state(std::make_shared()); + machine->add_transition(0, 1, std::make_shared(1)); + machine->add_transition(1, 0, std::make_shared(2)); + machine->set_initial_state(0); + std::vector> controllers{machine, + std::make_shared( + camera)};*/ + + camera->set_zoom(zoom); + + + auto level_runner = std::make_unique( + system_listener, + std::make_unique(), + camera, + global_dispatcher, + level_dispatcher, + world, + controllers); + + level_dispatcher->registry(std::make_shared(*level_runner, std::make_shared(keys[LevelLoaderFromServer::IdKeys::Hero], keys[LevelLoaderFromServer::IdKeys::FinishBlock]))); + level_dispatcher->registry(std::make_shared(*level_runner)); + + return level_runner; + } + + std::unordered_map LevelLoaderFromServer::create_world(std::shared_ptr world) { + std::stringstream m_level_map_stream; + m_level_map_stream << m_level_map; + float object_size = m_config_json["block"]; + float current_position_x = object_size / 2; + float current_position_y = object_size / 2; + std::unordered_map keys; + Entity::Id hero_id = 0; + std::string map_line; + + create_background(world); + + while (std::getline(m_level_map_stream, map_line)) { + for (char object : map_line) { + switch (m_objects[object]) { + case Objects::UnstableBlock: { + create_block(world, + {current_position_x, + current_position_y}, + object_size, false, m_objects[object]); + break; + } + case Objects::GroundBlock: { + create_block(world, + {current_position_x, + current_position_y}, + object_size, true, m_objects[object]); + break; + } + case Objects::BeginBlock: { + create_block(world, + {current_position_x, + current_position_y}, + object_size, true, m_objects[object]); + break; + } + case Objects::MiddleBlock: { + create_block(world, + {current_position_x, + current_position_y}, + object_size, true, m_objects[object]); + break; + } + case Objects::EndBlock: { + create_block(world, + {current_position_x, + current_position_y}, + object_size, true, m_objects[object]); + break; + } + case Objects::SeparateBlock: { + create_block(world, + {current_position_x, + current_position_y}, + object_size, true, m_objects[object]); + break; + } + case Objects::Decoration1: { + create_decoration(world, + {current_position_x, + current_position_y}, + m_objects[object]); + break; + } + case Objects::Decoration2: { + create_decoration(world, + {current_position_x, + current_position_y}, + m_objects[object]); + break; + } + case Objects::Decoration3: { + create_decoration(world, + {current_position_x, + current_position_y}, + m_objects[object]); + break; + } + case Objects::FinishBlock: { + keys[LevelLoaderFromServer::IdKeys::FinishBlock] = create_finish_block( + world, + {current_position_x, current_position_y}, + object_size); + break; + } + case Objects::Hero: { + // Hero hero(world, {current_position_x, current_position_y}, m_config_json, level_dispatcher, controllers); + hero_id = create_hero(world, {current_position_x, current_position_y}); + r_hero_id = keys[LevelLoaderFromServer::IdKeys::Hero] = hero_id; + break; + } + case Objects::Enemy1: { + break; + } + case Objects::Enemy2: { + create_mob(world, {current_position_x, current_position_y}); + break; + } + case Objects::Empty: { + break; + } + } + current_position_x += object_size; + } + current_position_y += object_size; + current_position_x = object_size / 2; + } + return keys; + } + + void LevelLoaderFromServer::create_block(std::shared_ptr world, Vec2d position, + float block_size, bool is_stable, Objects object) { + + std::filesystem::path source(m_config_json["static_resources"]); + + switch (object) { + case Objects::UnstableBlock: { + source /= m_config_json["texture"]["unstable_block"]; + break; + } + case Objects::GroundBlock: { + source /= m_config_json["texture"]["ground_block"]; + break; + } + case Objects::BeginBlock: { + source /= m_config_json["texture"]["begin_block"]; + break; + } + case Objects::MiddleBlock: { + source /= m_config_json["texture"]["middle_block"]; + break; + } + case Objects::EndBlock: { + source /= m_config_json["texture"]["end_block"]; + break; + } + case Objects::SeparateBlock: { + source /= m_config_json["texture"]["separate_block"]; + break; + } + } + + auto image_storage = std::make_shared( + std::unordered_map>( + {{ImageStorage::TypeAction::Idle, + std::make_shared(source, block_size, + block_size, + StaticImage::TransformType::Fit) + }})); + + Entity::Id square_id = world->create_physical_entity( + 1, + position, + 0, + image_storage, + is_stable); + } + + void LevelLoaderFromServer::create_decoration(std::shared_ptr world, Vec2d position, Objects object) { + std::filesystem::path source(m_config_json["decoration_resources"]); + + float decoration_scale = 1; + float delta_x = 0; + float delta_y = 0; + + switch (object) { + case Objects::Decoration1 : { + source /= m_config_json["decoration"]["decoration_01"]["source"]; + decoration_scale = m_config_json["decoration"]["decoration_01"]["scale"]; + delta_x = m_config_json["decoration"]["decoration_01"]["delta_x"]; + delta_y = m_config_json["decoration"]["decoration_01"]["delta_y"]; + break; + } + case Objects::Decoration2 : { + source /= m_config_json["decoration"]["decoration_02"]["source"]; + decoration_scale = m_config_json["decoration"]["decoration_02"]["scale"]; + delta_x = m_config_json["decoration"]["decoration_02"]["delta_x"]; + delta_y = m_config_json["decoration"]["decoration_02"]["delta_y"]; + break; + } + case Objects::Decoration3 : { + source /= m_config_json["decoration"]["decoration_03"]["source"]; + decoration_scale = m_config_json["decoration"]["decoration_03"]["scale"]; + delta_x = m_config_json["decoration"]["decoration_03"]["delta_x"]; + delta_y = m_config_json["decoration"]["decoration_03"]["delta_y"]; + break; + } + } + decoration_scale *= static_cast(m_config_json["camera"]["zoom"]); + + auto image_storage = std::make_shared( + std::unordered_map>( + {{ImageStorage::TypeAction::Idle, + std::make_shared(source, decoration_scale, delta_x, delta_y) + }})); + + Entity::Id decoration_id = world->create_viewable_entity( + 0, + position, + 0, + image_storage + ); + } + + Entity::Id LevelLoaderFromServer::create_hero(std::shared_ptr world, Vec2d position) { + std::filesystem::path source(m_config_json["animated_resources"]); + source /= m_config_json["hero"]["source"]; + + Entity::Id hero_id = 0; + + std::shared_ptr image_storage; + + float physical_size_width = m_config_json["hero"]["animated"]["size_width"]; + float physical_size_height = m_config_json["hero"]["animated"]["size_height"]; + float size_scale = m_config_json["hero"]["animated"]["size_scale"]; + float delta_x = m_config_json["hero"]["animated"]["delta_x"]; + float delta_y = m_config_json["hero"]["animated"]["delta_y"]; + + + image_storage = std::make_shared( + std::unordered_map>( + {{ImageStorage::TypeAction::Jump, + std::make_shared( + source / m_config_json["hero"]["animated"]["actions"]["jump"]["source"], + + m_config_json["hero"]["animated"]["actions"]["jump"]["delta_time"], + physical_size_width, physical_size_height, size_scale, + delta_x, delta_y)}, + {ImageStorage::TypeAction::Idle, + std::make_shared( + source / m_config_json["hero"]["animated"]["actions"]["idle"]["source"], + + m_config_json["hero"]["animated"]["actions"]["idle"]["delta_time"], + physical_size_width, physical_size_height, size_scale, + delta_x, delta_y)}, + {ImageStorage::TypeAction::Run, + std::make_shared( + source / m_config_json["hero"]["animated"]["actions"]["run"]["source"], + + m_config_json["hero"]["animated"]["actions"]["run"]["delta_time"], + physical_size_width, physical_size_height, size_scale, + delta_x, delta_y)}, + {ImageStorage::TypeAction::Fly_up, + std::make_shared( + source / m_config_json["hero"]["animated"]["actions"]["fly_up"]["source"], + + m_config_json["hero"]["animated"]["actions"]["fly_up"]["delta_time"], + physical_size_width, physical_size_height, size_scale, + delta_x, delta_y)}, + {ImageStorage::TypeAction::Fall, + std::make_shared( + source / m_config_json["hero"]["animated"]["actions"]["fall"]["source"], + + m_config_json["hero"]["animated"]["actions"]["fall"]["delta_time"], + physical_size_width, physical_size_height, size_scale, + delta_x, delta_y)}, + {ImageStorage::TypeAction::Attack_1_beg, + std::make_shared( + source / m_config_json["hero"]["animated"]["actions"]["attack_1_beg"]["source"], + + m_config_json["hero"]["animated"]["actions"]["attack_1_beg"]["delta_time"], + physical_size_width, physical_size_height, size_scale, + delta_x, delta_y)}, + {ImageStorage::TypeAction::Attack_1_end, + std::make_shared( + source / m_config_json["hero"]["animated"]["actions"]["attack_1_end"]["source"], + + m_config_json["hero"]["animated"]["actions"]["attack_1_end"]["delta_time"], + physical_size_width, physical_size_height, size_scale, + delta_x, delta_y)}, + {ImageStorage::TypeAction::Attack_2_beg, + std::make_shared( + source / m_config_json["hero"]["animated"]["actions"]["attack_2_beg"]["source"], + + m_config_json["hero"]["animated"]["actions"]["attack_2_beg"]["delta_time"], + physical_size_width, physical_size_height, size_scale, + delta_x, delta_y)}, + {ImageStorage::TypeAction::Attack_2_end, + std::make_shared( + source / m_config_json["hero"]["animated"]["actions"]["attack_2_end"]["source"], + + m_config_json["hero"]["animated"]["actions"]["attack_2_end"]["delta_time"], + physical_size_width, physical_size_height, size_scale, + delta_x, delta_y)}, + {ImageStorage::TypeAction::Attack_3_beg, + std::make_shared( + source / m_config_json["hero"]["animated"]["actions"]["attack_3_beg"]["source"], + + m_config_json["hero"]["animated"]["actions"]["attack_3_beg"]["delta_time"], + physical_size_width, physical_size_height, size_scale, + delta_x, delta_y)}, + {ImageStorage::TypeAction::Attack_3_end, + std::make_shared( + source / m_config_json["hero"]["animated"]["actions"]["attack_3_end"]["source"], + + m_config_json["hero"]["animated"]["actions"]["attack_3_end"]["delta_time"], + physical_size_width, physical_size_height, size_scale, + delta_x, delta_y)}, + {ImageStorage::TypeAction::Hurt, + std::make_shared( + source / m_config_json["hero"]["animated"]["actions"]["hurt"]["source"], + + m_config_json["hero"]["animated"]["actions"]["hurt"]["delta_time"], + physical_size_width, physical_size_height, size_scale, + delta_x, delta_y)}, + {ImageStorage::TypeAction::Die, + std::make_shared( + source / m_config_json["hero"]["animated"]["actions"]["die"]["source"], + + m_config_json["hero"]["animated"]["actions"]["die"]["delta_time"], + physical_size_width, physical_size_height, size_scale, + delta_x, delta_y)} + })); + + hero_id = world->create_physical_entity( + 2, + position, + 0, + image_storage, + false, false, + 0x0004, 0x0002); + + /// add sensor + auto m_entity = cast_to_or_null(world->get_storage().get_entity(hero_id)); + m_entity->add_sensor({0, 6}, 2.65, 0.05); + + float m_impulse = 2000; + float horizontal_velocity = 20; + + auto machine = std::make_shared(world, position, hero_id, level_dispatcher, m_impulse, horizontal_velocity); + controllers.push_back(machine); + + return hero_id; + } + + + void LevelLoaderFromServer::create_mob(std::shared_ptr world, Vec2d position) { + std::filesystem::path source(m_config_json["animated_resources"]); + source /= m_config_json["enemy"]["source"]; + + std::shared_ptr image_storage; + + float physical_size_width = m_config_json["enemy"]["animated"]["size_width"]; + float physical_size_height = m_config_json["enemy"]["animated"]["size_height"]; + float size_scale = m_config_json["enemy"]["animated"]["size_scale"]; + float delta_x = m_config_json["enemy"]["animated"]["delta_x"]; + float delta_y = m_config_json["enemy"]["animated"]["delta_y"]; + + + image_storage = std::make_shared( + std::unordered_map>( + {{ImageStorage::TypeAction::Idle, + std::make_shared( + source / m_config_json["enemy"]["animated"]["actions"]["idle"]["source"], + + m_config_json["enemy"]["animated"]["actions"]["idle"]["delta_time"], + physical_size_width, physical_size_height, size_scale, + delta_x, delta_y)}, + {ImageStorage::TypeAction::Run, + std::make_shared( + source / m_config_json["enemy"]["animated"]["actions"]["run"]["source"], + + m_config_json["enemy"]["animated"]["actions"]["run"]["delta_time"], + physical_size_width, physical_size_height, size_scale, + delta_x, delta_y)}, + {ImageStorage::TypeAction::Attack_1_beg, + std::make_shared( + source / m_config_json["enemy"]["animated"]["actions"]["attack_beg"]["source"], + + m_config_json["enemy"]["animated"]["actions"]["attack_beg"]["delta_time"], + physical_size_width, physical_size_height, size_scale, + delta_x, delta_y)}, + {ImageStorage::TypeAction::Attack_1_end, + std::make_shared( + source / m_config_json["enemy"]["animated"]["actions"]["attack_end"]["source"], + + m_config_json["enemy"]["animated"]["actions"]["attack_end"]["delta_time"], + physical_size_width, physical_size_height, size_scale, + delta_x, delta_y)}, + {ImageStorage::TypeAction::Die, + std::make_shared( + source / m_config_json["enemy"]["animated"]["actions"]["die"]["source"], + + m_config_json["enemy"]["animated"]["actions"]["die"]["delta_time"], + physical_size_width, physical_size_height, size_scale, + delta_x, delta_y)}, + {ImageStorage::TypeAction::Hurt, + std::make_shared( + source / m_config_json["enemy"]["animated"]["actions"]["hurt"]["source"], + + m_config_json["enemy"]["animated"]["actions"]["hurt"]["delta_time"], + physical_size_width, physical_size_height, size_scale, + delta_x, delta_y)} + })); + + Entity::Id enemy_id = world->create_physical_entity( + 2, + position, + 0, + image_storage, + false, false, + 0x0004, 0x0002); + + + float m_impulse = 2000; + float horizontal_velocity = 5.5f; + auto m_entity = cast_to_or_null(world->get_storage().get_entity(enemy_id)); + m_entity->add_sensor({6, 0}, 2.65, 0.05); + + auto machine = std::make_shared(world, position, enemy_id, level_dispatcher, m_impulse, horizontal_velocity, r_hero_id); + controllers.push_back(machine); + } + Entity::Id LevelLoaderFromServer::create_finish_block(std::shared_ptr world, Vec2d position, float block_size) { + std::filesystem::path source(m_config_json["static_resources"]); + source /= static_cast(m_config_json["texture"]["finish_block"]); + + auto image_storage = std::make_shared( + std::unordered_map>( + {{ImageStorage::TypeAction::Idle, + std::make_shared(source, block_size, + block_size, + StaticImage::TransformType::Fit)}})); + + return world->create_physical_entity( + 1, + position, + 0, + image_storage, + true); + } + + void LevelLoaderFromServer::create_background(std::shared_ptr world) { + std::filesystem::path source(m_config_json["background"]["source"]); + + std::shared_ptr image_storage; + std::vector parallax_ratios = m_config_json["background"]["parallax_ratios"]; + + image_storage = std::make_shared( + std::unordered_map>( + {{ImageStorage::TypeAction::Idle, + std::make_shared( + source, + parallax_ratios) + }})); + world->create_viewable_entity( + -1, + {0, 0}, + 0, + image_storage); + } + + +}// namespace mad::core diff --git a/core/loader/LevelLoaderFromServer.hpp b/core/loader/LevelLoaderFromServer.hpp new file mode 100644 index 0000000..0829ad8 --- /dev/null +++ b/core/loader/LevelLoaderFromServer.hpp @@ -0,0 +1,114 @@ +#ifndef MAD_LEVELLOADERFROMSERVER_HPP +#define MAD_LEVELLOADERFROMSERVER_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include +#include +#include +#include +#include +#include + +using json = nlohmann::json; + +namespace mad::core { + + + + + class LevelLoaderFromServer : public LevelLoader { + private: + enum class IdKeys { + Hero, + FinishBlock, + }; + + enum class Objects; + + public: + + explicit LevelLoaderFromServer(std::string map, json config); + + std::unique_ptr load( + std::shared_ptr global_dispatcher, + std::shared_ptr system_listener) override; + + std::unordered_map create_world(std::shared_ptr world); + + void create_block(std::shared_ptr world, Vec2d position, + float block_size, bool is_stable, Objects object); + + Entity::Id create_hero(std::shared_ptr world, Vec2d position); + + void create_mob(std::shared_ptr world, Vec2d position); + + void create_background(std::shared_ptr world); + + Entity::Id create_finish_block(std::shared_ptr world, Vec2d position, float block_size); + + void create_decoration(std::shared_ptr world, Vec2d position, Objects object); + + private: + enum class Objects { + UnstableBlock, + GroundBlock, + FinishBlock, + BeginBlock, + MiddleBlock, + EndBlock, + SeparateBlock, + Decoration1, + Decoration2, + Decoration3, + Hero, + Enemy1, + Enemy2, + Empty + }; + + json m_config_json; + + std::string m_level_map; + + std::vector> controllers; + + std::shared_ptr level_dispatcher; + + std::unordered_map m_objects = { + {'.', Objects::Empty}, + {'#', Objects::GroundBlock}, + {'@', Objects::UnstableBlock}, + {'F', Objects::FinishBlock}, + {'[', Objects::BeginBlock}, + {'_', Objects::MiddleBlock}, + {']', Objects::EndBlock}, + {'+', Objects::SeparateBlock}, + {'*', Objects::Decoration1}, + {'&', Objects::Decoration2}, + {'^', Objects::Decoration3}, + {'H', Objects::Hero}, + {'Z', Objects::Enemy1}, + {'E', Objects::Enemy2} + }; + + int r_hero_id; + }; +} + +#endif //MAD_LEVELLOADERFROMFILE_HPP diff --git a/core/runner/LevelRunner.cpp b/core/runner/LevelRunner.cpp index ca01554..fb3e711 100644 --- a/core/runner/LevelRunner.cpp +++ b/core/runner/LevelRunner.cpp @@ -41,6 +41,7 @@ namespace mad::core { controller->control(); } m_camera->render(window); + //m_world->produce(*m_level_event_dispatcher); } window.display(); } diff --git a/core/visual/Camera.cpp b/core/visual/Camera.cpp index 6afcdf0..5ffc851 100644 --- a/core/visual/Camera.cpp +++ b/core/visual/Camera.cpp @@ -8,11 +8,12 @@ namespace mad::core { void Camera::turn_on(EventDispatcher &event_dispatcher, Entity::Id chased_id, float smoothness, - FollowType type, float minimal_distance) { + FollowType type, float minimal_distance, float part_of_window) { m_smoothness = smoothness; m_chased_object = chased_id; m_type = type; m_minimal_distant = minimal_distance; + m_part_of_window = part_of_window; auto start_appearance = [](Entity &entity, EventDispatcher &event_dispatcher) { const_cast_to(entity).appear(event_dispatcher); }; @@ -20,6 +21,12 @@ namespace mad::core { } bool Camera::render(sf::RenderWindow &window) { + if (m_distance_over_hero == 0) { + m_view.setSize(static_cast(window.getSize().x) * *m_zoom, static_cast(window.getSize().y) * *m_zoom); + m_distance_over_hero = -static_cast(window.getSize().y) * m_part_of_window * *m_zoom; + *m_position += Vec2d{0, m_distance_over_hero}; + m_view.setCenter(*m_position); + } auto end_of_render = [](Entity &entity, EventDispatcher &event_dispatcher) { const_cast_to(entity).end_of_render_action(event_dispatcher); }; @@ -102,7 +109,8 @@ namespace mad::core { pointer_cast_to(image); RenderableBackground renderable_background(background_image, m_position, - positional_appearance.get_rotation()); + positional_appearance.get_rotation(), + m_zoom); insert_renderable_to_scene({positional_appearance.get_z_index(), RenderableWithId(std::make_shared(renderable_background), @@ -133,7 +141,7 @@ namespace mad::core { Camera::Camera(Vec2d initial_position, std::shared_ptr world, bool is_debug_mode) : m_position(std::make_shared(initial_position)), m_world(std::move(world)), - m_view(initial_position, {640, 480}), + m_view(initial_position, {0, 0}), m_is_debug_mode(is_debug_mode) { } @@ -143,9 +151,10 @@ namespace mad::core { Vec2d position = entity.get_image_position(); if (!m_last_position.has_value()) { m_last_position = position; - *m_position = position; + *m_position = position + Vec2d{0, m_distance_over_hero}; m_view.setCenter(*m_position); } + *m_position -= Vec2d{0, m_distance_over_hero}; switch (m_type) { case FollowType::Forward: { float move_x; @@ -184,6 +193,7 @@ namespace mad::core { break; } } + *m_position += Vec2d{0, m_distance_over_hero}; m_last_position = position; } } @@ -202,6 +212,7 @@ namespace mad::core { } void Camera::set_zoom(float zoom) { + *m_zoom = zoom; m_view.zoom(zoom); } diff --git a/core/visual/Camera.hpp b/core/visual/Camera.hpp index 6e8d78d..7aed993 100644 --- a/core/visual/Camera.hpp +++ b/core/visual/Camera.hpp @@ -52,7 +52,7 @@ namespace mad::core { explicit Camera(Vec2d initial_position, std::shared_ptr world, bool is_debug_mode = false); void turn_on(EventDispatcher &event_dispatcher, Entity::Id chased_id, float smoothness, - FollowType type = FollowType::Forward, float minimal_distance = 1); + FollowType type = FollowType::Forward, float minimal_distance = 1, float part_of_window = 0); bool render(sf::RenderWindow &window) override; @@ -91,12 +91,18 @@ namespace mad::core { float m_smoothness; + std::shared_ptr m_zoom = std::make_shared(1.0); + FollowType m_type; float m_minimal_distant; bool m_is_debug_mode; + float m_distance_over_hero = 0; + + float m_part_of_window; + sf::RectangleShape get_physical_shape() noexcept override; }; diff --git a/core/visual/image/animated/RenderableAnimatedSeveralFiles.cpp b/core/visual/image/animated/RenderableAnimatedSeveralFiles.cpp index 8e8868f..cb6353c 100644 --- a/core/visual/image/animated/RenderableAnimatedSeveralFiles.cpp +++ b/core/visual/image/animated/RenderableAnimatedSeveralFiles.cpp @@ -1,8 +1,9 @@ #include "RenderableAnimatedSeveralFiles.hpp" +#include "spdlog/spdlog.h" -#include #include #include +#include namespace mad::core { @@ -26,6 +27,7 @@ namespace mad::core { CHECK_THROW(texture.loadFromFile(file_name), FileDoesNotExist, "File with StaticImage doesn't exist"); m_textures.push_back(texture); + debug_m_textures_names.push_back(file_name); } m_current_frame = m_textures.size(); @@ -36,7 +38,7 @@ namespace mad::core { m_scale = {animated_image->get_size_scale(), animated_image->get_size_scale()}; - float outline = 1; + float outline = 0.2; m_physical_shape = sf::RectangleShape({animated_image->get_physical_width() - outline, animated_image->get_physical_height() - outline}); m_physical_shape.setOrigin((animated_image->get_physical_width() - outline) / 2, @@ -55,6 +57,10 @@ namespace mad::core { } sf::Sprite render_sprite; + if(debug_prev_name != debug_m_textures_names[m_current_frame]){ + debug_prev_name = debug_m_textures_names[m_current_frame]; + //SPDLOG_DEBUG("current frame name {}", debug_prev_name); + } render_sprite.setTexture(m_textures[m_current_frame]); if (*m_orientation == Image::Orientation::Left && m_scale.get_x() > 0 || diff --git a/core/visual/image/animated/RenderableAnimatedSeveralFiles.hpp b/core/visual/image/animated/RenderableAnimatedSeveralFiles.hpp index cdde1a1..c4d28e1 100644 --- a/core/visual/image/animated/RenderableAnimatedSeveralFiles.hpp +++ b/core/visual/image/animated/RenderableAnimatedSeveralFiles.hpp @@ -42,6 +42,12 @@ namespace mad::core { float m_delta_y; sf::RectangleShape m_physical_shape; + + int debug_prev_sprite_num = 0; + + std::vector debug_m_textures_names; + + std::string debug_prev_name; }; } diff --git a/core/visual/image/background/BackgroundImage.cpp b/core/visual/image/background/BackgroundImage.cpp index 13e5786..1b3e388 100644 --- a/core/visual/image/background/BackgroundImage.cpp +++ b/core/visual/image/background/BackgroundImage.cpp @@ -5,9 +5,9 @@ namespace mad::core { - BackgroundImage::BackgroundImage(std::filesystem::path path, std::vector parallax_ratios, float scale) + BackgroundImage::BackgroundImage(std::filesystem::path path, std::vector parallax_ratios) : Image(Image::Type::Background), m_path(std::move(path)), - m_parallax_ratios(std::move(parallax_ratios)), m_scale(scale) { + m_parallax_ratios(std::move(parallax_ratios)) { } std::filesystem::path BackgroundImage::get_path() const noexcept { @@ -22,10 +22,5 @@ namespace mad::core { return {}; } - float BackgroundImage::get_scale() const noexcept { - return m_scale; - } - - } diff --git a/core/visual/image/background/BackgroundImage.hpp b/core/visual/image/background/BackgroundImage.hpp index 88b5bbb..ceb78c0 100644 --- a/core/visual/image/background/BackgroundImage.hpp +++ b/core/visual/image/background/BackgroundImage.hpp @@ -10,21 +10,17 @@ namespace mad::core { class BackgroundImage : public Image { public: - BackgroundImage(std::filesystem::path path, std::vector parallax_ratios, float scale); + BackgroundImage(std::filesystem::path path, std::vector parallax_ratios); [[nodiscard]] std::filesystem::path get_path() const noexcept; [[nodiscard]] std::vector get_parallax_ratios() const noexcept; - [[nodiscard]] float get_scale() const noexcept; - b2PolygonShape as_fixture() override; private: std::filesystem::path m_path; std::vector m_parallax_ratios; - - float m_scale; }; } diff --git a/core/visual/image/background/RenderableBackground.cpp b/core/visual/image/background/RenderableBackground.cpp index 65c91e5..9599acd 100644 --- a/core/visual/image/background/RenderableBackground.cpp +++ b/core/visual/image/background/RenderableBackground.cpp @@ -7,11 +7,11 @@ namespace mad::core { RenderableBackground::RenderableBackground(const std::shared_ptr &background, std::shared_ptr position, - std::shared_ptr rotation) : + std::shared_ptr rotation, std::shared_ptr zoom) : m_camera_position(std::move(position)), m_rotation(std::move(rotation)), m_parallax_ratios(background->get_parallax_ratios()), m_last_camera_position(*m_camera_position), - m_scale({background->get_scale(), background->get_scale()}) { + m_zoom(std::move(zoom)) { is_active = background->is_active; std::set sorted_files; @@ -34,7 +34,8 @@ namespace mad::core { sf::Sprite background; background.setTexture(m_layers[i]); float ratio = m_parallax_ratios[i]; - background.setScale(m_scale); + float scale = static_cast(window.getSize().y) / background.getLocalBounds().height * *m_zoom; + background.setScale({scale, scale}); if (m_layers_positions.size() == i) { m_layers_positions.push_back(*m_camera_position); background.setPosition(m_layers_positions[i]); @@ -44,6 +45,7 @@ namespace mad::core { m_layers_positions[i] += {(*m_camera_position - m_last_camera_position).get_x() * ratio, (*m_camera_position - m_layers_positions[i]).get_y()}; background.setTextureRect({0, 0, static_cast(background.getLocalBounds().width) * 100, static_cast(background.getLocalBounds().height)}); background.setOrigin(background.getLocalBounds().width / 2, background.getLocalBounds().height / 2); //static_cast(window.getSize().y) / 2); + window.draw(background); } m_last_camera_position = *m_camera_position; diff --git a/core/visual/image/background/RenderableBackground.hpp b/core/visual/image/background/RenderableBackground.hpp index df95e9c..2e6f38b 100644 --- a/core/visual/image/background/RenderableBackground.hpp +++ b/core/visual/image/background/RenderableBackground.hpp @@ -13,8 +13,8 @@ namespace mad::core { class RenderableBackground : public Renderable { public: - RenderableBackground(const std::shared_ptr &background, - std::shared_ptr position, std::shared_ptr rotation); + RenderableBackground(const std::shared_ptr &background, std::shared_ptr position, + std::shared_ptr rotation, std::shared_ptr zoom); bool render(sf::RenderWindow &window) override; @@ -31,7 +31,7 @@ namespace mad::core { std::shared_ptr m_rotation; - Vec2d m_scale = {1, 1}; + std::shared_ptr m_zoom; std::vector m_parallax_ratios; }; diff --git a/core/visual/image/static/RenderableStatic.cpp b/core/visual/image/static/RenderableStatic.cpp index 8884430..35b97d1 100644 --- a/core/visual/image/static/RenderableStatic.cpp +++ b/core/visual/image/static/RenderableStatic.cpp @@ -32,7 +32,7 @@ namespace mad::core { } } - float outline = 1; + float outline = 0.2; m_physical_shape = sf::RectangleShape({static_image->get_width() - outline, static_image->get_height() - outline}); m_physical_shape.setOrigin((static_image->get_width() - outline) / 2, (static_image->get_height() - outline) / 2); diff --git a/core/visual/image/storage/ImageStorage.hpp b/core/visual/image/storage/ImageStorage.hpp index 5699096..95abea7 100644 --- a/core/visual/image/storage/ImageStorage.hpp +++ b/core/visual/image/storage/ImageStorage.hpp @@ -13,7 +13,17 @@ namespace mad::core { enum class TypeAction { Idle, Run, - Attack + Attack_1_beg, + Attack_1_end, + Attack_2_beg, + Attack_2_end, + Attack_3_beg, + Attack_3_end, + Jump, + Fly_up, + Fall, + Die, + Hurt, }; explicit ImageStorage(std::unordered_map> actions); diff --git a/core/world/LocalWorld.cpp b/core/world/LocalWorld.cpp index b65987c..ffac6fa 100644 --- a/core/world/LocalWorld.cpp +++ b/core/world/LocalWorld.cpp @@ -54,6 +54,9 @@ void mad::core::LocalWorld::produce(mad::core::EventDispatcher &dispatcher) { for (Entity::Id entity_id : m_storage.extract(TrueFilter())) { if (auto physical_entity = cast_to_or_null(m_storage.get_entity(entity_id)); physical_entity != nullptr) { physical_entity->synchronize_position_with_viewable(); + if(abs(physical_entity->get_linear_velocity().get_y()) > 0.01){ + //SPDLOG_DEBUG("vel {}", physical_entity->get_linear_velocity().get_y()); + } } } @@ -85,11 +88,14 @@ mad::core::Entity::Id mad::core::LocalWorld::create_viewable_entity(int z_ind, m return m_storage.create_viewable_entity(z_ind, initial_position, initial_rotation, image_storage); } mad::core::Entity::Id mad::core::LocalWorld::create_physical_entity(int z_ind, mad::core::Vec2d initial_position, float initial_rotation, - std::shared_ptr image_storage, bool is_fixed, bool is_rotated) { + std::shared_ptr image_storage, bool is_fixed, bool is_rotated, uint16 categoryBits, uint16 maskBits) { return m_storage.create_physical_entity(z_ind, initial_position, initial_rotation, image_storage, - m_physical_world, is_fixed, is_rotated); + m_physical_world, is_fixed, is_rotated, categoryBits, maskBits); } mad::core::Entity &mad::core::LocalWorld::get_entity(mad::core::Entity::Id id) noexcept { return m_storage.get_entity(id); } +mad::core::EntityStorage &mad::core::LocalWorld::get_storage() { + return m_storage; +} diff --git a/core/world/LocalWorld.hpp b/core/world/LocalWorld.hpp index 14c38a8..3f64ea6 100644 --- a/core/world/LocalWorld.hpp +++ b/core/world/LocalWorld.hpp @@ -22,7 +22,7 @@ namespace mad::core { class LocalWorld : public World { public: - explicit LocalWorld(EventDispatcher &event_dispatcher, Vec2d gravitation_scale = {0, 30.0f}); + explicit LocalWorld(EventDispatcher &event_dispatcher, Vec2d gravitation_scale = {0, 40.0f}); bool manipulate(const Filter &filter, const Intent &intent) override; @@ -33,7 +33,9 @@ namespace mad::core { Entity::Id create_viewable_entity(int z_ind, Vec2d initial_position, float initial_rotation, std::shared_ptr image_storage) override; Entity::Id create_physical_entity(int z_ind, Vec2d initial_position, float initial_rotation, std::shared_ptr image_storage, - bool is_fixed = false, bool is_rotated = true) override; + bool is_fixed = false, bool is_rotated = true, uint16 categoryBits = 0x0006, uint16 maskBits = 0x0006) override; + EntityStorage& get_storage(); + private: std::shared_ptr>> m_step_events_queue; diff --git a/core/world/World.hpp b/core/world/World.hpp index 230d808..5e50119 100644 --- a/core/world/World.hpp +++ b/core/world/World.hpp @@ -36,7 +36,7 @@ namespace mad::core { virtual Entity::Id create_physical_entity(int z_ind, Vec2d initial_position, float initial_rotation, std::shared_ptr image_storage, - bool is_fixed, bool is_rotated) = 0; + bool is_fixed, bool is_rotated, uint16 categoryBits = 0x0002, uint16 maskBits = 0x0002) = 0; }; }// namespace mad::core diff --git a/core/world/entity/ContactListener/ContactListener.hpp b/core/world/entity/ContactListener/ContactListener.hpp index c4e0983..113a443 100644 --- a/core/world/entity/ContactListener/ContactListener.hpp +++ b/core/world/entity/ContactListener/ContactListener.hpp @@ -1,15 +1,23 @@ #ifndef MAD_CONTACTLISTENER_HPP #define MAD_CONTACTLISTENER_HPP +#include "event/physics/SensorCollision.hpp" +#include "event/physics/SensorCollisionEnd.hpp" +#include "spdlog/spdlog.h" #include -#include #include #include +#include namespace mad::core{ class MyContactListener : public b2ContactListener { void BeginContact(b2Contact *contact) override { - + ///sensors + b2FixtureUserData fixture_data_A = contact->GetFixtureA()->GetUserData(); + b2FixtureUserData fixture_data_B = contact->GetFixtureB()->GetUserData(); + if(static_cast(fixture_data_A.pointer) != 0) dispatcher.dispatch(std::make_shared(fixture_data_A.pointer)); + if(static_cast(fixture_data_B.pointer) != 0) dispatcher.dispatch(std::make_shared(fixture_data_B.pointer)); + ///bodies b2BodyUserData dataA = contact->GetFixtureA()->GetBody()->GetUserData(); b2BodyUserData dataB = contact->GetFixtureB()->GetBody()->GetUserData(); //std::cout << "!!! " << dataA.pointer << "\n"; @@ -24,15 +32,11 @@ namespace mad::core{ void EndContact(b2Contact* contact) override{ - /*//check if fixture A was a ball - void* bodyUserData = contact->GetFixtureA()->GetBody()->GetUserData(); - if ( bodyUserData ) - static_cast( bodyUserData )->endContact(); - - //check if fixture B was a ball - bodyUserData = contact->GetFixtureB()->GetBody()->GetUserData(); - if ( bodyUserData ) - static_cast( bodyUserData )->endContact();*/ + ///sensors + b2FixtureUserData fixture_data_A = contact->GetFixtureA()->GetUserData(); + b2FixtureUserData fixture_data_B = contact->GetFixtureB()->GetUserData(); + if(static_cast(fixture_data_A.pointer) != 0) dispatcher.dispatch(std::make_shared(fixture_data_A.pointer)); + if(static_cast(fixture_data_B.pointer) != 0) dispatcher.dispatch(std::make_shared(fixture_data_B.pointer)); } diff --git a/core/world/entity/EntityStorage.cpp b/core/world/entity/EntityStorage.cpp index 2253dc2..b75c3b7 100644 --- a/core/world/entity/EntityStorage.cpp +++ b/core/world/entity/EntityStorage.cpp @@ -1,15 +1,22 @@ +#include "EntityStorage.hpp" +#include "algorithm" +#include "world/filter/RadiusFilter.hpp" +#include "world/filter/TrueFilter.hpp" #include #include -#include #include -#include "EntityStorage.hpp" +#include + namespace mad::core { + float dist_sq(const Vec2d &v1, const Vec2d &v2) { + return (v1.get_x() - v2.get_x()) * (v1.get_x() - v2.get_x()) + (v1.get_y() - v2.get_y()) * (v1.get_y() - v2.get_y()); + } - std::vector EntityStorage::extract(const Filter &filter) const { + std::vector EntityStorage::extract(const Filter &filter) { switch (filter.type) { case Filter::Type::Id: { IdFilter id_filter = const_cast_to(filter); @@ -19,6 +26,20 @@ namespace mad::core { case Filter::Type::True: { return m_list_ids; } + + case Filter::Type::Radius: { + std::vector arr; + + RadiusFilter radius_filter = const_cast_to(filter); + for (Entity::Id entity_id : extract(TrueFilter())) { + if (auto physical_entity = cast_to_or_null(get_entity(entity_id))) { + if (dist_sq(physical_entity->get_position(), radius_filter.get_filter_point()) < radius_filter.get_filter_radius_sq()) { + arr.push_back(entity_id); + } + } + } + return arr; + } } } @@ -36,12 +57,18 @@ namespace mad::core { } Entity::Id EntityStorage::create_physical_entity(int z_ind, Vec2d initial_position, float initial_rotation, std::shared_ptr image_storage, - b2World &physicalWorld, bool is_fixed, bool is_rotated) { + b2World &physicalWorld, bool is_fixed, bool is_rotated, uint16 categoryBits, uint16 maskBits) { auto new_entity_id = static_cast(m_map_entities.size()); m_list_ids.push_back(new_entity_id); m_map_entities[new_entity_id] = std::make_unique(new_entity_id, z_ind, initial_position, initial_rotation, - image_storage, physicalWorld, is_fixed, is_rotated); + image_storage, physicalWorld, is_fixed, is_rotated, categoryBits, maskBits); return new_entity_id; } + void EntityStorage::destroy_physical_entity(Entity::Id entity_id) { + m_list_ids.erase(std::remove(m_list_ids.begin(), m_list_ids.end(), entity_id), m_list_ids.end()); + m_map_entities[entity_id] = nullptr; + } + + }// namespace mad::core diff --git a/core/world/entity/EntityStorage.hpp b/core/world/entity/EntityStorage.hpp index 476597d..61aa90c 100644 --- a/core/world/entity/EntityStorage.hpp +++ b/core/world/entity/EntityStorage.hpp @@ -3,19 +3,19 @@ #include "Entity.hpp" -#include #include +#include #include #include #include #include "EntityStorage.hpp" +#include "PhysicalEntity.hpp" #include "ViewableEntity.hpp" #include "visual/image/shape/Shape.hpp" -#include "PhysicalEntity.hpp" -#include #include +#include namespace mad::core { class Image; @@ -25,13 +25,14 @@ namespace mad::core { class EntityStorage { public: - [[nodiscard]] std::vector extract(const Filter &filter) const; + [[nodiscard]] std::vector extract(const Filter &filter) ; Entity &get_entity(Entity::Id id); Entity::Id create_viewable_entity(int z_ind, Vec2d initial_position, float initial_rotation, std::shared_ptr image_storage); Entity::Id create_physical_entity(int z_ind, Vec2d initial_position, float initial_rotation, std::shared_ptr image_storage, - b2World &physicalWorld, bool is_fixed, bool is_rotated); + b2World &physicalWorld, bool is_fixed, bool is_rotated, uint16 categoryBits, uint16 maskBits); + void destroy_physical_entity(Entity::Id entity_id); private: std::unordered_map> m_map_entities; @@ -39,7 +40,7 @@ namespace mad::core { std::vector m_list_ids; }; -} +}// namespace mad::core -#endif //MAD_CORE_WORLD_ENTITY_ENTITYSTORAGE_HPP +#endif//MAD_CORE_WORLD_ENTITY_ENTITYSTORAGE_HPP diff --git a/core/world/entity/PhysicalEntity.cpp b/core/world/entity/PhysicalEntity.cpp index 9b58177..a5f1c24 100644 --- a/core/world/entity/PhysicalEntity.cpp +++ b/core/world/entity/PhysicalEntity.cpp @@ -8,7 +8,7 @@ #include mad::core::PhysicalEntity::PhysicalEntity(std::int32_t id, int z_ind, Vec2d initial_position, float initial_rotation, std::shared_ptr image_storage, - b2World &physicalWorld, bool is_fixed, bool is_rotated) + b2World &physicalWorld, bool is_fixed, bool is_rotated, uint16 categoryBits, uint16 maskBits) : ViewableEntity(id, z_ind, initial_position, initial_rotation, image_storage) { //rect.setOrigin(300, 50); @@ -16,10 +16,19 @@ mad::core::PhysicalEntity::PhysicalEntity(std::int32_t id, int z_ind, Vec2d init if(is_fixed) { b2BodyDef fixedBodyDef; + //fixtureDef.filter.categoryBits = categoryBits; + //fixtureDef.filter.maskBits = maskBits; fixedBodyDef.position.Set(initial_position.get_x(), initial_position.get_y()); body = physicalWorld.CreateBody(&fixedBodyDef); b2PolygonShape groundBox = (image_storage->get_action(ImageStorage::TypeAction::Idle))->as_fixture(); - body->CreateFixture(&groundBox, 0.0f); + + b2FixtureDef fixtureDef; + fixtureDef.filter.categoryBits = categoryBits; + fixtureDef.filter.maskBits = maskBits; + fixtureDef.shape = &groundBox; + fixtureDef.density = 0.0f; + + body->CreateFixture(&fixtureDef); body->SetTransform(body->GetPosition(), initial_rotation); } else @@ -35,10 +44,14 @@ mad::core::PhysicalEntity::PhysicalEntity(std::int32_t id, int z_ind, Vec2d init } b2FixtureDef fixtureDef; + fixtureDef.filter.categoryBits = categoryBits; + fixtureDef.filter.maskBits = maskBits; fixtureDef.shape = &dynamicBox; fixtureDef.density = 1.0f; - fixtureDef.friction = 0.3f; - fixtureDef.restitution = 0.2f; + fixtureDef.friction = 0.0f; + fixtureDef.restitution = 0.0f; + body->SetLinearDamping(0); + body->SetAngularDamping(0); body->CreateFixture(&fixtureDef); body->SetTransform(body->GetPosition(), initial_rotation); @@ -69,6 +82,10 @@ void mad::core::PhysicalEntity::apply_force_to_center(mad::core::Vec2d force, ma void mad::core::PhysicalEntity::set_linear_velocity(mad::core::Vec2d velocity, mad::core::EventDispatcher &dispatcher) { body->SetLinearVelocity(velocity); } +void mad::core::PhysicalEntity::set_linear_horizontal_velocity(float velocity, mad::core::EventDispatcher &dispatcher) { + body->SetLinearVelocity({velocity, body->GetLinearVelocity().y}); +} + void mad::core::PhysicalEntity::apply_angular_impulse(float impulse, mad::core::EventDispatcher &dispatcher, bool awake) { body->ApplyAngularImpulse(impulse, awake); } @@ -154,3 +171,14 @@ mad::core::Vec2d mad::core::PhysicalEntity::get_local_center() { mad::core::Vec2d mad::core::PhysicalEntity::get_world_center() { return {body->GetWorldCenter().x, body->GetWorldCenter().y}; } +void mad::core::PhysicalEntity::add_sensor(b2Vec2 offset, float x_size, float y_size) { + b2FixtureDef FixtureDef; + FixtureDef.filter.categoryBits = 0x0006; + FixtureDef.filter.maskBits = 0x0006; + b2PolygonShape fixture; + fixture.SetAsBox(x_size, y_size, offset, 0); + FixtureDef.shape = &fixture; + FixtureDef.isSensor = true; + b2Fixture* footSensorFixture = body->CreateFixture(&FixtureDef); + footSensorFixture->GetUserData().pointer = m_id; +} diff --git a/core/world/entity/PhysicalEntity.hpp b/core/world/entity/PhysicalEntity.hpp index fff81c2..fa45145 100644 --- a/core/world/entity/PhysicalEntity.hpp +++ b/core/world/entity/PhysicalEntity.hpp @@ -33,7 +33,8 @@ namespace mad::core { public: explicit PhysicalEntity(Id id, int z_ind, Vec2d initial_position, float initial_rotation, std::shared_ptr image_storage, - b2World &physicalWorld, bool is_fixed, bool is_rotated); + b2World &physicalWorld, bool is_fixed, bool is_rotated, + uint16 categoryBits, uint16 maskBits); void accept(World &world, const Intent &intent, EventDispatcher &dispatcher) override; @@ -45,6 +46,7 @@ namespace mad::core { void apply_angular_impulse(float impulse, EventDispatcher &dispatcher, bool awake = true); void apply_torque(float torque, EventDispatcher &dispatcher, bool awake = true); void set_linear_velocity(Vec2d velocity, EventDispatcher &dispatcher); + void set_linear_horizontal_velocity(float velocity, EventDispatcher &dispatcher); void set_angular_velocity(float velocity, EventDispatcher &dispatcher); void set_linear_damping(float linear_damping, EventDispatcher &dispatcher); void set_angular_damping(float angular_damping, EventDispatcher &dispatcher); @@ -78,6 +80,8 @@ namespace mad::core { void synchronize_position_with_viewable(); + void add_sensor(b2Vec2 offset, float x_size, float y_size); + private: b2Body *body; diff --git a/core/world/filter/Filter.hpp b/core/world/filter/Filter.hpp index 5454c94..7b3fdb1 100644 --- a/core/world/filter/Filter.hpp +++ b/core/world/filter/Filter.hpp @@ -12,7 +12,10 @@ namespace mad::core { struct Filter { enum class Type { Id, - True + True, + EntityTag, + Radius, + TagRadius }; explicit Filter(Type new_type) : type(new_type) { diff --git a/core/world/filter/RadiusFilter.hpp b/core/world/filter/RadiusFilter.hpp new file mode 100644 index 0000000..5018410 --- /dev/null +++ b/core/world/filter/RadiusFilter.hpp @@ -0,0 +1,35 @@ + +#ifndef MAD_RADIUSFILTER_HPP +#define MAD_RADIUSFILTER_HPP + +#include "Filter.hpp" +#include "common/FVec2D.hpp" + +namespace mad::core { + + struct RadiusFilter : Filter { + explicit RadiusFilter(Vec2d p, float r) : Filter(Filter::Type::Radius), p(p), r(r) { + } + + [[nodiscard]] float get_filter_radius() const noexcept { + return r; + } + + [[nodiscard]] float get_filter_radius_sq() const noexcept { + return r * r; + } + + [[nodiscard]] Vec2d get_filter_point() const noexcept { + return p; + } + + private: + Vec2d p; + float r; + + }; + +} + + +#endif//MAD_RADIUSFILTER_HPP \ No newline at end of file diff --git a/deps/cpp-httplib b/deps/cpp-httplib new file mode 160000 index 0000000..9452c0a --- /dev/null +++ b/deps/cpp-httplib @@ -0,0 +1 @@ +Subproject commit 9452c0a4b69c5e4e31169ed32e961d330695122c diff --git a/game/CMakeLists.txt b/game/CMakeLists.txt index 1bbf356..80ef2dc 100644 --- a/game/CMakeLists.txt +++ b/game/CMakeLists.txt @@ -37,6 +37,6 @@ function(game_executable EXECUTABLE_GAME_NAME EXECUTABLE_SOURCES) endfunction() game_executable(${EXECUTABLE_GAME} example.cpp) -#game_executable(${EXECUTABLE_GAME_RUNNER} game_runner_example.cpp) +game_executable(${EXECUTABLE_LOADER_FROM_SERVER} game_loader_from_server_example.cpp) game_executable(${EXECUTABLE_GAME_RUNNER} game_with_default_loader_example.cpp) game_executable(${EXECUTABLE_GAME_DATABASE} game_database_example.cpp) diff --git a/game/game_database_example.cpp b/game/game_database_example.cpp index 54699f6..bd6d6a1 100644 --- a/game/game_database_example.cpp +++ b/game/game_database_example.cpp @@ -33,7 +33,7 @@ int main() { #endif spdlog::set_level(log_level); - auto window = std::make_shared(sf::VideoMode(640, 480), "MAD"); + auto window = std::make_shared(sf::VideoMode(), "MAD", sf::Style::Fullscreen); ImGui::SFML::Init(*window); window->setFramerateLimit(120); @@ -45,10 +45,9 @@ int main() { auto database_storage_driver = std::make_shared(database); std::vector> level_loaders{ - std::make_shared("../../game/resources/levels/level_01"), - std::make_shared("../../game/resources/levels/level_02"), - std::make_shared("../../game/resources/levels/level_03"), - std::make_shared("../../game/resources/levels/level_with_finish") + std::make_shared("../../resources/levels/level_01"), + std::make_shared("../../resources/levels/level_02"), + std::make_shared("../../resources/levels/level_03") }; auto game_runner = std::make_unique( diff --git a/game/game_loader_from_server_example.cpp b/game/game_loader_from_server_example.cpp new file mode 100644 index 0000000..0d42e9d --- /dev/null +++ b/game/game_loader_from_server_example.cpp @@ -0,0 +1,71 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +int main() { +#ifndef NDEBUG + auto log_level = spdlog::level::trace; +#else + auto log_level = spdlog::level::info; +#endif + spdlog::set_level(log_level); + + auto window = std::make_shared(sf::VideoMode(640, 480), "MAD"); + ImGui::SFML::Init(*window); + window->setFramerateLimit(120); + + auto global_dispatcher = std::make_shared(); + + auto system_listener = std::make_shared(window); + + auto database = std::make_shared(); + auto database_storage_driver = std::make_shared(database); + + std::string level_map; + json level_config; + + std::ifstream input_config("../../resources/levels/level_with_finish/config.json"); + input_config >> level_config; + std::ifstream map_file("../../resources/levels/level_with_finish/map"); + std::string map_line; + while (std::getline(map_file, map_line)) { + level_map += map_line; + } + + std::vector> level_loaders{ + std::make_shared(level_map, level_config) + }; + + auto game_runner = std::make_unique( + level_loaders, + global_dispatcher, + std::make_unique(), + std::make_unique(database_storage_driver), + system_listener, + database_storage_driver + ); + + global_dispatcher->registry(std::make_shared(*window)); + global_dispatcher->registry(std::make_shared(*game_runner)); + global_dispatcher->registry(std::make_shared(*game_runner, database_storage_driver)); + global_dispatcher->registry(std::make_shared(*game_runner)); + + game_runner->run(*window); + + ImGui::SFML::Shutdown(); +} diff --git a/game/game_runner_example.cpp b/game/game_runner_example.cpp index 0613968..09ff347 100644 --- a/game/game_runner_example.cpp +++ b/game/game_runner_example.cpp @@ -103,7 +103,7 @@ class ExampleLevelLoader : public mad::core::LevelLoader { 0, mad::core::Vec2d{0.0f, 0.0f}, 0, - std::make_shared("../../game/resources/static/brick.png", 50, 50, + std::make_shared("../../resources/static/brick.png", 50, 50, mad::core::StaticImage::TransformType::Tile)); mad::core::Entity::Id square_id_2 = world->create_physical_entity( diff --git a/game/game_with_default_loader_example.cpp b/game/game_with_default_loader_example.cpp index cce779a..37cafe8 100644 --- a/game/game_with_default_loader_example.cpp +++ b/game/game_with_default_loader_example.cpp @@ -42,7 +42,7 @@ int main() { auto offline_storage_driver = std::make_shared(); std::vector> level_loaders{ - std::make_shared("../../game/resources/levels/level_01") + std::make_shared("../../resources/levels/level_01") }; auto game_runner = std::make_unique( diff --git a/game/mobs/hero/Hero.cpp b/game/mobs/hero/Hero.cpp new file mode 100644 index 0000000..62eb89f --- /dev/null +++ b/game/mobs/hero/Hero.cpp @@ -0,0 +1,258 @@ +#include "Hero.hpp" +#include "event/management/condition/EndAnimationCondition.hpp" +#include "event/management/condition/FallCondition.hpp" +#include "event/management/condition/KeyDownCondition.hpp" +#include "event/management/condition/KeyPressedCondition.hpp" +#include "event/management/condition/KeyReleasedCondition.hpp" +#include "event/management/condition/LastStateCondition.hpp" +#include "event/management/condition/SensorCondition.hpp" +#include "event/management/condition/SensorEndCondition.hpp" +#include "event/management/condition/TimerCondition.hpp" +#include "event/management/condition/TrueCondition.hpp" +#include "event/management/controller/Attack.hpp" +#include "event/management/controller/Fall.hpp" +#include "event/management/controller/FlyUp.hpp" +#include "event/management/controller/GroundMovement.hpp" +#include "event/management/controller/JumpImpulse.hpp" +#include "event/management/controller/Movement.hpp" +#include "event/management/controller/StartJump.hpp" +#include "event/management/controller/statemachine/StateMachine.hpp" +mad::core::Hero::Hero(std::shared_ptr world, Vec2d position, json m_config_json, std::shared_ptr level_dispatcher, std::vector> &controllers) : level_dispatcher(level_dispatcher){ + std::filesystem::path source(m_config_json["animated_resources"]); + source /= m_config_json["hero"]["source"]; + + std::shared_ptr image_storage; + + float physical_size_width = m_config_json["hero"]["animated"]["size_width"]; + float physical_size_height = m_config_json["hero"]["animated"]["size_height"]; + float size_scale = m_config_json["hero"]["animated"]["size_scale"]; + float delta_x = m_config_json["hero"]["animated"]["delta_x"]; + float delta_y = m_config_json["hero"]["animated"]["delta_y"]; + + + image_storage = std::make_shared( + std::unordered_map>( + {{ImageStorage::TypeAction::Idle, + std::make_shared( + source / m_config_json["hero"]["animated"]["actions"]["idle"]["source"], + + m_config_json["hero"]["animated"]["actions"]["idle"]["delta_time"], + physical_size_width, physical_size_height, size_scale, + delta_x, delta_y)}, + {ImageStorage::TypeAction::Run, + std::make_shared( + source / m_config_json["hero"]["animated"]["actions"]["run"]["source"], + + m_config_json["hero"]["animated"]["actions"]["run"]["delta_time"], + physical_size_width, physical_size_height, size_scale, + delta_x, delta_y)}, + {ImageStorage::TypeAction::Jump, + std::make_shared( + source / m_config_json["hero"]["animated"]["actions"]["jump"]["source"], + + m_config_json["hero"]["animated"]["actions"]["jump"]["delta_time"], + physical_size_width, physical_size_height, size_scale, + delta_x, delta_y)}, + {ImageStorage::TypeAction::Fly_up, + std::make_shared( + source / m_config_json["hero"]["animated"]["actions"]["fly_up"]["source"], + + m_config_json["hero"]["animated"]["actions"]["fly_up"]["delta_time"], + physical_size_width, physical_size_height, size_scale, + delta_x, delta_y)}, + {ImageStorage::TypeAction::Fall, + std::make_shared( + source / m_config_json["hero"]["animated"]["actions"]["fall"]["source"], + + m_config_json["hero"]["animated"]["actions"]["fall"]["delta_time"], + physical_size_width, physical_size_height, size_scale, + delta_x, delta_y)}, + {ImageStorage::TypeAction::Attack_1_beg, + std::make_shared( + source / m_config_json["hero"]["animated"]["actions"]["attack_1_beg"]["source"], + + m_config_json["hero"]["animated"]["actions"]["attack_1_beg"]["delta_time"], + physical_size_width, physical_size_height, size_scale, + delta_x, delta_y)}, + {ImageStorage::TypeAction::Attack_1_end, + std::make_shared( + source / m_config_json["hero"]["animated"]["actions"]["attack_1_end"]["source"], + + m_config_json["hero"]["animated"]["actions"]["attack_1_end"]["delta_time"], + physical_size_width, physical_size_height, size_scale, + delta_x, delta_y)}, + {ImageStorage::TypeAction::Attack_2_beg, + std::make_shared( + source / m_config_json["hero"]["animated"]["actions"]["attack_2_beg"]["source"], + + m_config_json["hero"]["animated"]["actions"]["attack_2_beg"]["delta_time"], + physical_size_width, physical_size_height, size_scale, + delta_x, delta_y)}, + {ImageStorage::TypeAction::Attack_2_end, + std::make_shared( + source / m_config_json["hero"]["animated"]["actions"]["attack_2_end"]["source"], + + m_config_json["hero"]["animated"]["actions"]["attack_2_end"]["delta_time"], + physical_size_width, physical_size_height, size_scale, + delta_x, delta_y)}, + {ImageStorage::TypeAction::Attack_3_beg, + std::make_shared( + source / m_config_json["hero"]["animated"]["actions"]["attack_3_beg"]["source"], + + m_config_json["hero"]["animated"]["actions"]["attack_3_beg"]["delta_time"], + physical_size_width, physical_size_height, size_scale, + delta_x, delta_y)}, + {ImageStorage::TypeAction::Attack_3_end, + std::make_shared( + source / m_config_json["hero"]["animated"]["actions"]["attack_3_end"]["source"], + + m_config_json["hero"]["animated"]["actions"]["attack_3_end"]["delta_time"], + physical_size_width, physical_size_height, size_scale, + delta_x, delta_y)} + } + )); + + hero_id = world->create_physical_entity( + 0, + position, + 0, + image_storage, + false, false + ); + + + ///State Machine + struct C1 : mad::core::Controller { + void control() override { + //SPDLOG_DEBUG("controller 1"); + }; + }; + struct C2 : mad::core::Controller { + void control() override { + //SPDLOG_DEBUG("controller 2"); + }; + }; + auto machine = std::make_shared( + std::shared_ptr(level_dispatcher)); + StateMachine::StateId ground_idle = machine->add_state(std::make_shared(world, hero_id, Movement::Direction::Idle)); + StateMachine::StateId ground_right = machine->add_state(std::make_shared(world, hero_id, Movement::Direction::Right, horizontal_velocity)); + StateMachine::StateId ground_left = machine->add_state(std::make_shared(world, hero_id, Movement::Direction::Left, horizontal_velocity)); + StateMachine::StateId jump_impulse = machine->add_state(std::make_shared(world, hero_id, m_impulse)); + StateMachine::StateId start_jump_left = machine->add_state(std::make_shared(world, hero_id, Movement::Direction::Left, horizontal_velocity)); + StateMachine::StateId start_jump_idle = machine->add_state(std::make_shared(world, hero_id, Movement::Direction::Idle, horizontal_velocity)); + StateMachine::StateId start_jump_right = machine->add_state(std::make_shared(world, hero_id, Movement::Direction::Right, horizontal_velocity)); + StateMachine::StateId fly_up_left = machine->add_state(std::make_shared(world, hero_id, Movement::Direction::Left, horizontal_velocity)); /// 7 + StateMachine::StateId fly_up_idle = machine->add_state(std::make_shared(world, hero_id, Movement::Direction::Idle, horizontal_velocity)); + StateMachine::StateId fly_up_right = machine->add_state(std::make_shared(world, hero_id, Movement::Direction::Right, horizontal_velocity)); + StateMachine::StateId fall_left = machine->add_state(std::make_shared(world, hero_id, Movement::Direction::Left, horizontal_velocity)); /// 10 + StateMachine::StateId fall_idle = machine->add_state(std::make_shared(world, hero_id, Movement::Direction::Idle, horizontal_velocity)); + StateMachine::StateId fall_right= machine->add_state(std::make_shared(world, hero_id, Movement::Direction::Right, horizontal_velocity)); + int *attack_stage = new int(0); + StateMachine::StateId attack_left = machine->add_state(std::make_shared(world, level_dispatcher, hero_id, Movement::Direction::Left, attack_stage, horizontal_velocity)); + StateMachine::StateId attack_idle= machine->add_state(std::make_shared(world, level_dispatcher, hero_id, Movement::Direction::Idle, attack_stage, horizontal_velocity)); + StateMachine::StateId attack_right = machine->add_state(std::make_shared(world, level_dispatcher, hero_id, Movement::Direction::Right, attack_stage, horizontal_velocity)); + + machine->add_transition(ground_idle, ground_right, std::make_shared(sf::Keyboard::Right)); + machine->add_transition(ground_idle, ground_left, std::make_shared(sf::Keyboard::Left)); + machine->add_transition(ground_right, ground_idle, std::make_shared(sf::Keyboard::Right)); + machine->add_transition(ground_left, ground_idle, std::make_shared(sf::Keyboard::Left)); + machine->add_transition(ground_right, ground_left, std::make_shared(sf::Keyboard::Left)); + machine->add_transition(ground_left, ground_right, std::make_shared(sf::Keyboard::Right)); + machine->add_transition(ground_idle, jump_impulse, std::make_shared(sf::Keyboard::Space)); + machine->add_transition(ground_right, jump_impulse, std::make_shared(sf::Keyboard::Space)); + machine->add_transition(ground_left, jump_impulse, std::make_shared(sf::Keyboard::Space)); + + machine->add_transition(jump_impulse, start_jump_idle, std::make_shared()); + machine->add_transition(start_jump_idle, start_jump_left , std::make_shared(sf::Keyboard::Left)); + machine->add_transition(start_jump_idle, start_jump_right, std::make_shared(sf::Keyboard::Right)); + machine->add_transition(start_jump_left , start_jump_idle, std::make_shared(sf::Keyboard::Left)); + machine->add_transition(start_jump_right, start_jump_idle, std::make_shared(sf::Keyboard::Right)); + + + machine->add_transition(start_jump_left , fly_up_idle, std::make_shared(hero_id, ImageStorage::TypeAction::Jump)); + machine->add_transition(start_jump_idle, fly_up_idle, std::make_shared(hero_id, ImageStorage::TypeAction::Jump)); + machine->add_transition(start_jump_right, fly_up_idle, std::make_shared(hero_id, ImageStorage::TypeAction::Jump)); + + machine->add_transition(fly_up_idle, fly_up_left, std::make_shared(sf::Keyboard::Left)); + machine->add_transition(fly_up_idle, fly_up_right, std::make_shared(sf::Keyboard::Right)); + machine->add_transition(fly_up_left, fly_up_idle, std::make_shared(sf::Keyboard::Left)); + machine->add_transition(fly_up_right, fly_up_idle, std::make_shared(sf::Keyboard::Right)); + + machine->add_transition(fly_up_left, fall_idle, std::make_shared(world, hero_id, 0)); + machine->add_transition(fly_up_idle, fall_idle, std::make_shared(world, hero_id, 0)); + machine->add_transition(fly_up_right, fall_idle, std::make_shared(world, hero_id, 0)); + + machine->add_transition(ground_left, fall_idle, std::vector>{std::make_shared(world, hero_id, 0.1), std::make_shared(hero_id, 0.2)}); + machine->add_transition(ground_idle, fall_idle, std::vector>{std::make_shared(world, hero_id, 0.1), std::make_shared(hero_id, 0.2)}); + machine->add_transition(ground_right, fall_idle, std::vector>{std::make_shared(world, hero_id, 0.1), std::make_shared(hero_id, 0.2)}); + + machine->add_transition(fall_idle, fall_left, std::make_shared(sf::Keyboard::Left)); + machine->add_transition(fall_idle, fall_right, std::make_shared(sf::Keyboard::Right)); + machine->add_transition(fall_left, fall_idle, std::make_shared(sf::Keyboard::Left)); + machine->add_transition(fall_right, fall_idle, std::make_shared(sf::Keyboard::Right)); + + machine->add_transition(fall_left, ground_idle, std::make_shared(hero_id)); + machine->add_transition(fall_idle, ground_idle, std::make_shared(hero_id)); + machine->add_transition(fall_right, ground_idle, std::make_shared(hero_id)); + + + machine->add_transition(ground_left, attack_idle, std::make_shared(sf::Keyboard::Q)); + machine->add_transition(ground_idle, attack_idle, std::make_shared(sf::Keyboard::Q)); + machine->add_transition(ground_right, attack_idle, std::make_shared(sf::Keyboard::Q)); + machine->add_transition(start_jump_left, attack_idle, std::make_shared(sf::Keyboard::Q)); + machine->add_transition(start_jump_idle, attack_idle, std::make_shared(sf::Keyboard::Q)); + machine->add_transition(start_jump_right, attack_idle, std::make_shared(sf::Keyboard::Q)); + machine->add_transition(fly_up_left, attack_idle, std::make_shared(sf::Keyboard::Q)); + machine->add_transition(fly_up_idle, attack_idle, std::make_shared(sf::Keyboard::Q)); + machine->add_transition(fly_up_right, attack_idle, std::make_shared(sf::Keyboard::Q)); + machine->add_transition(fall_left, attack_idle, std::make_shared(sf::Keyboard::Q)); + machine->add_transition(fall_idle, attack_idle, std::make_shared(sf::Keyboard::Q)); + machine->add_transition(fall_right, attack_idle, std::make_shared(sf::Keyboard::Q)); + + machine->add_transition(attack_idle, attack_left, std::make_shared(sf::Keyboard::Left)); + machine->add_transition(attack_left, attack_idle, std::make_shared(sf::Keyboard::Left)); + machine->add_transition(attack_idle, attack_right, std::make_shared(sf::Keyboard::Right)); + machine->add_transition(attack_right, attack_idle, std::make_shared(sf::Keyboard::Right)); + + machine->add_transition(attack_idle, attack_idle, std::make_shared(hero_id, ImageStorage::TypeAction::Attack_1_beg, attack_stage)); + machine->add_transition(attack_left, attack_idle, std::make_shared(hero_id, ImageStorage::TypeAction::Attack_1_beg, attack_stage)); + machine->add_transition(attack_right, attack_idle, std::make_shared(hero_id, ImageStorage::TypeAction::Attack_1_beg, attack_stage)); + + machine->add_transition(attack_left, ground_idle, std::make_shared(hero_id, ImageStorage::TypeAction::Attack_1_end, attack_stage)); + machine->add_transition(attack_idle, ground_idle, std::make_shared(hero_id, ImageStorage::TypeAction::Attack_1_end, attack_stage)); + machine->add_transition(attack_right, ground_idle, std::make_shared(hero_id, ImageStorage::TypeAction::Attack_1_end, attack_stage)); + + machine->add_transition(attack_idle, attack_idle, std::make_shared(hero_id, ImageStorage::TypeAction::Attack_2_beg, attack_stage)); + machine->add_transition(attack_left, attack_idle, std::make_shared(hero_id, ImageStorage::TypeAction::Attack_2_beg, attack_stage)); + machine->add_transition(attack_right, attack_idle, std::make_shared(hero_id, ImageStorage::TypeAction::Attack_2_beg, attack_stage)); + + machine->add_transition(attack_left, ground_idle, std::make_shared(hero_id, ImageStorage::TypeAction::Attack_2_end, attack_stage)); + machine->add_transition(attack_idle, ground_idle, std::make_shared(hero_id, ImageStorage::TypeAction::Attack_2_end, attack_stage)); + machine->add_transition(attack_right, ground_idle, std::make_shared(hero_id, ImageStorage::TypeAction::Attack_2_end, attack_stage)); + + machine->add_transition(attack_idle, attack_idle, std::make_shared(hero_id, ImageStorage::TypeAction::Attack_3_beg, attack_stage)); + machine->add_transition(attack_left, attack_idle, std::make_shared(hero_id, ImageStorage::TypeAction::Attack_3_beg, attack_stage)); + machine->add_transition(attack_right, attack_idle, std::make_shared(hero_id, ImageStorage::TypeAction::Attack_3_beg, attack_stage)); + + machine->add_transition(attack_left, ground_idle, std::make_shared(hero_id, ImageStorage::TypeAction::Attack_3_end, attack_stage)); + machine->add_transition(attack_idle, ground_idle, std::make_shared(hero_id, ImageStorage::TypeAction::Attack_3_end, attack_stage)); + machine->add_transition(attack_right, ground_idle, std::make_shared(hero_id, ImageStorage::TypeAction::Attack_3_end, attack_stage)); + + + + + + + + + machine->set_initial_state(0); + controllers.push_back(machine); + + + /// add sensor + auto m_entity = cast_to_or_null(world->get_storage().get_entity(hero_id)); + m_entity->add_sensor({0, 6}, 2.65, 0.05); +} +mad::core::Entity::Id mad::core::Hero::get_hero_id() const { + return hero_id; +} diff --git a/game/mobs/hero/Hero.hpp b/game/mobs/hero/Hero.hpp new file mode 100644 index 0000000..11df06c --- /dev/null +++ b/game/mobs/hero/Hero.hpp @@ -0,0 +1,23 @@ +#ifndef MAD_HERO_HPP +#define MAD_HERO_HPP + +#include "loader/LevelLoaderFromFile.hpp" +#include "world/LocalWorld.hpp" +#include +#include "world/entity/PhysicalEntity.hpp" +#include +namespace mad::core { + class Hero { + public: + Hero(std::shared_ptr world, Vec2d position, json m_config_json, std::shared_ptr level_dispatcher, std::vector> &controllers); + Entity::Id get_hero_id() const; + + private: + Entity::Id hero_id; + std::shared_ptr level_dispatcher; + float horizontal_velocity = 20; + float m_impulse = 2000; + }; +}// namespace mad::core + +#endif//MAD_HERO_HPP diff --git a/game/resources/animated/helicopter.png b/game/resources/animated/helicopter.png deleted file mode 100644 index 4d43f8c..0000000 Binary files a/game/resources/animated/helicopter.png and /dev/null differ diff --git a/game/resources/animated/runner_new.png b/game/resources/animated/runner_new.png deleted file mode 100644 index 075c1d8..0000000 Binary files a/game/resources/animated/runner_new.png and /dev/null differ diff --git a/game/resources/decoration/decoration_03/stone.png b/game/resources/decoration/decoration_03/stone.png deleted file mode 100644 index 05a5004..0000000 Binary files a/game/resources/decoration/decoration_03/stone.png and /dev/null differ diff --git a/game/resources/decoration/decoration_03/tree.png b/game/resources/decoration/decoration_03/tree.png deleted file mode 100644 index 51c45b3..0000000 Binary files a/game/resources/decoration/decoration_03/tree.png and /dev/null differ diff --git a/game/resources/levels/level_01/config.json b/game/resources/levels/level_01/config.json deleted file mode 100644 index 6550a5f..0000000 --- a/game/resources/levels/level_01/config.json +++ /dev/null @@ -1,68 +0,0 @@ -{ - "name" : "level_01", - "animated_resources" : "../../game/resources/animated/", - "static_resources" : "../../game/resources/static/block_01", - "decoration_resources" : "../../game/resources/decoration/decoration_01", - "block" : 50.0, - "camera": { - "position" : { - "x" : 10.0, - "y" : 10.0 - }, - "angle": 15.0, - "smoothness": 0.1, - "zoom": 10.5, - "follow_type" : "forward", - "minimal_distance" : 3.0 - }, - "background" : { - "source" : "../../game/resources/background/background_01", - "parallax_ratios" : [0.95, 0.9, 0.85, 0.8, 0.75, 0.7, 0.65], - "scale" : 0.45 - }, - "texture" : { - "unstable_block" : "unstable_block.png", - "ground_block" : "ground_block.png", - "finish_block" : "finish_block.png", - "begin_block" : "begin_block.png", - "middle_block" : "middle_block.png", - "end_block" : "end_block.png", - "separate_block" : "separate_block.png" - }, - "decoration" : { - "decoration_01" : { - "source" : "tree.png", - "scale" : 1, - "delta_x" : 0, - "delta_y" : 5 - }, - "decoration_02" : { - "source" : "stone.png", - "scale" : 1, - "delta_x" : 0, - "delta_y" : -20 - } - }, - "hero" : { - "source" : "hero", - "animated" : { - "size_width": 30, - "size_height": 50, - "size_scale": 0.2, - "delta_x" : 0, - "delta_y" : 0, - "actions" : { - "idle" : { - "source": "idle", - "type": "several_files", - "delta_time": 100 - }, - "run" : { - "source": "run", - "type": "several_files", - "delta_time": 100 - } - } - } - } -} \ No newline at end of file diff --git a/game/resources/levels/level_02/config.json b/game/resources/levels/level_02/config.json deleted file mode 100644 index 0c7db93..0000000 --- a/game/resources/levels/level_02/config.json +++ /dev/null @@ -1,68 +0,0 @@ -{ - "name" : "level_01", - "animated_resources" : "../../game/resources/animated/", - "static_resources" : "../../game/resources/static/block_01", - "decoration_resources" : "../../game/resources/decoration/decoration_01", - "block" : 50.0, - "camera": { - "position" : { - "x" : 10.0, - "y" : 10.0 - }, - "angle": 15.0, - "smoothness": 0.1, - "zoom": 10.5, - "follow_type" : "forward", - "minimal_distance" : 3.0 - }, - "background" : { - "source" : "../../game/resources/background/background_02", - "parallax_ratios" : [0.95, 0.9, 0.85, 0.8, 0.75, 0.7, 0.65, 0.6], - "scale" : 0.45 - }, - "texture" : { - "unstable_block" : "unstable_block.png", - "ground_block" : "ground_block.png", - "finish_block" : "finish_block.png", - "begin_block" : "begin_block.png", - "middle_block" : "middle_block.png", - "end_block" : "end_block.png", - "separate_block" : "separate_block.png" - }, - "decoration" : { - "decoration_01" : { - "source" : "tree.png", - "scale" : 1, - "delta_x" : 0, - "delta_y" : 5 - }, - "decoration_02" : { - "source" : "stone.png", - "scale" : 1, - "delta_x" : 0, - "delta_y" : -20 - } - }, - "hero" : { - "source" : "hero", - "animated" : { - "size_width": 30, - "size_height": 50, - "size_scale": 0.2, - "delta_x" : 0, - "delta_y" : 0, - "actions" : { - "idle" : { - "source": "idle", - "type": "several_files", - "delta_time": 100 - }, - "run" : { - "source": "run", - "type": "several_files", - "delta_time": 100 - } - } - } - } -} \ No newline at end of file diff --git a/game/resources/levels/level_02/map b/game/resources/levels/level_02/map deleted file mode 100644 index 02896b6..0000000 --- a/game/resources/levels/level_02/map +++ /dev/null @@ -1,8 +0,0 @@ -@......H..#..#...................... -.................................... -.................................... -.................................F.. -.......&.....*...................... -.....[__________].....+...[]........ -.....############.........##........ -[__]......................##........ \ No newline at end of file diff --git a/game/resources/levels/level_03/config.json b/game/resources/levels/level_03/config.json deleted file mode 100644 index 2abaa77..0000000 --- a/game/resources/levels/level_03/config.json +++ /dev/null @@ -1,68 +0,0 @@ -{ - "name" : "level_01", - "animated_resources" : "../../game/resources/animated/", - "static_resources" : "../../game/resources/static/block_03", - "decoration_resources" : "../../game/resources/decoration/decoration_03", - "block" : 50.0, - "camera": { - "position" : { - "x" : 10.0, - "y" : 10.0 - }, - "angle": 15.0, - "smoothness": 0.1, - "zoom": 10.5, - "follow_type" : "forward", - "minimal_distance" : 3.0 - }, - "background" : { - "source" : "../../game/resources/background/background_03", - "parallax_ratios" : [0.95, 0.9, 0.85, 0.8], - "scale" : 2.75 - }, - "texture" : { - "unstable_block" : "unstable_block.png", - "ground_block" : "ground_block.png", - "finish_block" : "finish_block.png", - "begin_block" : "begin_block.png", - "middle_block" : "middle_block.png", - "end_block" : "end_block.png", - "separate_block" : "separate_block.png" - }, - "decoration" : { - "decoration_01" : { - "source" : "tree.png", - "scale" : 1, - "delta_x" : 0, - "delta_y" : 5 - }, - "decoration_02" : { - "source" : "stone.png", - "scale" : 1, - "delta_x" : 0, - "delta_y" : -20 - } - }, - "hero" : { - "source" : "hero", - "animated" : { - "size_width": 30, - "size_height": 50, - "size_scale": 0.2, - "delta_x" : 0, - "delta_y" : 0, - "actions" : { - "idle" : { - "source": "idle", - "type": "several_files", - "delta_time": 100 - }, - "run" : { - "source": "run", - "type": "several_files", - "delta_time": 100 - } - } - } - } -} \ No newline at end of file diff --git a/game/resources/levels/level_03/map b/game/resources/levels/level_03/map deleted file mode 100644 index 02896b6..0000000 --- a/game/resources/levels/level_03/map +++ /dev/null @@ -1,8 +0,0 @@ -@......H..#..#...................... -.................................... -.................................... -.................................F.. -.......&.....*...................... -.....[__________].....+...[]........ -.....############.........##........ -[__]......................##........ \ No newline at end of file diff --git a/game/resources/levels/level_with_finish/config.json b/game/resources/levels/level_with_finish/config.json deleted file mode 100644 index 2dac5d2..0000000 --- a/game/resources/levels/level_with_finish/config.json +++ /dev/null @@ -1,49 +0,0 @@ -{ - "name" : "level_with_finish", - "animated_resources" : "../../game/resources/animated/", - "static_resources" : "../../game/resources/static/", - "block" : 50.0, - "camera": { - "position" : { - "x" : 10.0, - "y" : 10.0 - }, - "angle": 15.0, - "smoothness": 0.6, - "zoom": 10.5, - "follow_type" : "forward", - "minimal_distance" : 3.0 - }, - "background" : { - "source" : "../../game/resources/background/background_02", - "parallax_ratios" : [0.95, 0.9, 0.85, 0.8, 0.75], - "scale" : 3 - }, - "texture" : { - "ground_block" : "brick.png", - "unstable_block" : "brick.png", - "finish_block" : "exit.png" - }, - "hero" : { - "source" : "hero", - "animated" : { - "size_width": 30, - "size_height": 50, - "size_scale": 0.2, - "delta_x" : 0, - "delta_y" : 0, - "actions" : { - "idle" : { - "source": "idle", - "type": "several_files", - "delta_time": 100 - }, - "run" : { - "source": "run", - "type": "several_files", - "delta_time": 100 - } - } - } - } -} \ No newline at end of file diff --git a/game/resources/static/18plus.png b/game/resources/static/18plus.png deleted file mode 100644 index e627de0..0000000 Binary files a/game/resources/static/18plus.png and /dev/null differ diff --git a/game/resources/static/block_01/unstable_block.png b/game/resources/static/block_01/unstable_block.png deleted file mode 100644 index f65c6f1..0000000 Binary files a/game/resources/static/block_01/unstable_block.png and /dev/null differ diff --git a/game/resources/static/block_03/begin_block.png b/game/resources/static/block_03/begin_block.png deleted file mode 100644 index 393774b..0000000 Binary files a/game/resources/static/block_03/begin_block.png and /dev/null differ diff --git a/game/resources/static/block_03/end_block.png b/game/resources/static/block_03/end_block.png deleted file mode 100644 index 3c4d210..0000000 Binary files a/game/resources/static/block_03/end_block.png and /dev/null differ diff --git a/game/resources/static/block_03/ground_block.png b/game/resources/static/block_03/ground_block.png deleted file mode 100644 index 3f450fe..0000000 Binary files a/game/resources/static/block_03/ground_block.png and /dev/null differ diff --git a/game/resources/static/block_03/middle_block.png b/game/resources/static/block_03/middle_block.png deleted file mode 100644 index 75c533c..0000000 Binary files a/game/resources/static/block_03/middle_block.png and /dev/null differ diff --git a/game/resources/static/block_03/separate_block.png b/game/resources/static/block_03/separate_block.png deleted file mode 100644 index b3d6a02..0000000 Binary files a/game/resources/static/block_03/separate_block.png and /dev/null differ diff --git a/game/resources/static/block_03/unstable_block.png b/game/resources/static/block_03/unstable_block.png deleted file mode 100644 index f65c6f1..0000000 Binary files a/game/resources/static/block_03/unstable_block.png and /dev/null differ diff --git a/game/resources/static/brick.png b/game/resources/static/brick.png deleted file mode 100644 index f65c6f1..0000000 Binary files a/game/resources/static/brick.png and /dev/null differ diff --git a/network/CMakeLists.txt b/network/CMakeLists.txt new file mode 100644 index 0000000..69e16eb --- /dev/null +++ b/network/CMakeLists.txt @@ -0,0 +1,41 @@ +function(network_executable EXECUTABLE_NETWORK_NAME EXECUTABLE_SOURCES) + message(STATUS "Network executable: '${EXECUTABLE_NETWORK_NAME}' is built with ${EXECUTABLE_SOURCES}") + + add_executable( + ${EXECUTABLE_NETWORK_NAME} + ${EXECUTABLE_SOURCES} + ${SOURCES_IMGUI} + ${SOURCES_IMGUI_SFML} + ) + + if (CMAKE_BUILD_TYPE MATCHES Debug) + target_compile_definitions(${EXECUTABLE_NETWORK_NAME} PUBLIC SPDLOG_ACTIVE_LEVEL=SPDLOG_LEVEL_TRACE) + message(STATUS "Enable debug logs for ${EXECUTABLE_NETWORK_NAME}") + endif() + + target_include_directories( + ${EXECUTABLE_NETWORK_NAME} PUBLIC + + ${PROJECT_SOURCE_DIR} + ${INCLUDE_SPDLOG} + ${INCLUDE_BOX2D} + ${INCLUDE_IMGUI} + ${INCLUDE_IMGUI_SFML} + ${INCLUDE_HTTP} + ) + + target_link_libraries( + ${EXECUTABLE_NETWORK_NAME} + + ${LIBRARY_SFML} + ${LIBRARY_CORE} + ${LIBRARY_SPDLOG} + ${LIBRARY_BOX2D} + ${LIBRARY_OPENGL} + ${LIBRARY_PQXX} + ) + +endfunction() + +network_executable(${EXECUTABLE_SIMPLE_SERVER} server/simple-server.cpp) +network_executable(${EXECUTABLE_SIMPLE_CLIENT} client/simple-client.cpp) diff --git a/network/client/simple-client.cpp b/network/client/simple-client.cpp new file mode 100644 index 0000000..5a11788 --- /dev/null +++ b/network/client/simple-client.cpp @@ -0,0 +1,125 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +namespace mad::core { + + class NetworkClientStorageDriver : public ClientStorageDriver { + public: + explicit NetworkClientStorageDriver() : m_client("localhost", 8080) { + auto res = m_client.Get("/connection"); + SPDLOG_DEBUG("Connection request result:\n\tStatus: " + std::to_string(res->status) + "\n\tMessage: " + res->body); + } + + bool log_in(const std::string &username) const override { + auto res = m_client.Post("/user/login", httplib::Params{ + {"username", username} + }); + SPDLOG_DEBUG("Login request result:\n\tStatus: " + std::to_string(res->status) + "\n\tMessage: " + res->body); + if (res->status == 200) { + m_username = username; + } + return res->status == 200; + } + + bool sign_up(const std::string &username) override { + auto res = m_client.Post("/user/signup", httplib::Params{ + {"username", username} + }); + SPDLOG_DEBUG("Sign up request result:\n\tStatus: " + std::to_string(res->status) + "\n\tMessage: " + res->body); + return res->status == 200; + } + + std::size_t get_progress() const override { + auto res = m_client.Post("/user/progress", httplib::Params{ + {"username", m_username} + }); + SPDLOG_DEBUG("Get progress request result:\n\tStatus: " + std::to_string(res->status) + "\n\tMessage: " + res->body); + return std::stoi(res->body); + } + + void update_progress() override { + auto res = m_client.Post("/user/increment-progress", httplib::Params{ + {"username", m_username} + }); + SPDLOG_DEBUG("Update request result:\n\tStatus: " + std::to_string(res->status) + "\n\tMessage: " + res->body); + } + + std::vector> get_levels() { + auto res = m_client.Get("/level/total"); + std::size_t level_count = std::stoi(res->body); + std::vector> loaders; + for (std::size_t i = 1; i <= level_count; ++i) { + auto res1 = m_client.Post("/level/load", httplib::Params{ + {"number", std::to_string(i)} + }); + json config; + std::stringstream ss; + ss << res1->body; + ss >> config; + loaders.push_back(std::make_shared(config["map"], config)); + } + return loaders; + } + + private: + mutable std::string m_username; + mutable httplib::Client m_client; + + }; + +} + +int main() { +#ifndef NDEBUG + auto log_level = spdlog::level::trace; +#else + auto log_level = spdlog::level::info; +#endif + spdlog::set_level(log_level); + + auto window = std::make_shared(sf::VideoMode(), "MAD", sf::Style::Fullscreen); + ImGui::SFML::Init(*window); + window->setFramerateLimit(120); + + auto global_dispatcher = std::make_shared(); + + auto system_listener = std::make_shared(window); + + auto database_storage_driver = std::make_shared(); + + std::vector> level_loaders = database_storage_driver->get_levels(); + + auto game_runner = std::make_unique( + level_loaders, + global_dispatcher, + std::make_unique(), + std::make_unique(database_storage_driver), + system_listener, + database_storage_driver + ); + + global_dispatcher->registry(std::make_shared(*window)); + global_dispatcher->registry(std::make_shared(*game_runner)); + global_dispatcher->registry(std::make_shared(*game_runner, database_storage_driver)); + global_dispatcher->registry(std::make_shared(*game_runner)); + + game_runner->run(*window); + + ImGui::SFML::Shutdown(); +} diff --git a/network/server/simple-server.cpp b/network/server/simple-server.cpp new file mode 100644 index 0000000..6125c04 --- /dev/null +++ b/network/server/simple-server.cpp @@ -0,0 +1,247 @@ +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include + +using json = nlohmann::json; + + +int main() { + httplib::Server svr; + mad::core::Database db; + std::filesystem::path levels_directory = "../../resources/levels"; + + std::mutex locker; + std::vector logs; + + svr.Get("/connection", [&logs, &locker](const httplib::Request &req, httplib::Response &res) { + std::unique_lock lock(locker); + res.status = 200; + res.body = "Connection successful"; + logs.push_back("Connected user port " + std::to_string(req.remote_port)); + }); + + svr.Get("/level/total", [&logs, &locker, &db](const httplib::Request &req, httplib::Response &res) { + std::unique_lock lock(locker); + res.status = 200; + res.body = std::to_string(db.get_levels_total()); + logs.push_back("Send total level counter to port " + std::to_string(req.remote_port)); + }); + + svr.Post("/level/load", [&logs, &locker, &db, &levels_directory](const httplib::Request &req, httplib::Response &res) { + std::unique_lock lock(locker); + if (req.has_param("number")) { + auto number = std::stoi(req.get_param_value("number")); + if (number <= db.get_levels_total()) { + auto levelname = db.get_levelname(number); + auto cur_level_directory = levels_directory / levelname; + std::ifstream input_config(cur_level_directory / "config.json"); + std::ifstream input_map(cur_level_directory / "map"); + json config; + std::string map, map_line; + input_config >> config; + while (input_map >> map_line) { + map += map_line + '\n'; + } + config["map"] = map; + res.status = 200; + res.body = to_string(config); + logs.push_back("Send level " + levelname + " to port " + std::to_string(req.remote_port)); + } else { + res.status = 404; + res.body = "Invalid number of level"; + } + } else { + res.status = 404; + res.body = "Invalid params of request"; + } + }); + + svr.Post("/user/login", [&db, &logs, &locker](const httplib::Request &req, httplib::Response &res) { + std::unique_lock lock(locker); + if (req.has_param("username")) { + auto username = req.get_param_value("username"); + if (db.is_user_exists(username)) { + res.status = 200; + res.body = "OK"; + logs.push_back("User " + std::to_string(req.remote_port) + " login as " + username); + } else { + res.status = 404; + res.body = "User doesn\'t exists"; + } + } else { + res.status = 404; + res.body = "Invalid params of request"; + } + }); + + svr.Post("/user/signup", [&db, &logs, &locker](const httplib::Request &req, httplib::Response &res) { + std::unique_lock lock(locker); + if (req.has_param("username")) { + auto username = req.get_param_value("username"); + if (db.is_user_exists(username)) { + res.status = 404; + res.body = "User already exists"; + logs.push_back("Register new user " + username + " from port " + std::to_string(req.remote_port)); + } else { + db.registry_user(username); + res.status = 200; + res.body = "User " + username + " is registered"; + } + } else { + res.status = 404; + res.body = "Invalid params of request"; + } + }); + + svr.Post("/user/progress", [&db, &logs, &locker](const httplib::Request &req, httplib::Response &res) { + std::unique_lock lock(locker); + if (req.has_param("username")) { + auto username = req.get_param_value("username"); + if (db.is_user_exists(username)) { + res.status = 200; + res.body = std::to_string(db.get_progress(username)); + logs.push_back("Send progress to user " + username); + } else { + res.status = 404; + res.body = "User doesn\'t exists"; + } + } else { + res.status = 404; + res.body = "Invalid params of request"; + } + }); + + svr.Post("/user/increment-progress", [&db, &logs, &locker](const httplib::Request &req, httplib::Response &res) { + std::unique_lock lock(locker); + if (req.has_param("username")) { + auto username = req.get_param_value("username"); + if (db.is_user_exists(username)) { + res.status = 200; + res.body = "OK"; + db.increment_progress(username); + logs.push_back("Increment progress for user " + username); + } else { + res.status = 404; + res.body = "User doesn\'t exists"; + } + } else { + res.status = 404; + res.body = "Invalid params of request"; + } + }); + + sf::RenderWindow window(sf::VideoMode(640, 480), "MAD Server"); + ImGui::SFML::Init(window); + window.setFramerateLimit(120); + char input_levelname[255] = "\0"; + std::string text_hint = "new level name"; + sf::Clock clock; + while (window.isOpen()) { + sf::Event event; + while (window.pollEvent(event)) { + ImGui::SFML::ProcessEvent(event); + + if (event.type == sf::Event::Closed) { + window.close(); + if (svr.is_running()) { + svr.stop(); + } + } + } + + ImGui::SFML::Update(window, clock.restart()); + + ImGui::SetNextWindowSize(ImVec2(window.getSize().x, window.getSize().y)); + ImGui::SetNextWindowPos({0, 0}); + ImGui::Begin("Server util", nullptr, ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove); + + { + std::unique_lock lock(locker); + ImGuiWindowFlags window_flags = ImGuiWindowFlags_HorizontalScrollbar; + ImGui::BeginChild("Tool buttons", ImVec2(ImGui::GetContentRegionAvail().x * 0.3f, 82), true, window_flags); + if (ImGui::Button("Start server")) { + if (!svr.is_running()) { + std::thread([&svr]() mutable { + svr.listen("localhost", 8080); + }).detach(); + logs.emplace_back("Server has started"); + } + } + + if (ImGui::Button("Stop server")) { + if (svr.is_running()) { + svr.stop(); + logs.emplace_back("Server has stopped"); + } + } + + if (ImGui::Button("Quit")) { + window.close(); + if (svr.is_running()) { + svr.stop(); + } + } + ImGui::EndChild(); + } + + ImGui::SameLine(); + { + std::unique_lock lock(locker); + ImGuiWindowFlags window_flags = ImGuiWindowFlags_HorizontalScrollbar; + ImGui::BeginChild("Input levelname", ImVec2(ImGui::GetContentRegionAvail().x, 82), true, window_flags); + ImGui::InputText("##", input_levelname, 255); + ImGui::Text(text_hint.c_str()); + if (ImGui::Button("Enter")) { + if (!std::string(input_levelname).empty()) { + std::filesystem::path level_container = levels_directory / input_levelname; + if (std::filesystem::is_directory(level_container) && + std::filesystem::exists(level_container / "config.json") && + std::filesystem::exists(level_container / "map")) { + if (!db.is_level_exists(input_levelname)) { + db.append_level(input_levelname); + text_hint = "new level name"; + } else { + text_hint = "level name is already used"; + } + } else { + text_hint = "wrong directory format"; + } + } else { + text_hint = "string is empty"; + } + } + ImGui::EndChild(); + } + + { + std::unique_lock lock(locker); + ImGuiWindowFlags window_flags = ImGuiWindowFlags_HorizontalScrollbar; + ImGui::BeginChild("Logs", ImVec2(ImGui::GetContentRegionAvail().x, ImGui::GetContentRegionAvail().y), true, window_flags); + for (int i = 0; i < logs.size(); ++i) { + ImGui::Text(logs[i].c_str(), i); + } + ImGui::EndChild(); + } + + ImGui::End(); + + window.clear(); + ImGui::SFML::Render(window); + window.display(); + } + ImGui::SFML::Shutdown(); +} diff --git a/resources/animated/enemy/enemy_attack_beg/slime-attack-0.png b/resources/animated/enemy/enemy_attack_beg/slime-attack-0.png new file mode 100644 index 0000000..78b9be1 Binary files /dev/null and b/resources/animated/enemy/enemy_attack_beg/slime-attack-0.png differ diff --git a/resources/animated/enemy/enemy_attack_beg/slime-attack-1.png b/resources/animated/enemy/enemy_attack_beg/slime-attack-1.png new file mode 100644 index 0000000..9998355 Binary files /dev/null and b/resources/animated/enemy/enemy_attack_beg/slime-attack-1.png differ diff --git a/resources/animated/enemy/enemy_attack_beg/slime-attack-2.png b/resources/animated/enemy/enemy_attack_beg/slime-attack-2.png new file mode 100644 index 0000000..0a92e29 Binary files /dev/null and b/resources/animated/enemy/enemy_attack_beg/slime-attack-2.png differ diff --git a/resources/animated/enemy/enemy_attack_beg/slime-attack-3.png b/resources/animated/enemy/enemy_attack_beg/slime-attack-3.png new file mode 100644 index 0000000..12782ae Binary files /dev/null and b/resources/animated/enemy/enemy_attack_beg/slime-attack-3.png differ diff --git a/resources/animated/enemy/enemy_attack_end/slime-attack-4.png b/resources/animated/enemy/enemy_attack_end/slime-attack-4.png new file mode 100644 index 0000000..4488708 Binary files /dev/null and b/resources/animated/enemy/enemy_attack_end/slime-attack-4.png differ diff --git a/resources/animated/enemy/enemy_die/slime-die-0.png b/resources/animated/enemy/enemy_die/slime-die-0.png new file mode 100644 index 0000000..812039b Binary files /dev/null and b/resources/animated/enemy/enemy_die/slime-die-0.png differ diff --git a/resources/animated/enemy/enemy_die/slime-die-1.png b/resources/animated/enemy/enemy_die/slime-die-1.png new file mode 100644 index 0000000..9d96a42 Binary files /dev/null and b/resources/animated/enemy/enemy_die/slime-die-1.png differ diff --git a/resources/animated/enemy/enemy_die/slime-die-2.png b/resources/animated/enemy/enemy_die/slime-die-2.png new file mode 100644 index 0000000..8d503d3 Binary files /dev/null and b/resources/animated/enemy/enemy_die/slime-die-2.png differ diff --git a/resources/animated/enemy/enemy_die/slime-die-3.png b/resources/animated/enemy/enemy_die/slime-die-3.png new file mode 100644 index 0000000..28c5e57 Binary files /dev/null and b/resources/animated/enemy/enemy_die/slime-die-3.png differ diff --git a/resources/animated/enemy/enemy_hurt/slime-hurt-0.png b/resources/animated/enemy/enemy_hurt/slime-hurt-0.png new file mode 100644 index 0000000..ff97e70 Binary files /dev/null and b/resources/animated/enemy/enemy_hurt/slime-hurt-0.png differ diff --git a/resources/animated/enemy/enemy_hurt/slime-hurt-1.png b/resources/animated/enemy/enemy_hurt/slime-hurt-1.png new file mode 100644 index 0000000..bf76518 Binary files /dev/null and b/resources/animated/enemy/enemy_hurt/slime-hurt-1.png differ diff --git a/resources/animated/enemy/enemy_hurt/slime-hurt-2.png b/resources/animated/enemy/enemy_hurt/slime-hurt-2.png new file mode 100644 index 0000000..463f3cd Binary files /dev/null and b/resources/animated/enemy/enemy_hurt/slime-hurt-2.png differ diff --git a/resources/animated/enemy/enemy_hurt/slime-hurt-3.png b/resources/animated/enemy/enemy_hurt/slime-hurt-3.png new file mode 100644 index 0000000..f01c35c Binary files /dev/null and b/resources/animated/enemy/enemy_hurt/slime-hurt-3.png differ diff --git a/resources/animated/enemy/enemy_idle/slime-idle-0.png b/resources/animated/enemy/enemy_idle/slime-idle-0.png new file mode 100644 index 0000000..52864bf Binary files /dev/null and b/resources/animated/enemy/enemy_idle/slime-idle-0.png differ diff --git a/resources/animated/enemy/enemy_idle/slime-idle-1.png b/resources/animated/enemy/enemy_idle/slime-idle-1.png new file mode 100644 index 0000000..80fc4a3 Binary files /dev/null and b/resources/animated/enemy/enemy_idle/slime-idle-1.png differ diff --git a/resources/animated/enemy/enemy_idle/slime-idle-2.png b/resources/animated/enemy/enemy_idle/slime-idle-2.png new file mode 100644 index 0000000..ac7c9d6 Binary files /dev/null and b/resources/animated/enemy/enemy_idle/slime-idle-2.png differ diff --git a/resources/animated/enemy/enemy_idle/slime-idle-3.png b/resources/animated/enemy/enemy_idle/slime-idle-3.png new file mode 100644 index 0000000..505bb3b Binary files /dev/null and b/resources/animated/enemy/enemy_idle/slime-idle-3.png differ diff --git a/resources/animated/enemy/enemy_run/slime-move-0.png b/resources/animated/enemy/enemy_run/slime-move-0.png new file mode 100644 index 0000000..f3df2ff Binary files /dev/null and b/resources/animated/enemy/enemy_run/slime-move-0.png differ diff --git a/resources/animated/enemy/enemy_run/slime-move-1.png b/resources/animated/enemy/enemy_run/slime-move-1.png new file mode 100644 index 0000000..c932b38 Binary files /dev/null and b/resources/animated/enemy/enemy_run/slime-move-1.png differ diff --git a/resources/animated/enemy/enemy_run/slime-move-2.png b/resources/animated/enemy/enemy_run/slime-move-2.png new file mode 100644 index 0000000..f85bf27 Binary files /dev/null and b/resources/animated/enemy/enemy_run/slime-move-2.png differ diff --git a/resources/animated/enemy/enemy_run/slime-move-3.png b/resources/animated/enemy/enemy_run/slime-move-3.png new file mode 100644 index 0000000..f10cedd Binary files /dev/null and b/resources/animated/enemy/enemy_run/slime-move-3.png differ diff --git a/resources/animated/hero/hero_attack_1_beg/adventurer-attack1-00.png b/resources/animated/hero/hero_attack_1_beg/adventurer-attack1-00.png new file mode 100644 index 0000000..893cbe1 Binary files /dev/null and b/resources/animated/hero/hero_attack_1_beg/adventurer-attack1-00.png differ diff --git a/resources/animated/hero/hero_attack_1_beg/adventurer-attack1-01.png b/resources/animated/hero/hero_attack_1_beg/adventurer-attack1-01.png new file mode 100644 index 0000000..893cbe1 Binary files /dev/null and b/resources/animated/hero/hero_attack_1_beg/adventurer-attack1-01.png differ diff --git a/resources/animated/hero/hero_attack_1_beg/adventurer-attack1-02.png b/resources/animated/hero/hero_attack_1_beg/adventurer-attack1-02.png new file mode 100644 index 0000000..d5d52cf Binary files /dev/null and b/resources/animated/hero/hero_attack_1_beg/adventurer-attack1-02.png differ diff --git a/resources/animated/hero/hero_attack_1_beg/adventurer-attack1-03.png b/resources/animated/hero/hero_attack_1_beg/adventurer-attack1-03.png new file mode 100644 index 0000000..d5d52cf Binary files /dev/null and b/resources/animated/hero/hero_attack_1_beg/adventurer-attack1-03.png differ diff --git a/resources/animated/hero/hero_attack_1_beg/adventurer-attack1-04.png b/resources/animated/hero/hero_attack_1_beg/adventurer-attack1-04.png new file mode 100644 index 0000000..00f6001 Binary files /dev/null and b/resources/animated/hero/hero_attack_1_beg/adventurer-attack1-04.png differ diff --git a/resources/animated/hero/hero_attack_1_end/adventurer-attack1-02.png b/resources/animated/hero/hero_attack_1_end/adventurer-attack1-02.png new file mode 100644 index 0000000..00f6001 Binary files /dev/null and b/resources/animated/hero/hero_attack_1_end/adventurer-attack1-02.png differ diff --git a/resources/animated/hero/hero_attack_1_end/adventurer-attack1-03.png b/resources/animated/hero/hero_attack_1_end/adventurer-attack1-03.png new file mode 100644 index 0000000..3704560 Binary files /dev/null and b/resources/animated/hero/hero_attack_1_end/adventurer-attack1-03.png differ diff --git a/resources/animated/hero/hero_attack_1_end/adventurer-attack1-04.png b/resources/animated/hero/hero_attack_1_end/adventurer-attack1-04.png new file mode 100644 index 0000000..3704560 Binary files /dev/null and b/resources/animated/hero/hero_attack_1_end/adventurer-attack1-04.png differ diff --git a/resources/animated/hero/hero_attack_1_end/adventurer-attack1-05.png b/resources/animated/hero/hero_attack_1_end/adventurer-attack1-05.png new file mode 100644 index 0000000..7f4983a Binary files /dev/null and b/resources/animated/hero/hero_attack_1_end/adventurer-attack1-05.png differ diff --git a/resources/animated/hero/hero_attack_1_end/adventurer-attack1-06.png b/resources/animated/hero/hero_attack_1_end/adventurer-attack1-06.png new file mode 100644 index 0000000..7f4983a Binary files /dev/null and b/resources/animated/hero/hero_attack_1_end/adventurer-attack1-06.png differ diff --git a/resources/animated/hero/hero_attack_2_beg/adventurer-attack2-00.png b/resources/animated/hero/hero_attack_2_beg/adventurer-attack2-00.png new file mode 100644 index 0000000..38e8301 Binary files /dev/null and b/resources/animated/hero/hero_attack_2_beg/adventurer-attack2-00.png differ diff --git a/resources/animated/hero/hero_attack_2_beg/adventurer-attack2-000.png b/resources/animated/hero/hero_attack_2_beg/adventurer-attack2-000.png new file mode 100644 index 0000000..38e8301 Binary files /dev/null and b/resources/animated/hero/hero_attack_2_beg/adventurer-attack2-000.png differ diff --git a/resources/animated/hero/hero_attack_2_beg/adventurer-attack2-01.png b/resources/animated/hero/hero_attack_2_beg/adventurer-attack2-01.png new file mode 100644 index 0000000..a237738 Binary files /dev/null and b/resources/animated/hero/hero_attack_2_beg/adventurer-attack2-01.png differ diff --git a/resources/animated/hero/hero_attack_2_beg/adventurer-attack2-02.png b/resources/animated/hero/hero_attack_2_beg/adventurer-attack2-02.png new file mode 100644 index 0000000..a237738 Binary files /dev/null and b/resources/animated/hero/hero_attack_2_beg/adventurer-attack2-02.png differ diff --git a/resources/animated/hero/hero_attack_2_beg/adventurer-attack2-03.png b/resources/animated/hero/hero_attack_2_beg/adventurer-attack2-03.png new file mode 100644 index 0000000..18e53fc Binary files /dev/null and b/resources/animated/hero/hero_attack_2_beg/adventurer-attack2-03.png differ diff --git a/resources/animated/hero/hero_attack_2_beg/adventurer-attack2-04.png b/resources/animated/hero/hero_attack_2_beg/adventurer-attack2-04.png new file mode 100644 index 0000000..18e53fc Binary files /dev/null and b/resources/animated/hero/hero_attack_2_beg/adventurer-attack2-04.png differ diff --git a/resources/animated/hero/hero_attack_2_beg/adventurer-attack2-05.png b/resources/animated/hero/hero_attack_2_beg/adventurer-attack2-05.png new file mode 100644 index 0000000..5e807d5 Binary files /dev/null and b/resources/animated/hero/hero_attack_2_beg/adventurer-attack2-05.png differ diff --git a/resources/animated/hero/hero_attack_2_end/adventurer-attack2-03.png b/resources/animated/hero/hero_attack_2_end/adventurer-attack2-03.png new file mode 100644 index 0000000..5e807d5 Binary files /dev/null and b/resources/animated/hero/hero_attack_2_end/adventurer-attack2-03.png differ diff --git a/resources/animated/hero/hero_attack_2_end/adventurer-attack2-04.png b/resources/animated/hero/hero_attack_2_end/adventurer-attack2-04.png new file mode 100644 index 0000000..7495386 Binary files /dev/null and b/resources/animated/hero/hero_attack_2_end/adventurer-attack2-04.png differ diff --git a/resources/animated/hero/hero_attack_2_end/adventurer-attack2-05.png b/resources/animated/hero/hero_attack_2_end/adventurer-attack2-05.png new file mode 100644 index 0000000..7495386 Binary files /dev/null and b/resources/animated/hero/hero_attack_2_end/adventurer-attack2-05.png differ diff --git a/resources/animated/hero/hero_attack_2_end/adventurer-attack2-06.png b/resources/animated/hero/hero_attack_2_end/adventurer-attack2-06.png new file mode 100644 index 0000000..95b51a4 Binary files /dev/null and b/resources/animated/hero/hero_attack_2_end/adventurer-attack2-06.png differ diff --git a/resources/animated/hero/hero_attack_2_end/adventurer-attack2-07.png b/resources/animated/hero/hero_attack_2_end/adventurer-attack2-07.png new file mode 100644 index 0000000..95b51a4 Binary files /dev/null and b/resources/animated/hero/hero_attack_2_end/adventurer-attack2-07.png differ diff --git a/resources/animated/hero/hero_attack_3_beg/adventurer-attack3-00.png b/resources/animated/hero/hero_attack_3_beg/adventurer-attack3-00.png new file mode 100644 index 0000000..99b6794 Binary files /dev/null and b/resources/animated/hero/hero_attack_3_beg/adventurer-attack3-00.png differ diff --git a/resources/animated/hero/hero_attack_3_beg/adventurer-attack3-01.png b/resources/animated/hero/hero_attack_3_beg/adventurer-attack3-01.png new file mode 100644 index 0000000..99b6794 Binary files /dev/null and b/resources/animated/hero/hero_attack_3_beg/adventurer-attack3-01.png differ diff --git a/resources/animated/hero/hero_attack_3_beg/adventurer-attack3-02.png b/resources/animated/hero/hero_attack_3_beg/adventurer-attack3-02.png new file mode 100644 index 0000000..02eca0d Binary files /dev/null and b/resources/animated/hero/hero_attack_3_beg/adventurer-attack3-02.png differ diff --git a/resources/animated/hero/hero_attack_3_beg/adventurer-attack3-03.png b/resources/animated/hero/hero_attack_3_beg/adventurer-attack3-03.png new file mode 100644 index 0000000..02eca0d Binary files /dev/null and b/resources/animated/hero/hero_attack_3_beg/adventurer-attack3-03.png differ diff --git a/resources/animated/hero/hero_attack_3_beg/adventurer-attack3-04.png b/resources/animated/hero/hero_attack_3_beg/adventurer-attack3-04.png new file mode 100644 index 0000000..40901e1 Binary files /dev/null and b/resources/animated/hero/hero_attack_3_beg/adventurer-attack3-04.png differ diff --git a/resources/animated/hero/hero_attack_3_end/adventurer-attack3-02.png b/resources/animated/hero/hero_attack_3_end/adventurer-attack3-02.png new file mode 100644 index 0000000..40901e1 Binary files /dev/null and b/resources/animated/hero/hero_attack_3_end/adventurer-attack3-02.png differ diff --git a/resources/animated/hero/hero_attack_3_end/adventurer-attack3-03.png b/resources/animated/hero/hero_attack_3_end/adventurer-attack3-03.png new file mode 100644 index 0000000..22462fa Binary files /dev/null and b/resources/animated/hero/hero_attack_3_end/adventurer-attack3-03.png differ diff --git a/resources/animated/hero/hero_attack_3_end/adventurer-attack3-04.png b/resources/animated/hero/hero_attack_3_end/adventurer-attack3-04.png new file mode 100644 index 0000000..22462fa Binary files /dev/null and b/resources/animated/hero/hero_attack_3_end/adventurer-attack3-04.png differ diff --git a/resources/animated/hero/hero_attack_3_end/adventurer-attack3-05.png b/resources/animated/hero/hero_attack_3_end/adventurer-attack3-05.png new file mode 100644 index 0000000..ceedfdf Binary files /dev/null and b/resources/animated/hero/hero_attack_3_end/adventurer-attack3-05.png differ diff --git a/resources/animated/hero/hero_attack_3_end/adventurer-attack3-06.png b/resources/animated/hero/hero_attack_3_end/adventurer-attack3-06.png new file mode 100644 index 0000000..ceedfdf Binary files /dev/null and b/resources/animated/hero/hero_attack_3_end/adventurer-attack3-06.png differ diff --git a/resources/animated/hero/hero_attack_3_end/adventurer-attack3-07.png b/resources/animated/hero/hero_attack_3_end/adventurer-attack3-07.png new file mode 100644 index 0000000..1156b4e Binary files /dev/null and b/resources/animated/hero/hero_attack_3_end/adventurer-attack3-07.png differ diff --git a/resources/animated/hero/hero_attack_3_end/adventurer-attack3-08.png b/resources/animated/hero/hero_attack_3_end/adventurer-attack3-08.png new file mode 100644 index 0000000..1156b4e Binary files /dev/null and b/resources/animated/hero/hero_attack_3_end/adventurer-attack3-08.png differ diff --git a/resources/animated/hero/hero_die/adventurer-die-00.png b/resources/animated/hero/hero_die/adventurer-die-00.png new file mode 100644 index 0000000..8efaf11 Binary files /dev/null and b/resources/animated/hero/hero_die/adventurer-die-00.png differ diff --git a/resources/animated/hero/hero_die/adventurer-die-01.png b/resources/animated/hero/hero_die/adventurer-die-01.png new file mode 100644 index 0000000..21732bd Binary files /dev/null and b/resources/animated/hero/hero_die/adventurer-die-01.png differ diff --git a/resources/animated/hero/hero_die/adventurer-die-02.png b/resources/animated/hero/hero_die/adventurer-die-02.png new file mode 100644 index 0000000..df3cb98 Binary files /dev/null and b/resources/animated/hero/hero_die/adventurer-die-02.png differ diff --git a/resources/animated/hero/hero_die/adventurer-die-03.png b/resources/animated/hero/hero_die/adventurer-die-03.png new file mode 100644 index 0000000..5e26bde Binary files /dev/null and b/resources/animated/hero/hero_die/adventurer-die-03.png differ diff --git a/resources/animated/hero/hero_die/adventurer-die-04.png b/resources/animated/hero/hero_die/adventurer-die-04.png new file mode 100644 index 0000000..13da129 Binary files /dev/null and b/resources/animated/hero/hero_die/adventurer-die-04.png differ diff --git a/resources/animated/hero/hero_die/adventurer-die-05.png b/resources/animated/hero/hero_die/adventurer-die-05.png new file mode 100644 index 0000000..30eadec Binary files /dev/null and b/resources/animated/hero/hero_die/adventurer-die-05.png differ diff --git a/resources/animated/hero/hero_die/adventurer-die-06.png b/resources/animated/hero/hero_die/adventurer-die-06.png new file mode 100644 index 0000000..13da129 Binary files /dev/null and b/resources/animated/hero/hero_die/adventurer-die-06.png differ diff --git a/resources/animated/hero/hero_fall/adventurer-fall-00.png b/resources/animated/hero/hero_fall/adventurer-fall-00.png new file mode 100644 index 0000000..3a4b30f Binary files /dev/null and b/resources/animated/hero/hero_fall/adventurer-fall-00.png differ diff --git a/resources/animated/hero/hero_fall/adventurer-fall-01.png b/resources/animated/hero/hero_fall/adventurer-fall-01.png new file mode 100644 index 0000000..cd61af0 Binary files /dev/null and b/resources/animated/hero/hero_fall/adventurer-fall-01.png differ diff --git a/resources/animated/hero/hero_fly_up/adventurer-jump-03.png b/resources/animated/hero/hero_fly_up/adventurer-jump-03.png new file mode 100644 index 0000000..0458013 Binary files /dev/null and b/resources/animated/hero/hero_fly_up/adventurer-jump-03.png differ diff --git a/resources/animated/hero/hero_hurt/adventurer-hurt-00.png b/resources/animated/hero/hero_hurt/adventurer-hurt-00.png new file mode 100644 index 0000000..8efaf11 Binary files /dev/null and b/resources/animated/hero/hero_hurt/adventurer-hurt-00.png differ diff --git a/resources/animated/hero/hero_hurt/adventurer-hurt-01.png b/resources/animated/hero/hero_hurt/adventurer-hurt-01.png new file mode 100644 index 0000000..21732bd Binary files /dev/null and b/resources/animated/hero/hero_hurt/adventurer-hurt-01.png differ diff --git a/resources/animated/hero/hero_hurt/adventurer-hurt-02.png b/resources/animated/hero/hero_hurt/adventurer-hurt-02.png new file mode 100644 index 0000000..8910012 Binary files /dev/null and b/resources/animated/hero/hero_hurt/adventurer-hurt-02.png differ diff --git a/resources/animated/hero/hero_idle/adventurer-idle-00.png b/resources/animated/hero/hero_idle/adventurer-idle-00.png new file mode 100644 index 0000000..3bd528e Binary files /dev/null and b/resources/animated/hero/hero_idle/adventurer-idle-00.png differ diff --git a/resources/animated/hero/hero_idle/adventurer-idle-01.png b/resources/animated/hero/hero_idle/adventurer-idle-01.png new file mode 100644 index 0000000..230c1cb Binary files /dev/null and b/resources/animated/hero/hero_idle/adventurer-idle-01.png differ diff --git a/resources/animated/hero/hero_idle/adventurer-idle-02.png b/resources/animated/hero/hero_idle/adventurer-idle-02.png new file mode 100644 index 0000000..2668b59 Binary files /dev/null and b/resources/animated/hero/hero_idle/adventurer-idle-02.png differ diff --git a/resources/animated/hero/hero_idle/adventurer-idle-03.png b/resources/animated/hero/hero_idle/adventurer-idle-03.png new file mode 100644 index 0000000..53207e8 Binary files /dev/null and b/resources/animated/hero/hero_idle/adventurer-idle-03.png differ diff --git a/resources/animated/hero/hero_jump/adventurer-jump-00.png b/resources/animated/hero/hero_jump/adventurer-jump-00.png new file mode 100644 index 0000000..eedea05 Binary files /dev/null and b/resources/animated/hero/hero_jump/adventurer-jump-00.png differ diff --git a/resources/animated/hero/hero_jump/adventurer-jump-01.png b/resources/animated/hero/hero_jump/adventurer-jump-01.png new file mode 100644 index 0000000..b20e034 Binary files /dev/null and b/resources/animated/hero/hero_jump/adventurer-jump-01.png differ diff --git a/resources/animated/hero/hero_jump/adventurer-jump-02.png b/resources/animated/hero/hero_jump/adventurer-jump-02.png new file mode 100644 index 0000000..ba27779 Binary files /dev/null and b/resources/animated/hero/hero_jump/adventurer-jump-02.png differ diff --git a/resources/animated/hero/hero_jump/adventurer-jump-03.png b/resources/animated/hero/hero_jump/adventurer-jump-03.png new file mode 100644 index 0000000..0458013 Binary files /dev/null and b/resources/animated/hero/hero_jump/adventurer-jump-03.png differ diff --git a/resources/animated/hero/hero_run/adventurer-run-00.png b/resources/animated/hero/hero_run/adventurer-run-00.png new file mode 100644 index 0000000..e3d7cc0 Binary files /dev/null and b/resources/animated/hero/hero_run/adventurer-run-00.png differ diff --git a/resources/animated/hero/hero_run/adventurer-run-01.png b/resources/animated/hero/hero_run/adventurer-run-01.png new file mode 100644 index 0000000..96d8320 Binary files /dev/null and b/resources/animated/hero/hero_run/adventurer-run-01.png differ diff --git a/resources/animated/hero/hero_run/adventurer-run-02.png b/resources/animated/hero/hero_run/adventurer-run-02.png new file mode 100644 index 0000000..2e3b74d Binary files /dev/null and b/resources/animated/hero/hero_run/adventurer-run-02.png differ diff --git a/resources/animated/hero/hero_run/adventurer-run-03.png b/resources/animated/hero/hero_run/adventurer-run-03.png new file mode 100644 index 0000000..a512930 Binary files /dev/null and b/resources/animated/hero/hero_run/adventurer-run-03.png differ diff --git a/resources/animated/hero/hero_run/adventurer-run-04.png b/resources/animated/hero/hero_run/adventurer-run-04.png new file mode 100644 index 0000000..ca34331 Binary files /dev/null and b/resources/animated/hero/hero_run/adventurer-run-04.png differ diff --git a/resources/animated/hero/hero_run/adventurer-run-05.png b/resources/animated/hero/hero_run/adventurer-run-05.png new file mode 100644 index 0000000..01c9c00 Binary files /dev/null and b/resources/animated/hero/hero_run/adventurer-run-05.png differ diff --git a/game/resources/animated/hero/idle/Chara - BlueIdle00000.png b/resources/animated/hero/idle/Chara - BlueIdle00000.png similarity index 100% rename from game/resources/animated/hero/idle/Chara - BlueIdle00000.png rename to resources/animated/hero/idle/Chara - BlueIdle00000.png diff --git a/game/resources/animated/hero/idle/Chara - BlueIdle00001.png b/resources/animated/hero/idle/Chara - BlueIdle00001.png similarity index 100% rename from game/resources/animated/hero/idle/Chara - BlueIdle00001.png rename to resources/animated/hero/idle/Chara - BlueIdle00001.png diff --git a/game/resources/animated/hero/idle/Chara - BlueIdle00002.png b/resources/animated/hero/idle/Chara - BlueIdle00002.png similarity index 100% rename from game/resources/animated/hero/idle/Chara - BlueIdle00002.png rename to resources/animated/hero/idle/Chara - BlueIdle00002.png diff --git a/game/resources/animated/hero/idle/Chara - BlueIdle00003.png b/resources/animated/hero/idle/Chara - BlueIdle00003.png similarity index 100% rename from game/resources/animated/hero/idle/Chara - BlueIdle00003.png rename to resources/animated/hero/idle/Chara - BlueIdle00003.png diff --git a/game/resources/animated/hero/idle/Chara - BlueIdle00004.png b/resources/animated/hero/idle/Chara - BlueIdle00004.png similarity index 100% rename from game/resources/animated/hero/idle/Chara - BlueIdle00004.png rename to resources/animated/hero/idle/Chara - BlueIdle00004.png diff --git a/game/resources/animated/hero/idle/Chara - BlueIdle00005.png b/resources/animated/hero/idle/Chara - BlueIdle00005.png similarity index 100% rename from game/resources/animated/hero/idle/Chara - BlueIdle00005.png rename to resources/animated/hero/idle/Chara - BlueIdle00005.png diff --git a/game/resources/animated/hero/idle/Chara - BlueIdle00006.png b/resources/animated/hero/idle/Chara - BlueIdle00006.png similarity index 100% rename from game/resources/animated/hero/idle/Chara - BlueIdle00006.png rename to resources/animated/hero/idle/Chara - BlueIdle00006.png diff --git a/game/resources/animated/hero/idle/Chara - BlueIdle00007.png b/resources/animated/hero/idle/Chara - BlueIdle00007.png similarity index 100% rename from game/resources/animated/hero/idle/Chara - BlueIdle00007.png rename to resources/animated/hero/idle/Chara - BlueIdle00007.png diff --git a/game/resources/animated/hero/idle/Chara - BlueIdle00008.png b/resources/animated/hero/idle/Chara - BlueIdle00008.png similarity index 100% rename from game/resources/animated/hero/idle/Chara - BlueIdle00008.png rename to resources/animated/hero/idle/Chara - BlueIdle00008.png diff --git a/game/resources/animated/hero/idle/Chara - BlueIdle00009.png b/resources/animated/hero/idle/Chara - BlueIdle00009.png similarity index 100% rename from game/resources/animated/hero/idle/Chara - BlueIdle00009.png rename to resources/animated/hero/idle/Chara - BlueIdle00009.png diff --git a/game/resources/animated/hero/idle/Chara - BlueIdle00010.png b/resources/animated/hero/idle/Chara - BlueIdle00010.png similarity index 100% rename from game/resources/animated/hero/idle/Chara - BlueIdle00010.png rename to resources/animated/hero/idle/Chara - BlueIdle00010.png diff --git a/game/resources/animated/hero/idle/Chara - BlueIdle00011.png b/resources/animated/hero/idle/Chara - BlueIdle00011.png similarity index 100% rename from game/resources/animated/hero/idle/Chara - BlueIdle00011.png rename to resources/animated/hero/idle/Chara - BlueIdle00011.png diff --git a/game/resources/animated/hero/idle/Chara - BlueIdle00012.png b/resources/animated/hero/idle/Chara - BlueIdle00012.png similarity index 100% rename from game/resources/animated/hero/idle/Chara - BlueIdle00012.png rename to resources/animated/hero/idle/Chara - BlueIdle00012.png diff --git a/game/resources/animated/hero/idle/Chara - BlueIdle00013.png b/resources/animated/hero/idle/Chara - BlueIdle00013.png similarity index 100% rename from game/resources/animated/hero/idle/Chara - BlueIdle00013.png rename to resources/animated/hero/idle/Chara - BlueIdle00013.png diff --git a/game/resources/animated/hero/idle/Chara - BlueIdle00014.png b/resources/animated/hero/idle/Chara - BlueIdle00014.png similarity index 100% rename from game/resources/animated/hero/idle/Chara - BlueIdle00014.png rename to resources/animated/hero/idle/Chara - BlueIdle00014.png diff --git a/game/resources/animated/hero/idle/Chara - BlueIdle00015.png b/resources/animated/hero/idle/Chara - BlueIdle00015.png similarity index 100% rename from game/resources/animated/hero/idle/Chara - BlueIdle00015.png rename to resources/animated/hero/idle/Chara - BlueIdle00015.png diff --git a/game/resources/animated/hero/idle/Chara - BlueIdle00016.png b/resources/animated/hero/idle/Chara - BlueIdle00016.png similarity index 100% rename from game/resources/animated/hero/idle/Chara - BlueIdle00016.png rename to resources/animated/hero/idle/Chara - BlueIdle00016.png diff --git a/game/resources/animated/hero/idle/Chara - BlueIdle00017.png b/resources/animated/hero/idle/Chara - BlueIdle00017.png similarity index 100% rename from game/resources/animated/hero/idle/Chara - BlueIdle00017.png rename to resources/animated/hero/idle/Chara - BlueIdle00017.png diff --git a/game/resources/animated/hero/idle/Chara - BlueIdle00018.png b/resources/animated/hero/idle/Chara - BlueIdle00018.png similarity index 100% rename from game/resources/animated/hero/idle/Chara - BlueIdle00018.png rename to resources/animated/hero/idle/Chara - BlueIdle00018.png diff --git a/game/resources/animated/hero/idle/Chara - BlueIdle00019.png b/resources/animated/hero/idle/Chara - BlueIdle00019.png similarity index 100% rename from game/resources/animated/hero/idle/Chara - BlueIdle00019.png rename to resources/animated/hero/idle/Chara - BlueIdle00019.png diff --git a/game/resources/animated/hero/run/Chara_BlueWalk00000.png b/resources/animated/hero/run/Chara_BlueWalk00000.png similarity index 100% rename from game/resources/animated/hero/run/Chara_BlueWalk00000.png rename to resources/animated/hero/run/Chara_BlueWalk00000.png diff --git a/game/resources/animated/hero/run/Chara_BlueWalk00001.png b/resources/animated/hero/run/Chara_BlueWalk00001.png similarity index 100% rename from game/resources/animated/hero/run/Chara_BlueWalk00001.png rename to resources/animated/hero/run/Chara_BlueWalk00001.png diff --git a/game/resources/animated/hero/run/Chara_BlueWalk00002.png b/resources/animated/hero/run/Chara_BlueWalk00002.png similarity index 100% rename from game/resources/animated/hero/run/Chara_BlueWalk00002.png rename to resources/animated/hero/run/Chara_BlueWalk00002.png diff --git a/game/resources/animated/hero/run/Chara_BlueWalk00003.png b/resources/animated/hero/run/Chara_BlueWalk00003.png similarity index 100% rename from game/resources/animated/hero/run/Chara_BlueWalk00003.png rename to resources/animated/hero/run/Chara_BlueWalk00003.png diff --git a/game/resources/animated/hero/run/Chara_BlueWalk00004.png b/resources/animated/hero/run/Chara_BlueWalk00004.png similarity index 100% rename from game/resources/animated/hero/run/Chara_BlueWalk00004.png rename to resources/animated/hero/run/Chara_BlueWalk00004.png diff --git a/game/resources/animated/hero/run/Chara_BlueWalk00005.png b/resources/animated/hero/run/Chara_BlueWalk00005.png similarity index 100% rename from game/resources/animated/hero/run/Chara_BlueWalk00005.png rename to resources/animated/hero/run/Chara_BlueWalk00005.png diff --git a/game/resources/animated/hero/run/Chara_BlueWalk00006.png b/resources/animated/hero/run/Chara_BlueWalk00006.png similarity index 100% rename from game/resources/animated/hero/run/Chara_BlueWalk00006.png rename to resources/animated/hero/run/Chara_BlueWalk00006.png diff --git a/game/resources/animated/hero/run/Chara_BlueWalk00007.png b/resources/animated/hero/run/Chara_BlueWalk00007.png similarity index 100% rename from game/resources/animated/hero/run/Chara_BlueWalk00007.png rename to resources/animated/hero/run/Chara_BlueWalk00007.png diff --git a/game/resources/animated/hero/run/Chara_BlueWalk00008.png b/resources/animated/hero/run/Chara_BlueWalk00008.png similarity index 100% rename from game/resources/animated/hero/run/Chara_BlueWalk00008.png rename to resources/animated/hero/run/Chara_BlueWalk00008.png diff --git a/game/resources/animated/hero/run/Chara_BlueWalk00009.png b/resources/animated/hero/run/Chara_BlueWalk00009.png similarity index 100% rename from game/resources/animated/hero/run/Chara_BlueWalk00009.png rename to resources/animated/hero/run/Chara_BlueWalk00009.png diff --git a/game/resources/animated/hero/run/Chara_BlueWalk00010.png b/resources/animated/hero/run/Chara_BlueWalk00010.png similarity index 100% rename from game/resources/animated/hero/run/Chara_BlueWalk00010.png rename to resources/animated/hero/run/Chara_BlueWalk00010.png diff --git a/game/resources/animated/hero/run/Chara_BlueWalk00011.png b/resources/animated/hero/run/Chara_BlueWalk00011.png similarity index 100% rename from game/resources/animated/hero/run/Chara_BlueWalk00011.png rename to resources/animated/hero/run/Chara_BlueWalk00011.png diff --git a/game/resources/animated/hero/run/Chara_BlueWalk00012.png b/resources/animated/hero/run/Chara_BlueWalk00012.png similarity index 100% rename from game/resources/animated/hero/run/Chara_BlueWalk00012.png rename to resources/animated/hero/run/Chara_BlueWalk00012.png diff --git a/game/resources/animated/hero/run/Chara_BlueWalk00013.png b/resources/animated/hero/run/Chara_BlueWalk00013.png similarity index 100% rename from game/resources/animated/hero/run/Chara_BlueWalk00013.png rename to resources/animated/hero/run/Chara_BlueWalk00013.png diff --git a/game/resources/animated/hero/run/Chara_BlueWalk00014.png b/resources/animated/hero/run/Chara_BlueWalk00014.png similarity index 100% rename from game/resources/animated/hero/run/Chara_BlueWalk00014.png rename to resources/animated/hero/run/Chara_BlueWalk00014.png diff --git a/game/resources/animated/hero/run/Chara_BlueWalk00015.png b/resources/animated/hero/run/Chara_BlueWalk00015.png similarity index 100% rename from game/resources/animated/hero/run/Chara_BlueWalk00015.png rename to resources/animated/hero/run/Chara_BlueWalk00015.png diff --git a/game/resources/animated/hero/run/Chara_BlueWalk00016.png b/resources/animated/hero/run/Chara_BlueWalk00016.png similarity index 100% rename from game/resources/animated/hero/run/Chara_BlueWalk00016.png rename to resources/animated/hero/run/Chara_BlueWalk00016.png diff --git a/game/resources/animated/hero/run/Chara_BlueWalk00017.png b/resources/animated/hero/run/Chara_BlueWalk00017.png similarity index 100% rename from game/resources/animated/hero/run/Chara_BlueWalk00017.png rename to resources/animated/hero/run/Chara_BlueWalk00017.png diff --git a/game/resources/animated/hero/run/Chara_BlueWalk00018.png b/resources/animated/hero/run/Chara_BlueWalk00018.png similarity index 100% rename from game/resources/animated/hero/run/Chara_BlueWalk00018.png rename to resources/animated/hero/run/Chara_BlueWalk00018.png diff --git a/game/resources/animated/hero/run/Chara_BlueWalk00019.png b/resources/animated/hero/run/Chara_BlueWalk00019.png similarity index 100% rename from game/resources/animated/hero/run/Chara_BlueWalk00019.png rename to resources/animated/hero/run/Chara_BlueWalk00019.png diff --git a/game/resources/background/background_01/background_01.png b/resources/background/background_01/background_01.png similarity index 100% rename from game/resources/background/background_01/background_01.png rename to resources/background/background_01/background_01.png diff --git a/game/resources/background/background_01/background_02.png b/resources/background/background_01/background_02.png similarity index 100% rename from game/resources/background/background_01/background_02.png rename to resources/background/background_01/background_02.png diff --git a/game/resources/background/background_01/background_03.png b/resources/background/background_01/background_03.png similarity index 100% rename from game/resources/background/background_01/background_03.png rename to resources/background/background_01/background_03.png diff --git a/game/resources/background/background_01/background_04.png b/resources/background/background_01/background_04.png similarity index 100% rename from game/resources/background/background_01/background_04.png rename to resources/background/background_01/background_04.png diff --git a/game/resources/background/background_01/background_05.png b/resources/background/background_01/background_05.png similarity index 100% rename from game/resources/background/background_01/background_05.png rename to resources/background/background_01/background_05.png diff --git a/game/resources/background/background_01/background_06.png b/resources/background/background_01/background_06.png similarity index 100% rename from game/resources/background/background_01/background_06.png rename to resources/background/background_01/background_06.png diff --git a/game/resources/background/background_01/background_07.png b/resources/background/background_01/background_07.png similarity index 100% rename from game/resources/background/background_01/background_07.png rename to resources/background/background_01/background_07.png diff --git a/game/resources/background/background_02/background_01.png b/resources/background/background_02/background_01.png similarity index 100% rename from game/resources/background/background_02/background_01.png rename to resources/background/background_02/background_01.png diff --git a/game/resources/background/background_02/background_02.png b/resources/background/background_02/background_02.png similarity index 100% rename from game/resources/background/background_02/background_02.png rename to resources/background/background_02/background_02.png diff --git a/game/resources/background/background_02/background_03.png b/resources/background/background_02/background_03.png similarity index 100% rename from game/resources/background/background_02/background_03.png rename to resources/background/background_02/background_03.png diff --git a/game/resources/background/background_02/background_04.png b/resources/background/background_02/background_04.png similarity index 100% rename from game/resources/background/background_02/background_04.png rename to resources/background/background_02/background_04.png diff --git a/game/resources/background/background_02/background_05.png b/resources/background/background_02/background_05.png similarity index 100% rename from game/resources/background/background_02/background_05.png rename to resources/background/background_02/background_05.png diff --git a/game/resources/background/background_02/background_06.png b/resources/background/background_02/background_06.png similarity index 100% rename from game/resources/background/background_02/background_06.png rename to resources/background/background_02/background_06.png diff --git a/game/resources/background/background_02/background_07.png b/resources/background/background_02/background_07.png similarity index 100% rename from game/resources/background/background_02/background_07.png rename to resources/background/background_02/background_07.png diff --git a/game/resources/background/background_02/background_08.png b/resources/background/background_02/background_08.png similarity index 100% rename from game/resources/background/background_02/background_08.png rename to resources/background/background_02/background_08.png diff --git a/game/resources/background/background_03/background_01.png b/resources/background/background_03/background_01.png similarity index 100% rename from game/resources/background/background_03/background_01.png rename to resources/background/background_03/background_01.png diff --git a/game/resources/background/background_03/background_02.png b/resources/background/background_03/background_02.png similarity index 100% rename from game/resources/background/background_03/background_02.png rename to resources/background/background_03/background_02.png diff --git a/game/resources/background/background_03/background_03.png b/resources/background/background_03/background_03.png similarity index 100% rename from game/resources/background/background_03/background_03.png rename to resources/background/background_03/background_03.png diff --git a/game/resources/background/background_03/background_04.png b/resources/background/background_03/background_04.png similarity index 100% rename from game/resources/background/background_03/background_04.png rename to resources/background/background_03/background_04.png diff --git a/game/resources/background/background_with_finish/background_01.png b/resources/background/background_with_finish/background_01.png similarity index 100% rename from game/resources/background/background_with_finish/background_01.png rename to resources/background/background_with_finish/background_01.png diff --git a/game/resources/background/background_with_finish/background_02.png b/resources/background/background_with_finish/background_02.png similarity index 100% rename from game/resources/background/background_with_finish/background_02.png rename to resources/background/background_with_finish/background_02.png diff --git a/game/resources/background/background_with_finish/background_03.png b/resources/background/background_with_finish/background_03.png similarity index 100% rename from game/resources/background/background_with_finish/background_03.png rename to resources/background/background_with_finish/background_03.png diff --git a/game/resources/background/background_with_finish/background_04.png b/resources/background/background_with_finish/background_04.png similarity index 100% rename from game/resources/background/background_with_finish/background_04.png rename to resources/background/background_with_finish/background_04.png diff --git a/game/resources/background/background_with_finish/background_05.png b/resources/background/background_with_finish/background_05.png similarity index 100% rename from game/resources/background/background_with_finish/background_05.png rename to resources/background/background_with_finish/background_05.png diff --git a/game/resources/background/config_background/config_background_01 b/resources/background/config_background/config_background_01 similarity index 100% rename from game/resources/background/config_background/config_background_01 rename to resources/background/config_background/config_background_01 diff --git a/game/resources/background/config_background/config_background_02 b/resources/background/config_background/config_background_02 similarity index 100% rename from game/resources/background/config_background/config_background_02 rename to resources/background/config_background/config_background_02 diff --git a/game/resources/background/config_background/config_background_03 b/resources/background/config_background/config_background_03 similarity index 100% rename from game/resources/background/config_background/config_background_03 rename to resources/background/config_background/config_background_03 diff --git a/game/resources/background/config_background/config_background_with_finish b/resources/background/config_background/config_background_with_finish similarity index 100% rename from game/resources/background/config_background/config_background_with_finish rename to resources/background/config_background/config_background_with_finish diff --git a/game/resources/decoration/config_decoration/config_decoration_01 b/resources/decoration/config_decoration/config_decoration_01 similarity index 100% rename from game/resources/decoration/config_decoration/config_decoration_01 rename to resources/decoration/config_decoration/config_decoration_01 diff --git a/game/resources/decoration/config_decoration/config_decoration_02 b/resources/decoration/config_decoration/config_decoration_02 similarity index 100% rename from game/resources/decoration/config_decoration/config_decoration_02 rename to resources/decoration/config_decoration/config_decoration_02 diff --git a/game/resources/decoration/config_decoration/config_decoration_03 b/resources/decoration/config_decoration/config_decoration_03 similarity index 100% rename from game/resources/decoration/config_decoration/config_decoration_03 rename to resources/decoration/config_decoration/config_decoration_03 diff --git a/resources/decoration/decoration_01/arrow.png b/resources/decoration/decoration_01/arrow.png new file mode 100644 index 0000000..8e35818 Binary files /dev/null and b/resources/decoration/decoration_01/arrow.png differ diff --git a/resources/decoration/decoration_01/gross.png b/resources/decoration/decoration_01/gross.png new file mode 100644 index 0000000..4dd9a14 Binary files /dev/null and b/resources/decoration/decoration_01/gross.png differ diff --git a/resources/decoration/decoration_01/head.png b/resources/decoration/decoration_01/head.png new file mode 100644 index 0000000..d25abaa Binary files /dev/null and b/resources/decoration/decoration_01/head.png differ diff --git a/game/resources/decoration/decoration_01/stone.png b/resources/decoration/decoration_03/stone.png similarity index 100% rename from game/resources/decoration/decoration_01/stone.png rename to resources/decoration/decoration_03/stone.png diff --git a/game/resources/decoration/decoration_01/tree.png b/resources/decoration/decoration_03/tree.png similarity index 100% rename from game/resources/decoration/decoration_01/tree.png rename to resources/decoration/decoration_03/tree.png diff --git a/resources/levels/level_01/config.json b/resources/levels/level_01/config.json new file mode 100644 index 0000000..e6c7b3d --- /dev/null +++ b/resources/levels/level_01/config.json @@ -0,0 +1,170 @@ +{ + "name" : "level_01", + "animated_resources" : "../../resources/animated/", + "block" : 10.0, + "static_resources" : "../../resources/static/block_01", + "decoration_resources" : "../../resources/decoration/decoration_01", + "camera": { + "position" : { + "x" : 10.0, + "y" : 10.0 + }, + "smoothness": 0.05, + "zoom": 0.1, + "follow_type" : "forward", + "minimal_distance" : 7.0, + "part_of_window" : 0.25 + }, + "background" : { + "source" : "../../resources/background/background_01", + "parallax_ratios" : [0.95, 0.9, 0.85, 0.8, 0.75, 0.7, 0.65] + }, + "texture" : { + "unstable_block" : "unstable_block.png", + "ground_block" : "ground_block.png", + "finish_block" : "finish_block.png", + "begin_block" : "begin_block.png", + "middle_block" : "middle_block.png", + "end_block" : "end_block.png", + "separate_block" : "separate_block.png" + }, + "decoration" : { + "decoration_01" : { + "source" : "arrow.png", + "scale" : 1, + "delta_x" : 0, + "delta_y" : 20 + }, + "decoration_02" : { + "source" : "head.png", + "scale" : 1, + "delta_x" : 0, + "delta_y" : 90 + }, + "decoration_03" : { + "source" : "gross.png", + "scale" : 1, + "delta_x" : 0, + "delta_y" : 0 + } + }, + "hero" : { + "source" : "hero", + "animated" : { + "size_width": 5.5, + "size_height": 9, + "size_scale": 0.3, + "delta_x" : 0, + "delta_y" : 3, + "actions" : { + "idle" : { + "source": "hero_idle", + "type": "several_files", + "delta_time": 200 + }, + "run" : { + "source": "hero_run", + "type": "several_files", + "delta_time": 130 + }, + "jump" : { + "source": "hero_jump", + "type": "several_files", + "delta_time": 50 + }, + "fly_up" : { + "source": "hero_fly_up", + "type": "several_files", + "delta_time": 100 + }, + "fall" : { + "source": "hero_fall", + "type": "several_files", + "delta_time": 130 + }, + "attack_1_beg" : { + "source": "hero_attack_1_beg", + "type": "several_files", + "delta_time": 30 + }, + "attack_1_end" : { + "source": "hero_attack_1_end", + "type": "several_files", + "delta_time": 30 + }, + "attack_2_beg" : { + "source": "hero_attack_2_beg", + "type": "several_files", + "delta_time": 30 + }, + "attack_2_end" : { + "source": "hero_attack_2_end", + "type": "several_files", + "delta_time": 30 + }, + "attack_3_beg" : { + "source": "hero_attack_3_beg", + "type": "several_files", + "delta_time": 30 + }, + "attack_3_end" : { + "source": "hero_attack_3_end", + "type": "several_files", + "delta_time": 30 + }, + "hurt" : { + "source": "hero_hurt", + "type": "several_files", + "delta_time": 130 + }, + "die" : { + "source": "hero_die", + "type": "several_files", + "delta_time": 130 + } + } + } + }, + "enemy" : { + "source" : "enemy", + "animated" : { + "size_width": 5.5, + "size_height": 5, + "size_scale": 0.3, + "delta_x" : 0, + "delta_y" : 3, + "actions" : { + "idle" : { + "source": "enemy_idle", + "type": "several_files", + "delta_time": 200 + }, + "run" : { + "source": "enemy_run", + "type": "several_files", + "delta_time": 130 + }, + "attack_beg" : { + "source": "enemy_attack_beg", + "type": "several_files", + "delta_time": 100 + }, + "attack_end" : { + "source": "enemy_attack_end", + "type": "several_files", + "delta_time": 100 + }, + "hurt" : { + "source": "enemy_hurt", + "type": "several_files", + "delta_time": 100 + }, + "die" : { + "source": "enemy_die", + "type": "several_files", + "delta_time": 100 + } + } + } + } +} \ No newline at end of file diff --git a/resources/levels/level_01/map b/resources/levels/level_01/map new file mode 100644 index 0000000..fc311bf --- /dev/null +++ b/resources/levels/level_01/map @@ -0,0 +1,11 @@ +......H.................................................*....^....E.............................................................................................................................................................................................................................................. +......................................................[______________]........................................................................................................................................................................................................................................................ +.................................................+++................................................................._.......................................................................................................................................................................................... +.*....^.....E...F.............................+............................^........^.....E..........................._.......................................................................................................................................................................................... +[_________________]....^....&......E..^....+.............................[____________________]......................_.................................................................................................................................................................................................................................. +......................[_________________].............................................................................._........................ +................................................................................................[_______________________... +..............................................................................................+ +............................................................................................+............................. +.......................................................................................................................... +............................................................................................................................................................................ diff --git a/resources/levels/level_02/config.json b/resources/levels/level_02/config.json new file mode 100644 index 0000000..db15eca --- /dev/null +++ b/resources/levels/level_02/config.json @@ -0,0 +1,164 @@ +{ + "name" : "level_02", + "animated_resources" : "../../resources/animated/", + "static_resources" : "../../resources/static/block_02", + "decoration_resources" : "../../resources/decoration/decoration_03", + "block" : 10.0, + "camera": { + "position" : { + "x" : 10.0, + "y" : 10.0 + }, + "smoothness": 0.1, + "zoom": 0.1, + "follow_type" : "forward", + "minimal_distance" : 3.0, + "part_of_window" : 0.25 + }, + "background" : { + "source" : "../../resources/background/background_02", + "parallax_ratios" : [0.95, 0.9, 0.85, 0.8, 0.75, 0.7, 0.65, 0.6] + }, + "texture" : { + "unstable_block" : "block.png", + "ground_block" : "block.png", + "finish_block" : "finish_block.png", + "begin_block" : "block.png", + "middle_block" : "block.png", + "end_block" : "block.png", + "separate_block" : "block.png" + }, + "decoration" : { + "decoration_01" : { + "source" : "tree.png", + "scale" : 1, + "delta_x" : 0, + "delta_y" : 5 + }, + "decoration_02" : { + "source" : "stone.png", + "scale" : 1, + "delta_x" : 0, + "delta_y" : -20 + } + }, + "hero" : { + "source" : "hero", + "animated" : { + "size_width": 5.5, + "size_height": 9, + "size_scale": 0.3, + "delta_x" : 0, + "delta_y" : 3, + "actions" : { + "idle" : { + "source": "hero_idle", + "type": "several_files", + "delta_time": 200 + }, + "run" : { + "source": "hero_run", + "type": "several_files", + "delta_time": 130 + }, + "jump" : { + "source": "hero_jump", + "type": "several_files", + "delta_time": 50 + }, + "fly_up" : { + "source": "hero_fly_up", + "type": "several_files", + "delta_time": 100 + }, + "fall" : { + "source": "hero_fall", + "type": "several_files", + "delta_time": 130 + }, + "attack_1_beg" : { + "source": "hero_attack_1_beg", + "type": "several_files", + "delta_time": 30 + }, + "attack_1_end" : { + "source": "hero_attack_1_end", + "type": "several_files", + "delta_time": 30 + }, + "attack_2_beg" : { + "source": "hero_attack_2_beg", + "type": "several_files", + "delta_time": 30 + }, + "attack_2_end" : { + "source": "hero_attack_2_end", + "type": "several_files", + "delta_time": 30 + }, + "attack_3_beg" : { + "source": "hero_attack_3_beg", + "type": "several_files", + "delta_time": 30 + }, + "attack_3_end" : { + "source": "hero_attack_3_end", + "type": "several_files", + "delta_time": 30 + }, + "hurt" : { + "source": "hero_hurt", + "type": "several_files", + "delta_time": 130 + }, + "die" : { + "source": "hero_die", + "type": "several_files", + "delta_time": 130 + } + } + } + }, + "enemy" : { + "source" : "enemy", + "animated" : { + "size_width": 5.5, + "size_height": 5, + "size_scale": 0.3, + "delta_x" : 0, + "delta_y" : 3, + "actions" : { + "idle" : { + "source": "enemy_idle", + "type": "several_files", + "delta_time": 200 + }, + "run" : { + "source": "enemy_run", + "type": "several_files", + "delta_time": 130 + }, + "attack_beg" : { + "source": "enemy_attack_beg", + "type": "several_files", + "delta_time": 30 + }, + "attack_end" : { + "source": "enemy_attack_end", + "type": "several_files", + "delta_time": 30 + }, + "hurt" : { + "source": "enemy_hurt", + "type": "several_files", + "delta_time": 30 + }, + "die" : { + "source": "enemy_die", + "type": "several_files", + "delta_time": 30 + } + } + } + } +} \ No newline at end of file diff --git a/resources/levels/level_02/map b/resources/levels/level_02/map new file mode 100644 index 0000000..7af544b --- /dev/null +++ b/resources/levels/level_02/map @@ -0,0 +1,8 @@ +@......H........................... +.................................... +.................................... +.................................... +...........E........................ +.....[__________]..+..+...[]..F..... +.....############.........##........ +[__]......................##........ \ No newline at end of file diff --git a/resources/levels/level_03/config.json b/resources/levels/level_03/config.json new file mode 100644 index 0000000..5ebd481 --- /dev/null +++ b/resources/levels/level_03/config.json @@ -0,0 +1,164 @@ +{ + "name" : "level_03", + "animated_resources" : "../../resources/animated/", + "static_resources" : "../../resources/static/block_03", + "decoration_resources" : "../../resources/decoration/decoration_03", + "block" : 10.0, + "camera": { + "position" : { + "x" : 10.0, + "y" : 10.0 + }, + "smoothness": 0.1, + "zoom": 0.1, + "follow_type" : "forward", + "minimal_distance" : 3.0, + "part_of_window" : 0.25 + }, + "background" : { + "source" : "../../resources/background/background_03", + "parallax_ratios" : [0.95, 0.9, 0.85, 0.8] + }, + "texture" : { + "unstable_block" : "unstable_block.png", + "ground_block" : "ground_block.png", + "finish_block" : "finish_block.png", + "begin_block" : "begin_block.png", + "middle_block" : "middle_block.png", + "end_block" : "end_block.png", + "separate_block" : "separate_block.png" + }, + "decoration" : { + "decoration_01" : { + "source" : "tree.png", + "scale" : 1, + "delta_x" : 0, + "delta_y" : 5 + }, + "decoration_02" : { + "source" : "stone.png", + "scale" : 1, + "delta_x" : 0, + "delta_y" : -20 + } + }, + "hero" : { + "source" : "hero", + "animated" : { + "size_width": 5.5, + "size_height": 9, + "size_scale": 0.3, + "delta_x" : 0, + "delta_y" : 3, + "actions" : { + "idle" : { + "source": "hero_idle", + "type": "several_files", + "delta_time": 200 + }, + "run" : { + "source": "hero_run", + "type": "several_files", + "delta_time": 130 + }, + "jump" : { + "source": "hero_jump", + "type": "several_files", + "delta_time": 50 + }, + "fly_up" : { + "source": "hero_fly_up", + "type": "several_files", + "delta_time": 100 + }, + "fall" : { + "source": "hero_fall", + "type": "several_files", + "delta_time": 130 + }, + "attack_1_beg" : { + "source": "hero_attack_1_beg", + "type": "several_files", + "delta_time": 30 + }, + "attack_1_end" : { + "source": "hero_attack_1_end", + "type": "several_files", + "delta_time": 30 + }, + "attack_2_beg" : { + "source": "hero_attack_2_beg", + "type": "several_files", + "delta_time": 30 + }, + "attack_2_end" : { + "source": "hero_attack_2_end", + "type": "several_files", + "delta_time": 30 + }, + "attack_3_beg" : { + "source": "hero_attack_3_beg", + "type": "several_files", + "delta_time": 30 + }, + "attack_3_end" : { + "source": "hero_attack_3_end", + "type": "several_files", + "delta_time": 30 + }, + "hurt" : { + "source": "hero_hurt", + "type": "several_files", + "delta_time": 130 + }, + "die" : { + "source": "hero_die", + "type": "several_files", + "delta_time": 130 + } + } + } + }, + "enemy" : { + "source" : "enemy", + "animated" : { + "size_width": 5.5, + "size_height": 5, + "size_scale": 0.3, + "delta_x" : 0, + "delta_y" : 3, + "actions" : { + "idle" : { + "source": "enemy_idle", + "type": "several_files", + "delta_time": 200 + }, + "run" : { + "source": "enemy_run", + "type": "several_files", + "delta_time": 130 + }, + "attack_beg" : { + "source": "enemy_attack_beg", + "type": "several_files", + "delta_time": 30 + }, + "attack_end" : { + "source": "enemy_attack_end", + "type": "several_files", + "delta_time": 30 + }, + "hurt" : { + "source": "enemy_hurt", + "type": "several_files", + "delta_time": 30 + }, + "die" : { + "source": "enemy_die", + "type": "several_files", + "delta_time": 30 + } + } + } + } +} \ No newline at end of file diff --git a/game/resources/levels/level_01/map b/resources/levels/level_03/map similarity index 62% rename from game/resources/levels/level_01/map rename to resources/levels/level_03/map index 02896b6..97d8a5f 100644 --- a/game/resources/levels/level_01/map +++ b/resources/levels/level_03/map @@ -1,8 +1,8 @@ @......H..#..#...................... .................................... .................................... -.................................F.. -.......&.....*...................... -.....[__________].....+...[]........ +.................................... +.......&..E..*...................... +.....[__________]..+..+..[]......... .....############.........##........ [__]......................##........ \ No newline at end of file diff --git a/resources/levels/level_demo_01/config.json b/resources/levels/level_demo_01/config.json new file mode 100644 index 0000000..b3692eb --- /dev/null +++ b/resources/levels/level_demo_01/config.json @@ -0,0 +1,164 @@ +{ + "name" : "level_03", + "animated_resources" : "../../resources/animated/", + "static_resources" : "../../resources/static/block_03", + "decoration_resources" : "../../resources/decoration/decoration_03", + "block" : 10.0, + "camera": { + "position" : { + "x" : 10.0, + "y" : 10.0 + }, + "smoothness": 0.1, + "zoom": 0.1, + "follow_type" : "forward", + "minimal_distance" : 3.0, + "part_of_window" : 0.1 + }, + "background" : { + "source" : "../../resources/background/background_01", + "parallax_ratios" : [0.95, 0.9, 0.85, 0.8] + }, + "texture" : { + "unstable_block" : "unstable_block.png", + "ground_block" : "ground_block.png", + "finish_block" : "finish_block.png", + "begin_block" : "begin_block.png", + "middle_block" : "middle_block.png", + "end_block" : "end_block.png", + "separate_block" : "separate_block.png" + }, + "decoration" : { + "decoration_01" : { + "source" : "tree.png", + "scale" : 1, + "delta_x" : 0, + "delta_y" : 5 + }, + "decoration_02" : { + "source" : "stone.png", + "scale" : 1, + "delta_x" : 0, + "delta_y" : -20 + } + }, + "hero" : { + "source" : "hero", + "animated" : { + "size_width": 5.5, + "size_height": 9, + "size_scale": 0.3, + "delta_x" : 0, + "delta_y" : 3, + "actions" : { + "idle" : { + "source": "hero_idle", + "type": "several_files", + "delta_time": 200 + }, + "run" : { + "source": "hero_run", + "type": "several_files", + "delta_time": 130 + }, + "jump" : { + "source": "hero_jump", + "type": "several_files", + "delta_time": 50 + }, + "fly_up" : { + "source": "hero_fly_up", + "type": "several_files", + "delta_time": 100 + }, + "fall" : { + "source": "hero_fall", + "type": "several_files", + "delta_time": 130 + }, + "attack_1_beg" : { + "source": "hero_attack_1_beg", + "type": "several_files", + "delta_time": 30 + }, + "attack_1_end" : { + "source": "hero_attack_1_end", + "type": "several_files", + "delta_time": 30 + }, + "attack_2_beg" : { + "source": "hero_attack_2_beg", + "type": "several_files", + "delta_time": 30 + }, + "attack_2_end" : { + "source": "hero_attack_2_end", + "type": "several_files", + "delta_time": 30 + }, + "attack_3_beg" : { + "source": "hero_attack_3_beg", + "type": "several_files", + "delta_time": 30 + }, + "attack_3_end" : { + "source": "hero_attack_3_end", + "type": "several_files", + "delta_time": 30 + }, + "hurt" : { + "source": "hero_hurt", + "type": "several_files", + "delta_time": 130 + }, + "die" : { + "source": "hero_die", + "type": "several_files", + "delta_time": 130 + } + } + } + }, + "enemy" : { + "source" : "enemy", + "animated" : { + "size_width": 5.5, + "size_height": 5, + "size_scale": 0.3, + "delta_x" : 0, + "delta_y" : 3, + "actions" : { + "idle" : { + "source": "enemy_idle", + "type": "several_files", + "delta_time": 200 + }, + "run" : { + "source": "enemy_run", + "type": "several_files", + "delta_time": 130 + }, + "attack_beg" : { + "source": "enemy_attack_beg", + "type": "several_files", + "delta_time": 30 + }, + "attack_end" : { + "source": "enemy_attack_end", + "type": "several_files", + "delta_time": 30 + }, + "hurt" : { + "source": "enemy_hurt", + "type": "several_files", + "delta_time": 30 + }, + "die" : { + "source": "enemy_die", + "type": "several_files", + "delta_time": 30 + } + } + } + } +} \ No newline at end of file diff --git a/resources/levels/level_demo_01/map b/resources/levels/level_demo_01/map new file mode 100644 index 0000000..fcaa6fc --- /dev/null +++ b/resources/levels/level_demo_01/map @@ -0,0 +1,13 @@ +.....................############............................. +.....................############............................. +.....................############............................. +.....................############............................. +......................##########.............................. +..........................#####............................... +..........................#####.........@...................F. +...H............E............E.._..............E..........[__] +........[___..[_____]...._______#..@.._____________]..[___###. +________####...........[_########.....#############....######. +############...........############################....######. +############...........############################....######. +############################################################## \ No newline at end of file diff --git a/resources/levels/level_demo_02/config.json b/resources/levels/level_demo_02/config.json new file mode 100644 index 0000000..1cce7f3 --- /dev/null +++ b/resources/levels/level_demo_02/config.json @@ -0,0 +1,164 @@ +{ + "name" : "level_02", + "animated_resources" : "../../resources/animated/", + "static_resources" : "../../resources/static/block_02", + "decoration_resources" : "../../resources/decoration/decoration_03", + "block" : 10.0, + "camera": { + "position" : { + "x" : 10.0, + "y" : 10.0 + }, + "smoothness": 0.1, + "zoom": 0.1, + "follow_type" : "forward", + "minimal_distance" : 3.0, + "part_of_window" : 0.1 + }, + "background" : { + "source" : "../../resources/background/background_02", + "parallax_ratios" : [0.95, 0.9, 0.85, 0.8, 0.75, 0.7, 0.65, 0.6] + }, + "texture" : { + "unstable_block" : "block.png", + "ground_block" : "block.png", + "finish_block" : "finish_block.png", + "begin_block" : "block.png", + "middle_block" : "block.png", + "end_block" : "block.png", + "separate_block" : "block.png" + }, + "decoration" : { + "decoration_01" : { + "source" : "tree.png", + "scale" : 1, + "delta_x" : 0, + "delta_y" : 5 + }, + "decoration_02" : { + "source" : "stone.png", + "scale" : 1, + "delta_x" : 0, + "delta_y" : -20 + } + }, + "hero" : { + "source" : "hero", + "animated" : { + "size_width": 5.5, + "size_height": 9, + "size_scale": 0.3, + "delta_x" : 0, + "delta_y" : 3, + "actions" : { + "idle" : { + "source": "hero_idle", + "type": "several_files", + "delta_time": 200 + }, + "run" : { + "source": "hero_run", + "type": "several_files", + "delta_time": 130 + }, + "jump" : { + "source": "hero_jump", + "type": "several_files", + "delta_time": 50 + }, + "fly_up" : { + "source": "hero_fly_up", + "type": "several_files", + "delta_time": 100 + }, + "fall" : { + "source": "hero_fall", + "type": "several_files", + "delta_time": 130 + }, + "attack_1_beg" : { + "source": "hero_attack_1_beg", + "type": "several_files", + "delta_time": 30 + }, + "attack_1_end" : { + "source": "hero_attack_1_end", + "type": "several_files", + "delta_time": 30 + }, + "attack_2_beg" : { + "source": "hero_attack_2_beg", + "type": "several_files", + "delta_time": 30 + }, + "attack_2_end" : { + "source": "hero_attack_2_end", + "type": "several_files", + "delta_time": 30 + }, + "attack_3_beg" : { + "source": "hero_attack_3_beg", + "type": "several_files", + "delta_time": 30 + }, + "attack_3_end" : { + "source": "hero_attack_3_end", + "type": "several_files", + "delta_time": 30 + }, + "hurt" : { + "source": "hero_hurt", + "type": "several_files", + "delta_time": 130 + }, + "die" : { + "source": "hero_die", + "type": "several_files", + "delta_time": 130 + } + } + } + }, + "enemy" : { + "source" : "enemy", + "animated" : { + "size_width": 5.5, + "size_height": 5, + "size_scale": 0.3, + "delta_x" : 0, + "delta_y" : 3, + "actions" : { + "idle" : { + "source": "enemy_idle", + "type": "several_files", + "delta_time": 200 + }, + "run" : { + "source": "enemy_run", + "type": "several_files", + "delta_time": 130 + }, + "attack_beg" : { + "source": "enemy_attack_beg", + "type": "several_files", + "delta_time": 30 + }, + "attack_end" : { + "source": "enemy_attack_end", + "type": "several_files", + "delta_time": 30 + }, + "hurt" : { + "source": "enemy_hurt", + "type": "several_files", + "delta_time": 30 + }, + "die" : { + "source": "enemy_die", + "type": "several_files", + "delta_time": 30 + } + } + } + } +} \ No newline at end of file diff --git a/resources/levels/level_demo_02/map b/resources/levels/level_demo_02/map new file mode 100644 index 0000000..879b4bc --- /dev/null +++ b/resources/levels/level_demo_02/map @@ -0,0 +1,13 @@ +#@@@@................ +#@@@@................ +#@@@@................ +#.................... +##................... +###.................. +####................. +#####................ +######............... +#######.............. +####.H..EE........... +#######.@@@......F... +###########..[______] \ No newline at end of file diff --git a/resources/levels/level_with_finish/config.json b/resources/levels/level_with_finish/config.json new file mode 100644 index 0000000..eb16d6e --- /dev/null +++ b/resources/levels/level_with_finish/config.json @@ -0,0 +1,126 @@ +{ + "name" : "level_with_finish", + "animated_resources" : "../../resources/animated/", + "static_resources" : "../../resources/static/", + "block" : 10.0, + "camera": { + "position" : { + "x" : 10.0, + "y" : 10.0 + }, + "angle": 15.0, + "smoothness": 0.6, + "zoom": 10.5, + "follow_type" : "forward", + "minimal_distance" : 3.0, + "part_of_window" : 0.02 + }, + "background" : { + "source" : "../../resources/background/background_02", + "parallax_ratios" : [0.95, 0.9, 0.85, 0.8, 0.75] + }, + "texture" : { + "ground_block" : "brick.png", + "unstable_block" : "brick.png", + "finish_block" : "exit.png" + }, + "hero" : { + "source" : "hero", + "animated" : { + "size_width": 5.5, + "size_height": 9, + "size_scale": 0.3, + "delta_x" : 0, + "delta_y" : 3, + "actions" : { + "idle" : { + "source": "hero_idle", + "type": "several_files", + "delta_time": 200 + }, + "run" : { + "source": "hero_run", + "type": "several_files", + "delta_time": 130 + }, + "jump" : { + "source": "hero_jump", + "type": "several_files", + "delta_time": 50 + }, + "fly_up" : { + "source": "hero_fly_up", + "type": "several_files", + "delta_time": 100 + }, + "fall" : { + "source": "hero_fall", + "type": "several_files", + "delta_time": 130 + }, + "attack_1_beg" : { + "source": "hero_attack_1_beg", + "type": "several_files", + "delta_time": 30 + }, + "attack_1_end" : { + "source": "hero_attack_1_end", + "type": "several_files", + "delta_time": 30 + }, + "attack_2_beg" : { + "source": "hero_attack_2_beg", + "type": "several_files", + "delta_time": 30 + }, + "attack_2_end" : { + "source": "hero_attack_2_end", + "type": "several_files", + "delta_time": 30 + }, + "attack_3_beg" : { + "source": "hero_attack_3_beg", + "type": "several_files", + "delta_time": 30 + }, + "attack_3_end" : { + "source": "hero_attack_3_end", + "type": "several_files", + "delta_time": 30 + } + } + } + }, + "enemy" : { + "source" : "enemy", + "animated" : { + "size_width": 5.5, + "size_height": 9, + "size_scale": 0.3, + "delta_x" : 0, + "delta_y" : 3, + "actions" : { + "idle" : { + "source": "enemy_idle", + "type": "several_files", + "delta_time": 200 + }, + "run" : { + "source": "enemy_run", + "type": "several_files", + "delta_time": 130 + }, + "attack_beg" : { + "source": "enemy_attack_beg", + "type": "several_files", + "delta_time": 30 + }, + "attack_end" : { + "source": "enemy_attack_end", + "type": "several_files", + "delta_time": 30 + } + } + } + } +} \ No newline at end of file diff --git a/game/resources/levels/level_with_finish/map b/resources/levels/level_with_finish/map similarity index 79% rename from game/resources/levels/level_with_finish/map rename to resources/levels/level_with_finish/map index d02509d..613bf7f 100644 --- a/game/resources/levels/level_with_finish/map +++ b/resources/levels/level_with_finish/map @@ -1,5 +1,5 @@ #................# -#.H..............# +#.HE.............# #....#...........# #...##.#...#....F# ########..###..### \ No newline at end of file diff --git a/resources/static/block_01/begin_block.png b/resources/static/block_01/begin_block.png new file mode 100644 index 0000000..9036972 Binary files /dev/null and b/resources/static/block_01/begin_block.png differ diff --git a/resources/static/block_01/end_block.png b/resources/static/block_01/end_block.png new file mode 100644 index 0000000..c570171 Binary files /dev/null and b/resources/static/block_01/end_block.png differ diff --git a/game/resources/static/block_01/finish_block.png b/resources/static/block_01/finish_block.png similarity index 100% rename from game/resources/static/block_01/finish_block.png rename to resources/static/block_01/finish_block.png diff --git a/resources/static/block_01/ground_block.png b/resources/static/block_01/ground_block.png new file mode 100644 index 0000000..099f23b Binary files /dev/null and b/resources/static/block_01/ground_block.png differ diff --git a/resources/static/block_01/middle_block.png b/resources/static/block_01/middle_block.png new file mode 100644 index 0000000..d956cf8 Binary files /dev/null and b/resources/static/block_01/middle_block.png differ diff --git a/resources/static/block_01/separate_block.png b/resources/static/block_01/separate_block.png new file mode 100644 index 0000000..a955ed8 Binary files /dev/null and b/resources/static/block_01/separate_block.png differ diff --git a/resources/static/block_01/unstable_block.png b/resources/static/block_01/unstable_block.png new file mode 100644 index 0000000..b9b1054 Binary files /dev/null and b/resources/static/block_01/unstable_block.png differ diff --git a/resources/static/block_02/block.png b/resources/static/block_02/block.png new file mode 100644 index 0000000..8f79066 Binary files /dev/null and b/resources/static/block_02/block.png differ diff --git a/game/resources/static/block_03/finish_block.png b/resources/static/block_02/finish_block.png similarity index 100% rename from game/resources/static/block_03/finish_block.png rename to resources/static/block_02/finish_block.png diff --git a/game/resources/static/block_01/begin_block.png b/resources/static/block_03/begin_block.png similarity index 100% rename from game/resources/static/block_01/begin_block.png rename to resources/static/block_03/begin_block.png diff --git a/game/resources/static/block_01/end_block.png b/resources/static/block_03/end_block.png similarity index 100% rename from game/resources/static/block_01/end_block.png rename to resources/static/block_03/end_block.png diff --git a/game/resources/static/exit.png b/resources/static/block_03/finish_block.png similarity index 100% rename from game/resources/static/exit.png rename to resources/static/block_03/finish_block.png diff --git a/game/resources/static/block_01/ground_block.png b/resources/static/block_03/ground_block.png similarity index 100% rename from game/resources/static/block_01/ground_block.png rename to resources/static/block_03/ground_block.png diff --git a/game/resources/static/block_01/middle_block.png b/resources/static/block_03/middle_block.png similarity index 100% rename from game/resources/static/block_01/middle_block.png rename to resources/static/block_03/middle_block.png diff --git a/game/resources/static/block_01/separate_block.png b/resources/static/block_03/separate_block.png similarity index 100% rename from game/resources/static/block_01/separate_block.png rename to resources/static/block_03/separate_block.png diff --git a/resources/static/block_03/unstable_block.png b/resources/static/block_03/unstable_block.png new file mode 100644 index 0000000..b9b1054 Binary files /dev/null and b/resources/static/block_03/unstable_block.png differ diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 07bb365..bc2aa5e 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -18,6 +18,7 @@ function(test_executable EXECUTABLE_TEST_NAME EXECUTABLE_SOURCES) ${INCLUDE_IMGUI} ${INCLUDE_IMGUI_SFML} ${INCLUDE_PQXX} + ${INCLUDE_HTTP} ) target_link_libraries( diff --git a/test/deps/CMakeLists.txt b/test/deps/CMakeLists.txt index 3078da8..817960a 100644 --- a/test/deps/CMakeLists.txt +++ b/test/deps/CMakeLists.txt @@ -1,3 +1,5 @@ test_executable(test-box2d TestBox2d.cpp) test_executable(test-imgui TestImGui.cpp) test_executable(test-pqxx TestPQXX.cpp) +test_executable(test-server network/server.cpp) +test_executable(test-client network/client.cpp) diff --git a/test/deps/network/client.cpp b/test/deps/network/client.cpp new file mode 100644 index 0000000..198b44a --- /dev/null +++ b/test/deps/network/client.cpp @@ -0,0 +1,22 @@ +#include +#include + +int main() { + httplib::Client cli("localhost", 8080); + + auto res1 = cli.Post("/user/login", httplib::Params{ + {"username", "Denis"} + }); + std::cout << res1->status << ' ' << res1->body << '\n'; + + + auto res2 = cli.Post("/user/login", httplib::Params{ + {"username", "NoDenis"} + }); + std::cout << res2->status << ' ' << res2->body << '\n'; + + auto res3 = cli.Post("/user/login", httplib::Params{ + {"name", "Denis"} + }); + std::cout << res3->status << ' ' << res3->body << '\n'; +} diff --git a/test/deps/network/server.cpp b/test/deps/network/server.cpp new file mode 100644 index 0000000..e4038c3 --- /dev/null +++ b/test/deps/network/server.cpp @@ -0,0 +1,155 @@ +#include +#include +#include + +namespace mad::core { + class Database { + public: + Database(); + + bool is_user_exists(const std::string &username); + + void registry_user(const std::string &username); + + std::size_t get_id(const std::string &username); + + std::size_t get_progress(std::size_t id); + + std::size_t get_progress(const std::string &username); + + void increment_progress(std::size_t id); + + void increment_progress(const std::string &username); + + void reset_progress(std::size_t id); + + void reset_progress(const std::string &username); + + private: + pqxx::connection m_connector; + std::string m_query; + + }; +} + +namespace mad::core { + + Database::Database() : m_connector("dbname = test-network") { + try { + if (m_connector.is_open()) { + SPDLOG_DEBUG("Database mad opened successfully"); + } else { + SPDLOG_DEBUG("Can't open database mad"); + } + + pqxx::work w(m_connector); + + m_query = "CREATE TABLE IF NOT EXISTS users(" + "id SMALLINT PRIMARY KEY," + "name TEXT NOT NULL UNIQUE);"; + w.exec(m_query); + + m_query = "CREATE TABLE IF NOT EXISTS progress(" + "id SMALLINT PRIMARY KEY REFERENCES users (id)," + "levels_completed SMALLINT NOT NULL);"; + w.exec(m_query); + + w.commit(); + + SPDLOG_DEBUG("Tables created successfully"); + } catch (std::exception &exc) { + SPDLOG_INFO(exc.what()); + } + } + + bool Database::is_user_exists(const std::string &username) { + pqxx::work W(m_connector); + m_query = "SELECT * FROM users WHERE name = '" + W.esc(username) + "';"; + pqxx::result rows_found = W.exec(m_query); + return !rows_found.empty(); + } + + void Database::registry_user(const std::string &username) { + pqxx::work W(m_connector); + + m_query = "SELECT id FROM users"; + pqxx::result total_rows = W.exec(m_query); + std::size_t id = total_rows.size(); + + m_query = "INSERT INTO users(id, name) VALUES(" + std::to_string(id) + ", '" + W.esc(username) + "');"; + W.exec(m_query); + + m_query = "INSERT INTO progress(id, levels_completed) VALUES(" + std::to_string(id) + ", 0);"; + W.exec(m_query); + + W.commit(); + } + + std::size_t Database::get_id(const std::string &username) { + pqxx::work W(m_connector); + m_query = "SELECT * FROM users WHERE name = '" + W.esc(username) + "';"; + auto found_row = W.exec1(m_query); + return found_row["id"].as(); + } + + std::size_t Database::get_progress(std::size_t id) { + pqxx::work W(m_connector); + m_query = "SELECT * FROM progress WHERE id = " + std::to_string(id) + ";"; + auto found_row = W.exec1(m_query); + return found_row["levels_completed"].as(); + } + + std::size_t Database::get_progress(const std::string &username) { + return get_progress(get_id(username)); + } + + void Database::increment_progress(std::size_t id) { + pqxx::work W(m_connector); + m_query = "UPDATE progress " + "SET levels_completed = levels_completed + 1 " + "WHERE id = " + std::to_string(id) + ";"; + W.exec(m_query); + W.commit(); + } + + void Database::increment_progress(const std::string &username) { + increment_progress(get_id(username)); + } + + void Database::reset_progress(std::size_t id) { + pqxx::work W(m_connector); + m_query = "UPDATE progress " + "SET levels_completed = 0 " + "WHERE id = " + std::to_string(id) + ";"; + W.exec(m_query); + W.commit(); + } + + void Database::reset_progress(const std::string &username) { + reset_progress(get_id(username)); + } +} + +int main() { + httplib::Server svr; + mad::core::Database db; + + svr.Post("/user/login", [&db](const httplib::Request &req, httplib::Response &res) { + if (req.has_param("username")) { + auto username = req.get_param_value("username"); + if (db.is_user_exists(username)) { + res.status = 200; + res.body = "OK"; + } else { + res.status = 404; + res.body = "User doesn\'t exists"; + } + } else { + res.status = 404; + res.body = "Invalid params of request"; + } + }); + + + svr.listen("localhost", 8080); +} \ No newline at end of file