From 6b504e3212352dd8b96c996e0e5006cfa33da186 Mon Sep 17 00:00:00 2001 From: Flavien Chenu Date: Tue, 26 Mar 2024 13:12:42 +0100 Subject: [PATCH 01/33] feat(games): add SnakeGame provider and common games classes --- games/common/CMakeLists.txt | 5 ++ games/common/game/AGame.cpp | 39 ++++++++++++++ games/common/game/AGame.hpp | 71 ++++++++++++++++++++++++++ games/snake/CMakeLists.txt | 11 ++-- games/snake/export.cpp | 7 +-- games/snake/src/SnakeGame.cpp | 39 ++++++++++++++ games/snake/src/SnakeGame.hpp | 41 +++++++++++++++ games/snake/src/SnakeGameProvider.cpp | 19 +++++++ games/snake/src/SnakeGameProvider.hpp | 35 +++++++++++++ shared/games/IGame.hpp | 6 --- shared/graphics/IGraphicsProvider.hpp | 13 ++--- shared/graphics/window/IWindow.hpp | 5 +- shared/graphics/window/IWindowIcon.hpp | 17 ------ 13 files changed, 266 insertions(+), 42 deletions(-) create mode 100644 games/common/CMakeLists.txt create mode 100644 games/common/game/AGame.cpp create mode 100644 games/common/game/AGame.hpp create mode 100644 games/snake/src/SnakeGame.cpp create mode 100644 games/snake/src/SnakeGame.hpp create mode 100644 games/snake/src/SnakeGameProvider.cpp create mode 100644 games/snake/src/SnakeGameProvider.hpp delete mode 100644 shared/graphics/window/IWindowIcon.hpp diff --git a/games/common/CMakeLists.txt b/games/common/CMakeLists.txt new file mode 100644 index 0000000..5df3b36 --- /dev/null +++ b/games/common/CMakeLists.txt @@ -0,0 +1,5 @@ +target_sources(${PROJECT_NAME} PUBLIC + game/AGame.cpp + game/AGame.hpp +) +target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_LIST_DIR}/../..) diff --git a/games/common/game/AGame.cpp b/games/common/game/AGame.cpp new file mode 100644 index 0000000..371714f --- /dev/null +++ b/games/common/game/AGame.cpp @@ -0,0 +1,39 @@ +/* +** EPITECH PROJECT, 2024 +** arcade +** File description: +** AGame.cpp +*/ + +#include "AGame.hpp" + +#include + +using namespace arcade::games; + +common::AGame::AGame(shared::types::Vector2u size) : _size(size) { + this->_entities = {}; +} + +const shared::games::entity::EntitiesMap &common::AGame::getEntities() const { + return this->_entities; +} + +common::EntityPtr common::AGame::getEntityById(const shared::types::UUId &id) const { + try { + return this->_entities.at(id); + } catch (std::out_of_range &e) { + return nullptr; + } +} + +const shared::types::Vector2u common::AGame::getSize() const noexcept { + return this->_size; +} + +shared::types::UUId common::AGame::_registerEntity(EntityPtr entity) { + const shared::types::UUId id; + + this->_entities[id] = std::move(entity); + return id; +} diff --git a/games/common/game/AGame.hpp b/games/common/game/AGame.hpp new file mode 100644 index 0000000..0700ef5 --- /dev/null +++ b/games/common/game/AGame.hpp @@ -0,0 +1,71 @@ +/* +** EPITECH PROJECT, 2024 +** arcade +** File description: +** AGame.hpp +*/ + +#pragma once + +#include +#include "shared/games/IGame.hpp" +#include "shared/types/Vector.hpp" + +namespace arcade::games::common { + class AGame; + typedef std::shared_ptr EntityPtr; +} + +class arcade::games::common::AGame : public shared::games::IGame { +public: + ~AGame() override = default; + + /** + * @brief Get map of entities + * + * @return Map of entities + */ + const shared::games::entity::EntitiesMap &getEntities() const override; + + /** + * @brief Get game size (in tiles) + * + * @return Size of the game + */ + const shared::types::Vector2u getSize() const noexcept override; + + /** + * @brief Get entity by id + * + * @param id Id of the entity + * @return The specific entity + */ + EntityPtr getEntityById(const shared::types::UUId &id) const override; + +protected: + /** + * @brief Construct a new AGame object + * + * @param size Size of the game + */ + explicit AGame(shared::types::Vector2u size); + + /** + * @brief List of game entities + */ + shared::games::entity::EntitiesMap _entities; + + /** + * @brief Game size + */ + shared::types::Vector2u _size; + + /** + * @brief Add an entity to the game + * + * @param entity Entity to add + * @return Id of the entity + * @warning This method is moving ownership of the entity + */ + shared::types::UUId _registerEntity(EntityPtr entity); +}; diff --git a/games/snake/CMakeLists.txt b/games/snake/CMakeLists.txt index 619422c..d1593e6 100644 --- a/games/snake/CMakeLists.txt +++ b/games/snake/CMakeLists.txt @@ -1,5 +1,10 @@ -add_library(snake SHARED +project(snake) +add_library(${PROJECT_NAME} SHARED export.cpp + src/SnakeGameProvider.cpp + src/SnakeGame.cpp ) -target_include_directories(snake PUBLIC ${CMAKE_CURRENT_LIST_DIR}/src) -target_include_directories(snake PUBLIC ${CMAKE_CURRENT_LIST_DIR}/../..) +add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/../common PRIVATE) +target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_LIST_DIR}/src) +target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_LIST_DIR}/../..) +target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_LIST_DIR}/..) diff --git a/games/snake/export.cpp b/games/snake/export.cpp index f2f7054..a5fd8e6 100644 --- a/games/snake/export.cpp +++ b/games/snake/export.cpp @@ -5,6 +5,7 @@ ** export */ +#include "src/SnakeGameProvider.hpp" #include "shared/games/IGameProvider.hpp" #include "shared/types/Libraries.hpp" @@ -14,8 +15,8 @@ extern "C" { return shared::types::LibraryType::GAME; } -/* std::shared_ptr SHARED_GAME_PROVIDER_LOADER_NAME(void) + std::shared_ptr SHARED_GAME_PROVIDER_LOADER_NAME(void) { - return std::make_shared(...) - }*/ + return std::make_shared(); + } } diff --git a/games/snake/src/SnakeGame.cpp b/games/snake/src/SnakeGame.cpp new file mode 100644 index 0000000..65619cf --- /dev/null +++ b/games/snake/src/SnakeGame.cpp @@ -0,0 +1,39 @@ +/* +** EPITECH PROJECT, 2024 +** arcade +** File description: +** SnakeGame.cpp +*/ + +#include +#include "SnakeGame.hpp" + +using namespace arcade::games; + +const shared::games::GameManifest snake::SnakeGame::manifest = { + .name = "Snake", + .description = "The snake original game", + .version = "0.0.1", + .authors = { + { + .name = "Flavien Chenu", + .email = "flavienchenu@epitech.eu", + .website = "https://github.com/flavien-chenu" + } + } +}; + +snake::SnakeGame::SnakeGame(): common::AGame(Vector2u(12, 12)) { + std::cout << "SnakeGame created" << std::endl; +} + +snake::SnakeGame::~SnakeGame() = default; + +const shared::games::GameManifest &snake::SnakeGame::getManifest() const noexcept { + return SnakeGame::manifest; +} + +void snake::SnakeGame::compute(shared::games::DeltaTime dt) { + std::cout << "SnakeGame::compute" << std::endl; + std::cout << "DeltaTime: " << dt << std::endl; +} diff --git a/games/snake/src/SnakeGame.hpp b/games/snake/src/SnakeGame.hpp new file mode 100644 index 0000000..b1ae049 --- /dev/null +++ b/games/snake/src/SnakeGame.hpp @@ -0,0 +1,41 @@ +/* +** EPITECH PROJECT, 2024 +** arcade +** File description: +** SnakeGame.hpp +*/ + +#pragma once + +#include "common/game/AGame.hpp" + +namespace arcade::games::snake { + class SnakeGame; +} + +class arcade::games::snake::SnakeGame : public arcade::games::common::AGame { +public: + SnakeGame(); + + ~SnakeGame() override; + + /** + * @brief Game manifest + * + */ + static const shared::games::GameManifest manifest; + + /** + * @brief Get the manifest object + * + * @return const shared::games::GameManifest& + */ + const shared::games::GameManifest &getManifest() const noexcept override; + + /** + * @brief Allow game possible actions + * + * @param dt Delta time from last frame + */ + void compute(shared::games::DeltaTime dt) override; +}; diff --git a/games/snake/src/SnakeGameProvider.cpp b/games/snake/src/SnakeGameProvider.cpp new file mode 100644 index 0000000..33c7b54 --- /dev/null +++ b/games/snake/src/SnakeGameProvider.cpp @@ -0,0 +1,19 @@ +/* +** EPITECH PROJECT, 2024 +** arcade +** File description: +** SnakeGameProvider.cpp +*/ + +#include "SnakeGame.hpp" +#include "SnakeGameProvider.hpp" + +using namespace arcade::games; + +const shared::games::GameManifest &snake::SnakeGameProvider::getManifest() const noexcept { + return SnakeGame::manifest; +} + +std::shared_ptr snake::SnakeGameProvider::createInstance() { + return std::make_shared(); +} diff --git a/games/snake/src/SnakeGameProvider.hpp b/games/snake/src/SnakeGameProvider.hpp new file mode 100644 index 0000000..7523c7f --- /dev/null +++ b/games/snake/src/SnakeGameProvider.hpp @@ -0,0 +1,35 @@ +/* +** EPITECH PROJECT, 2024 +** arcade +** File description: +** SnakeGameProvider.hpp +*/ + +#pragma once + +#include "shared/games/IGameProvider.hpp" + +namespace arcade::games::snake { + class SnakeGameProvider; +} + +class arcade::games::snake::SnakeGameProvider : public shared::games::IGameProvider { +public: + SnakeGameProvider() = default; + + ~SnakeGameProvider() override = default; + + /** + * @brief Provides the game manifest + * + * @return Manifest of current game + */ + const shared::games::GameManifest &getManifest() const noexcept override; + + /** + * @brief Provides a new instance of the game + * + * @return Created game instance + */ + std::shared_ptr createInstance() override; +}; diff --git a/shared/games/IGame.hpp b/shared/games/IGame.hpp index d888a3f..291ac21 100644 --- a/shared/games/IGame.hpp +++ b/shared/games/IGame.hpp @@ -39,12 +39,6 @@ class shared::games::IGame */ virtual const GameManifest &getManifest(void) const noexcept = 0; - /** - * @brief The minimum window size required for the game (pixels) - * - */ - virtual const Vector2u getWindowMinSize(void) const noexcept = 0; - /** * @brief Number of tiles that represent the game * Tile size is managed by the renderer diff --git a/shared/graphics/IGraphicsProvider.hpp b/shared/graphics/IGraphicsProvider.hpp index eab2ca9..2d2b7cf 100644 --- a/shared/graphics/IGraphicsProvider.hpp +++ b/shared/graphics/IGraphicsProvider.hpp @@ -49,16 +49,9 @@ class shared::graphics::IGraphicsProvider { /** * @brief Create a texture object * - * @param path Path of the texture file + * @param bin Path of the binary texture file + * @param ascii Path of the ascii texture file * @return Created texture object */ - virtual std::shared_ptr createTexture(const std::string &path) = 0; - - /** - * @brief Create a window icon object - * - * @param path Path of the window icon file - * @return Created window icon object - */ - virtual std::unique_ptr createWindowIcon(const std::string &path) = 0; + virtual std::shared_ptr createTexture(const std::string &bin, const std::string &ascii) = 0; }; diff --git a/shared/graphics/window/IWindow.hpp b/shared/graphics/window/IWindow.hpp index 95fac0f..22f3fc3 100644 --- a/shared/graphics/window/IWindow.hpp +++ b/shared/graphics/window/IWindow.hpp @@ -10,7 +10,6 @@ #include #include -#include "IWindowIcon.hpp" #include "../events/IEvent.hpp" #include "../../types/types.hpp" #include "../types/EntityProps.hpp" @@ -101,14 +100,14 @@ class shared::graphics::IWindow { * * @param icon Icon to use */ - virtual void setIcon(std::unique_ptr icon) = 0; + virtual void setIcon(const std::string &icon) = 0; /** * @brief Get the icon of the window * * @return Icon object of the window */ - virtual const IWindowIcon &getIcon(void) const = 0; + virtual const std::string &getIcon(void) const = 0; /** * @brief Render the entity with given properties diff --git a/shared/graphics/window/IWindowIcon.hpp b/shared/graphics/window/IWindowIcon.hpp deleted file mode 100644 index 9dfdb83..0000000 --- a/shared/graphics/window/IWindowIcon.hpp +++ /dev/null @@ -1,17 +0,0 @@ -/* -** EPITECH PROJECT, 2024 -** arcade-shared -** File description: -** IWindowIcon -*/ - -#pragma once - -namespace shared::graphics { - class IWindowIcon; -} - -class shared::graphics::IWindowIcon { - public: - virtual ~IWindowIcon() = default; -}; From 10044388afac0bb5f285b04a5fdb019b75e8c59e Mon Sep 17 00:00:00 2001 From: Flavien Chenu Date: Tue, 26 Mar 2024 13:53:24 +0100 Subject: [PATCH 02/33] feat(games): add Snake class --- games/common/game/AGame.cpp | 7 ++----- games/common/game/AGame.hpp | 2 +- games/snake/CMakeLists.txt | 2 ++ games/snake/src/Snake.cpp | 16 +++++++++++++++ games/snake/src/Snake.hpp | 37 +++++++++++++++++++++++++++++++++++ games/snake/src/SnakeGame.cpp | 1 - 6 files changed, 58 insertions(+), 7 deletions(-) create mode 100644 games/snake/src/Snake.cpp create mode 100644 games/snake/src/Snake.hpp diff --git a/games/common/game/AGame.cpp b/games/common/game/AGame.cpp index 371714f..7030e8b 100644 --- a/games/common/game/AGame.cpp +++ b/games/common/game/AGame.cpp @@ -31,9 +31,6 @@ const shared::types::Vector2u common::AGame::getSize() const noexcept { return this->_size; } -shared::types::UUId common::AGame::_registerEntity(EntityPtr entity) { - const shared::types::UUId id; - - this->_entities[id] = std::move(entity); - return id; +void common::AGame::_registerEntity(EntityPtr entity) { + this->_entities[entity->getId()] = std::move(entity); } diff --git a/games/common/game/AGame.hpp b/games/common/game/AGame.hpp index 0700ef5..12aa183 100644 --- a/games/common/game/AGame.hpp +++ b/games/common/game/AGame.hpp @@ -67,5 +67,5 @@ class arcade::games::common::AGame : public shared::games::IGame { * @return Id of the entity * @warning This method is moving ownership of the entity */ - shared::types::UUId _registerEntity(EntityPtr entity); + void _registerEntity(EntityPtr entity); }; diff --git a/games/snake/CMakeLists.txt b/games/snake/CMakeLists.txt index d1593e6..33a7066 100644 --- a/games/snake/CMakeLists.txt +++ b/games/snake/CMakeLists.txt @@ -3,6 +3,8 @@ add_library(${PROJECT_NAME} SHARED export.cpp src/SnakeGameProvider.cpp src/SnakeGame.cpp + src/Snake.cpp + src/Snake.hpp ) add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/../common PRIVATE) target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_LIST_DIR}/src) diff --git a/games/snake/src/Snake.cpp b/games/snake/src/Snake.cpp new file mode 100644 index 0000000..be77d95 --- /dev/null +++ b/games/snake/src/Snake.cpp @@ -0,0 +1,16 @@ +/* +** EPITECH PROJECT, 2024 +** arcade +** File description: +** Snake.cpp +*/ + +#include "Snake.hpp" + +using namespace arcade::games::snake; + +Snake::Snake() { +} + +Snake::~Snake() { +} diff --git a/games/snake/src/Snake.hpp b/games/snake/src/Snake.hpp new file mode 100644 index 0000000..4eed44a --- /dev/null +++ b/games/snake/src/Snake.hpp @@ -0,0 +1,37 @@ +/* +** EPITECH PROJECT, 2024 +** arcade +** File description: +** Snake.hpp +*/ + +#pragma once + +#include +#include +#include + +#include "shared/types/UUId.hpp" +#include "common/game/AGame.hpp" + +namespace arcade::games::snake { + class Snake; +} + +class arcade::games::snake::Snake { +public: + Snake(); + ~Snake(); + + /** + * @brief Entities that compose the snake + * + */ + std::vector body; + + /** + * @brief Head of the snake + * + */ + common::EntityPtr head; +}; diff --git a/games/snake/src/SnakeGame.cpp b/games/snake/src/SnakeGame.cpp index 65619cf..947e6bc 100644 --- a/games/snake/src/SnakeGame.cpp +++ b/games/snake/src/SnakeGame.cpp @@ -24,7 +24,6 @@ const shared::games::GameManifest snake::SnakeGame::manifest = { }; snake::SnakeGame::SnakeGame(): common::AGame(Vector2u(12, 12)) { - std::cout << "SnakeGame created" << std::endl; } snake::SnakeGame::~SnakeGame() = default; From 56ec74059e5eecb2a151e2b8a43a5fcb8029107f Mon Sep 17 00:00:00 2001 From: Matheo Coquet Date: Wed, 27 Mar 2024 15:56:25 +0100 Subject: [PATCH 03/33] fix: compilation with new shared update --- CMakeLists.txt | 2 +- core/main.cpp | 29 +++--- games/common/game/AGame.cpp | 14 ++- games/common/game/AGame.hpp | 13 ++- games/snake/src/Snake.hpp | 1 - games/snake/src/SnakeGame.cpp | 26 +++--- games/snake/src/SnakeGame.hpp | 4 + shared/games/IEntity.hpp | 16 +--- shared/games/IGame.hpp | 20 +++-- shared/games/components/IComponent.hpp | 57 ++++++------ .../components/IDisplayableComponent.hpp | 78 ++++++---------- shared/games/components/ITextComponent.hpp | 53 +++++++++++ shared/games/components/ITextureComponent.hpp | 38 ++++++++ shared/games/types/GameManifest.hpp | 29 +++--- shared/graphics/IFont.hpp | 17 ++++ shared/graphics/IGraphicsProvider.hpp | 17 ++-- shared/graphics/ISound.hpp | 17 ++-- shared/graphics/ITexture.hpp | 2 +- shared/graphics/{window => }/IWindow.hpp | 59 ++++++------ shared/graphics/events/IEvent.hpp | 6 +- shared/graphics/events/IKeyEvent.hpp | 61 +++++++++++++ shared/graphics/events/IMouseButtonEvent.hpp | 31 +++++++ shared/graphics/events/IMouseEvent.hpp | 27 ++++++ shared/graphics/events/key/AKeyEvent.hpp | 87 ------------------ shared/graphics/events/key/KeyPressEvent.hpp | 19 ---- .../graphics/events/key/KeyReleaseEvent.hpp | 18 ---- .../events/mouse/AMouseButtonEvent.hpp | 39 -------- shared/graphics/events/mouse/AMouseEvent.hpp | 50 ----------- .../events/mouse/MouseButtonPressEvent.hpp | 24 ----- .../events/mouse/MouseButtonReleaseEvent.hpp | 24 ----- .../graphics/events/mouse/MouseMoveEvent.hpp | 22 ----- .../events/window/WindowCloseEvent.hpp | 29 ------ .../events/window/WindowResizeEvent.hpp | 43 --------- shared/graphics/types/EntityProps.hpp | 32 ------- shared/graphics/types/TextProps.hpp | 45 ++++++++++ shared/graphics/types/TextureProps.hpp | 25 ++++++ shared/types/Color.hpp | 19 ++++ shared/types/UUId.cpp | 63 ------------- shared/types/UUId.hpp | 89 ------------------- shared/types/types.hpp | 11 --- 40 files changed, 505 insertions(+), 751 deletions(-) create mode 100644 shared/games/components/ITextComponent.hpp create mode 100644 shared/games/components/ITextureComponent.hpp create mode 100644 shared/graphics/IFont.hpp rename shared/graphics/{window => }/IWindow.hpp (69%) create mode 100644 shared/graphics/events/IKeyEvent.hpp create mode 100644 shared/graphics/events/IMouseButtonEvent.hpp create mode 100644 shared/graphics/events/IMouseEvent.hpp delete mode 100644 shared/graphics/events/key/AKeyEvent.hpp delete mode 100644 shared/graphics/events/key/KeyPressEvent.hpp delete mode 100644 shared/graphics/events/key/KeyReleaseEvent.hpp delete mode 100644 shared/graphics/events/mouse/AMouseButtonEvent.hpp delete mode 100644 shared/graphics/events/mouse/AMouseEvent.hpp delete mode 100644 shared/graphics/events/mouse/MouseButtonPressEvent.hpp delete mode 100644 shared/graphics/events/mouse/MouseButtonReleaseEvent.hpp delete mode 100644 shared/graphics/events/mouse/MouseMoveEvent.hpp delete mode 100644 shared/graphics/events/window/WindowCloseEvent.hpp delete mode 100644 shared/graphics/events/window/WindowResizeEvent.hpp delete mode 100644 shared/graphics/types/EntityProps.hpp create mode 100644 shared/graphics/types/TextProps.hpp create mode 100644 shared/graphics/types/TextureProps.hpp create mode 100644 shared/types/Color.hpp delete mode 100644 shared/types/UUId.cpp delete mode 100644 shared/types/UUId.hpp delete mode 100644 shared/types/types.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index b23028f..99d4b74 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,4 +13,4 @@ set(CMAKE_SHARED_LIBRARY_PREFIX "arcade_") add_subdirectory(core) add_subdirectory(games) -add_subdirectory(graphics) +#[[add_subdirectory(graphics)]] diff --git a/core/main.cpp b/core/main.cpp index 6e160ea..769a187 100644 --- a/core/main.cpp +++ b/core/main.cpp @@ -7,16 +7,23 @@ #include "loader/DLLoader.hpp" -int main(void) -{ - DLLoader loader; +int main(void) { + DLLoader loader; - try { - loader.loadLibraries("./lib"); - std::cout << "Games libraries:" << loader.getGamesLibraries().size() << std::endl; - std::cout << "Graphics libraries:" << loader.getGraphicsLibraries().size() << std::endl; - } catch (const std::exception &e) { - std::cerr << e.what() << std::endl; - } - return 0; + try { + loader.loadLibraries("./lib"); + std::cout << "Games libraries:" << loader.getGamesLibraries().size() << std::endl; + std::cout << "Graphics libraries:" << loader.getGraphicsLibraries().size() << std::endl; + } catch (const std::exception &e) { + std::cerr << e.what() << std::endl; + } + auto lib = loader.getGamesLibraries().at(0); + auto manifest = lib->getManifest(); + std::cout << "Game name: " << manifest.name << std::endl; + std::cout << "Game description: " << manifest.description << std::endl; + std::cout << "Game version: " << manifest.version << std::endl; + std::cout << "Game authors: " << manifest.authors[0].name << std::endl; + + auto game = lib->createInstance(); + return 0; } diff --git a/games/common/game/AGame.cpp b/games/common/game/AGame.cpp index 7030e8b..2b2e7a5 100644 --- a/games/common/game/AGame.cpp +++ b/games/common/game/AGame.cpp @@ -19,18 +19,14 @@ const shared::games::entity::EntitiesMap &common::AGame::getEntities() const { return this->_entities; } -common::EntityPtr common::AGame::getEntityById(const shared::types::UUId &id) const { - try { - return this->_entities.at(id); - } catch (std::out_of_range &e) { - return nullptr; - } -} - const shared::types::Vector2u common::AGame::getSize() const noexcept { return this->_size; } +const unsigned int common::AGame::getFps() const noexcept { + return this->_fps; +} + void common::AGame::_registerEntity(EntityPtr entity) { - this->_entities[entity->getId()] = std::move(entity); + this->_entities.push_back(std::move(entity)); } diff --git a/games/common/game/AGame.hpp b/games/common/game/AGame.hpp index 12aa183..26e5748 100644 --- a/games/common/game/AGame.hpp +++ b/games/common/game/AGame.hpp @@ -13,6 +13,7 @@ namespace arcade::games::common { class AGame; + typedef std::shared_ptr EntityPtr; } @@ -35,12 +36,11 @@ class arcade::games::common::AGame : public shared::games::IGame { const shared::types::Vector2u getSize() const noexcept override; /** - * @brief Get entity by id + * @brief Get fps of the game * - * @param id Id of the entity - * @return The specific entity + * @return The number of frame per seconds of the game */ - EntityPtr getEntityById(const shared::types::UUId &id) const override; + const unsigned int getFps() const noexcept override; protected: /** @@ -60,6 +60,11 @@ class arcade::games::common::AGame : public shared::games::IGame { */ shared::types::Vector2u _size; + /** + * @brief Game frame per seconds + */ + unsigned int _fps; + /** * @brief Add an entity to the game * diff --git a/games/snake/src/Snake.hpp b/games/snake/src/Snake.hpp index 4eed44a..9ee4143 100644 --- a/games/snake/src/Snake.hpp +++ b/games/snake/src/Snake.hpp @@ -11,7 +11,6 @@ #include #include -#include "shared/types/UUId.hpp" #include "common/game/AGame.hpp" namespace arcade::games::snake { diff --git a/games/snake/src/SnakeGame.cpp b/games/snake/src/SnakeGame.cpp index 947e6bc..4a36771 100644 --- a/games/snake/src/SnakeGame.cpp +++ b/games/snake/src/SnakeGame.cpp @@ -11,19 +11,25 @@ using namespace arcade::games; const shared::games::GameManifest snake::SnakeGame::manifest = { - .name = "Snake", - .description = "The snake original game", - .version = "0.0.1", - .authors = { - { - .name = "Flavien Chenu", - .email = "flavienchenu@epitech.eu", - .website = "https://github.com/flavien-chenu" + .name = "Snake", + .description = "The snake original game", + .version = "1.0.0", + .authors = { + { + .name = "TekMath", + .email = "matheo.coquet@epitech.eu", + .website = "https://github.com/tekmath" + }, + { + .name = "Flavien Chenu", + .email = "flavienchenu@epitech.eu", + .website = "https://github.com/flavien-chenu" + } } - } }; -snake::SnakeGame::SnakeGame(): common::AGame(Vector2u(12, 12)) { +snake::SnakeGame::SnakeGame() : common::AGame(Vector2u(19, 19)) { + this->_snake = std::make_unique(); } snake::SnakeGame::~SnakeGame() = default; diff --git a/games/snake/src/SnakeGame.hpp b/games/snake/src/SnakeGame.hpp index b1ae049..2787640 100644 --- a/games/snake/src/SnakeGame.hpp +++ b/games/snake/src/SnakeGame.hpp @@ -8,6 +8,7 @@ #pragma once #include "common/game/AGame.hpp" +#include "Snake.hpp" namespace arcade::games::snake { class SnakeGame; @@ -38,4 +39,7 @@ class arcade::games::snake::SnakeGame : public arcade::games::common::AGame { * @param dt Delta time from last frame */ void compute(shared::games::DeltaTime dt) override; + +protected: + std::unique_ptr _snake; }; diff --git a/shared/games/IEntity.hpp b/shared/games/IEntity.hpp index e251824..9741616 100644 --- a/shared/games/IEntity.hpp +++ b/shared/games/IEntity.hpp @@ -7,11 +7,9 @@ #pragma once -#include +#include #include -#include "../types/UUId.hpp" - namespace shared::games { class IGame; @@ -20,14 +18,15 @@ namespace shared::games { class IEntity; - typedef std::map> EntitiesMap; + typedef std::shared_ptr EntityPtr; + typedef std::vector EntitiesMap; } namespace components { class IComponent; - typedef std::map> ComponentsMap; + typedef std::vector> ComponentsMap; } } @@ -36,13 +35,6 @@ class shared::games::entity::IEntity public: virtual ~IEntity() = default; - /** - * @brief Get the id of the entity - * - * @return Entity unique id - */ - virtual const types::UUId &getId(void) const noexcept = 0; - /** * @brief Get the components of the entity * diff --git a/shared/games/IGame.hpp b/shared/games/IGame.hpp index 291ac21..bc8353d 100644 --- a/shared/games/IGame.hpp +++ b/shared/games/IGame.hpp @@ -9,7 +9,7 @@ #include #include "IEntity.hpp" -#include "../types/types.hpp" +#include "../types/Vector.hpp" #include "types/GameManifest.hpp" using namespace shared::types; @@ -36,27 +36,29 @@ class shared::games::IGame /** * @brief Manifest with informations of the game * + * @return Manifest of the game */ - virtual const GameManifest &getManifest(void) const noexcept = 0; + virtual const GameManifest &getManifest() const noexcept = 0; /** * @brief Number of tiles that represent the game * Tile size is managed by the renderer * + * @return The number of tiles of the game */ - virtual const Vector2u getSize(void) const noexcept = 0; + virtual const Vector2u getSize() const noexcept = 0; /** - * @brief Get map of entities + * @brief Get fps of the game * + * @return The number of frame per seconds of the game */ - virtual const entity::EntitiesMap &getEntities(void) const = 0; + virtual const unsigned int getFps() const noexcept = 0; /** - * @brief Get entity by id + * @brief Get map of entities * - * @param id Id of the entity - * @return The specific entity + * @return Entities map of the game */ - virtual std::shared_ptr getEntityById(const UUId &id) const = 0; + virtual const entity::EntitiesMap &getEntities(void) const = 0; }; diff --git a/shared/games/components/IComponent.hpp b/shared/games/components/IComponent.hpp index 4ee1093..e03cc51 100644 --- a/shared/games/components/IComponent.hpp +++ b/shared/games/components/IComponent.hpp @@ -8,42 +8,35 @@ #pragma once #include "../IEntity.hpp" -#include "../../types/UUId.hpp" namespace shared::games::components { - typedef enum { - DISPLAYABLE, - SOUND, - COLLIDABLE, - POSITION, - KEYBOARD - } ComponentType; - - class IComponent; + typedef enum { + TEXTURE, + TEXT, + SOUND, + COLLIDABLE, + POSITION, + KEYBOARD + } ComponentType; + + class IComponent; } class shared::games::components::IComponent { public: - virtual ~IComponent() = default; - - /** - * @brief Get the type of the component - * - * @return Type of the component - */ - virtual const ComponentType getType() const noexcept = 0; - - /** - * @brief Get the uuid of component - * - * @return Component id - */ - virtual const types::UUId &getId() const noexcept = 0; - - /** - * @brief Get the parent entity of the component - * - * @return Entity of the component - */ - virtual const entity::IEntity &getEntity() noexcept = 0; + virtual ~IComponent() = default; + + /** + * @brief Get the type of the component + * + * @return Type of the component + */ + virtual const ComponentType getType() const noexcept = 0; + + /** + * @brief Get the parent entity of the component + * + * @return Entity of the component + */ + virtual const entity::IEntity &getEntity() noexcept = 0; }; diff --git a/shared/games/components/IDisplayableComponent.hpp b/shared/games/components/IDisplayableComponent.hpp index c492e3b..0a60cec 100644 --- a/shared/games/components/IDisplayableComponent.hpp +++ b/shared/games/components/IDisplayableComponent.hpp @@ -1,8 +1,8 @@ /* ** EPITECH PROJECT, 2024 -** arcade-shared [WSL: Ubuntu-22.04] +** arcade-shared ** File description: -** ADisplaybleComponent +** IDisplaybleComponent */ #pragma once @@ -12,60 +12,40 @@ #include "../../types/Vector.hpp" namespace shared::games::components { - class IDisplayableComponent; - - typedef struct - { - const std::string ascii; // ASCII image representation path - const std::string bin; // Binary image path - Vector2f binTileSize; // Size of the binary tile - } TextureSources; - - typedef struct - { - TextureSources sources; // Sources of textures - Vector2u origin; // Origin of the texture - } TextureProps; + class IDisplayableComponent; } -class shared::games::components::IDisplayableComponent: public virtual IPositionComponent -{ +class shared::games::components::IDisplayableComponent : public virtual IPositionComponent { public: - virtual ~IDisplayableComponent() = default; + virtual ~IDisplayableComponent() = default; /** - * @brief Get size of the entity (tiles) - * - */ - virtual Vector2u &getSize(void) noexcept = 0; + * @brief Get size of the entity (tiles) + * + */ + virtual Vector2u &getSize() noexcept = 0; - /** - * @brief Get Z index that is usefull for display prioroty - * - */ - virtual unsigned int &getZIndex(void) noexcept = 0; - - /** - * @brief Get texture properties - * - */ - virtual TextureProps &getTextureProps(void) noexcept = 0; + /** + * @brief Get Z index that is usefull for display prioroty + * + */ + virtual unsigned int &getZIndex() noexcept = 0; - /** - * @brief On click event handler for the entity - * @param ctx Context of the game - */ - virtual void onMousePress(std::shared_ptr &ctx) = 0; + /** + * @brief On click event handler for the entity + * @param ctx Context of the game + */ + virtual void onMousePress(std::shared_ptr &ctx) = 0; - /** - * @brief On release event handler for the entity - * @param ctx Context of the game - */ - virtual void onMouseRelease(std::shared_ptr &ctx) = 0; + /** + * @brief On release event handler for the entity + * @param ctx Context of the game + */ + virtual void onMouseRelease(std::shared_ptr &ctx) = 0; - /** - * @brief On hover event handler for the entity - * @param ctx Context of the game - */ - virtual void onMouseHover(std::shared_ptr &ctx) = 0; + /** + * @brief On hover event handler for the entity + * @param ctx Context of the game + */ + virtual void onMouseHover(std::shared_ptr &ctx) = 0; }; diff --git a/shared/games/components/ITextComponent.hpp b/shared/games/components/ITextComponent.hpp new file mode 100644 index 0000000..c0a269c --- /dev/null +++ b/shared/games/components/ITextComponent.hpp @@ -0,0 +1,53 @@ +/* +** EPITECH PROJECT, 2024 +** ITextComponent.hpp +** File description: +** ITextComponent class +*/ + +#pragma once + +#include "IDisplayableComponent.hpp" +#include "../../types/Vector.hpp" +#include "../../types/Color.hpp" + +namespace shared::games::components { + class ITextComponent; + + typedef enum { + LEFT, + CENTER, + RIGHT + } TextAlign; + + typedef enum { + BOTTOM, + MIDDLE, + TOP + } TextVerticalAlign; + + typedef struct { + std::string path; // Path of the font + types::Vector2u size; // Font size + } TextFontProps; + + typedef struct { + std::string content; // Content of the text + TextAlign align; // Alignment of the text + TextVerticalAlign verticalAlign; // Vertical alignment of the text + TextFontProps font; // Font of the text + types::Color color; // Color of the text + } TextProps; +} + +class shared::games::components::ITextComponent : public virtual IDisplayableComponent { +public: + virtual ~ITextComponent() = default; + + /** + * @brief Get text props of the entity + * + * @return text props + */ + virtual TextProps getTextProps() noexcept = 0; +}; diff --git a/shared/games/components/ITextureComponent.hpp b/shared/games/components/ITextureComponent.hpp new file mode 100644 index 0000000..930215c --- /dev/null +++ b/shared/games/components/ITextureComponent.hpp @@ -0,0 +1,38 @@ +/* +** EPITECH PROJECT, 2024 +** arcade-shared +** File description: +** ITextureComponent +*/ + +#pragma once + +#include "IDisplayableComponent.hpp" +#include "../IGame.hpp" +#include "../../types/Vector.hpp" + +namespace shared::games::components { + class ITextureComponent; + + typedef struct { + const std::string ascii; // ASCII image representation path + const std::string bin; // Binary image path + Vector2f binTileSize; // Size of the binary tile + } TextureSources; + + typedef struct { + TextureSources sources; // Sources of textures + Vector2u origin; // Origin of the texture + } TextureProps; +} + +class shared::games::components::ITextureComponent : public virtual IDisplayableComponent { +public: + virtual ~ITextureComponent() = default; + + /** + * @brief Get texture properties + * + */ + virtual TextureProps &getTextureProps() noexcept = 0; +}; diff --git a/shared/games/types/GameManifest.hpp b/shared/games/types/GameManifest.hpp index 4c6efbf..25da00a 100644 --- a/shared/games/types/GameManifest.hpp +++ b/shared/games/types/GameManifest.hpp @@ -6,23 +6,22 @@ */ #pragma once + #include #include -namespace shared::games -{ - typedef struct - { - std::string name; // Name of the author - std::string email; // Public contact email - std::string website; // Website of the author (`github`, `gitlab`, etc.) - } Author; +namespace shared::games { + typedef struct { + std::string name; // Name of the author + std::string email; // Public contact email + std::string website; // Website of the author (`github`, `gitlab`, etc.) + } Author; - typedef struct - { - const std::string name; // Name of the game - const std::string description; // Description of the game - const std::string version; // Version of the game - const std::vector authors; // Authors - } GameManifest; + typedef struct { + const std::string name; // Name of the game + const std::string description; // Description of the game + const std::string version; // Version of the game + const std::vector authors; // Authors + const std::string iconPath; // Path of the icon game + } GameManifest; } diff --git a/shared/graphics/IFont.hpp b/shared/graphics/IFont.hpp new file mode 100644 index 0000000..63b7829 --- /dev/null +++ b/shared/graphics/IFont.hpp @@ -0,0 +1,17 @@ +/* +** EPITECH PROJECT, 2024 +** arcade-shared +** File description: +** IFont +*/ + +#pragma once + +namespace shared::graphics { + class IFont; +} + +class shared::graphics::IFont { + public: + virtual ~IFont() = default; +}; diff --git a/shared/graphics/IGraphicsProvider.hpp b/shared/graphics/IGraphicsProvider.hpp index 2d2b7cf..4200a5c 100644 --- a/shared/graphics/IGraphicsProvider.hpp +++ b/shared/graphics/IGraphicsProvider.hpp @@ -11,7 +11,7 @@ #include "ISound.hpp" #include "ITexture.hpp" -#include "window/IWindow.hpp" +#include "IWindow.hpp" #include "types/GraphicsManifest.hpp" namespace shared::graphics { @@ -22,7 +22,6 @@ class shared::graphics::IGraphicsProvider { public: virtual ~IGraphicsProvider() = default; - /** * @brief Get the manifest of the graphics library * @@ -31,12 +30,12 @@ class shared::graphics::IGraphicsProvider { virtual const GraphicsManifest &getManifest(void) const noexcept = 0; /** - * @brief Create a renderer object + * @brief Create a new window object * * @param windowProps Properties to use to init the window - * @return Created renderer object + * @return Created window object */ - virtual std::unique_ptr createWindow(const WindowInitProps &windowProps) = 0; + virtual std::unique_ptr createWindow(const IWindow::WindowInitProps &windowProps) = 0; /** * @brief Create a sound object @@ -54,4 +53,12 @@ class shared::graphics::IGraphicsProvider { * @return Created texture object */ virtual std::shared_ptr createTexture(const std::string &bin, const std::string &ascii) = 0; + + /** + * @brief Create a font object + * + * @param path Path of the font file + * @return Created font object + */ + virtual std::shared_ptr createFont(const std::string &path) = 0; }; diff --git a/shared/graphics/ISound.hpp b/shared/graphics/ISound.hpp index 96f192c..00da6af 100644 --- a/shared/graphics/ISound.hpp +++ b/shared/graphics/ISound.hpp @@ -10,20 +10,21 @@ namespace shared::graphics { class ISound; - - typedef unsigned char SoundVolume; - typedef enum - { - PLAY, - PAUSE, - STOP - } SoundState; } class shared::graphics::ISound { public: virtual ~ISound() = default; + typedef unsigned char SoundVolume; + + typedef enum + { + PLAY, + PAUSE, + STOP + } SoundState; + /** * @brief Get the state of the sound * diff --git a/shared/graphics/ITexture.hpp b/shared/graphics/ITexture.hpp index 69649da..f82f3e8 100644 --- a/shared/graphics/ITexture.hpp +++ b/shared/graphics/ITexture.hpp @@ -11,7 +11,7 @@ namespace shared::graphics { class ITexture; } -class ITexture { +class shared::graphics::ITexture { public: virtual ~ITexture() = default; }; diff --git a/shared/graphics/window/IWindow.hpp b/shared/graphics/IWindow.hpp similarity index 69% rename from shared/graphics/window/IWindow.hpp rename to shared/graphics/IWindow.hpp index 22f3fc3..ac1746a 100644 --- a/shared/graphics/window/IWindow.hpp +++ b/shared/graphics/IWindow.hpp @@ -9,36 +9,36 @@ #include #include +#include -#include "../events/IEvent.hpp" -#include "../../types/types.hpp" -#include "../types/EntityProps.hpp" +#include "events/IEvent.hpp" +#include "types/TextureProps.hpp" +#include "types/TextProps.hpp" using namespace shared::types; -namespace shared::graphics -{ +namespace shared::graphics { class IWindow; - - typedef enum - { - WINDOWED, - FULLSCREEN - } WindowMode; - - typedef struct { - Vector2u size; //Initial size of the window - WindowMode mode; //Initial mode of the window - unsigned int fps; //Initial framerate of the window - const std::string title; //Initial title of the window - const std::string icon; //Initial icon of the window - } WindowInitProps; } class shared::graphics::IWindow { public: virtual ~IWindow() = default; + typedef enum + { + WINDOWED, + FULLSCREEN + } WindowMode; + + typedef struct { + Vector2u size; //Initial size of the window + WindowMode mode; //Initial mode of the window + unsigned int fps; //Initial framerate of the window + const std::string title; //Initial title of the window + const std::string icon; //Initial icon of the window + } WindowInitProps; + /** * @brief Set the title of current window * @@ -46,13 +46,6 @@ class shared::graphics::IWindow { */ virtual void setTitle(const std::string &title) = 0; - /** - * @brief Get the title of current window - * - * @return Title of the window - */ - virtual std::string getTitle() const = 0; - /** * @brief Set the size of the window * @@ -103,18 +96,18 @@ class shared::graphics::IWindow { virtual void setIcon(const std::string &icon) = 0; /** - * @brief Get the icon of the window + * @brief Render the texture of entity with given properties * - * @return Icon object of the window + * @param props Properties of the entity & texture to render */ - virtual const std::string &getIcon(void) const = 0; + virtual void render(const TextureProps &props) = 0; /** - * @brief Render the entity with given properties + * @brief Render the text of entity with given properties * - * @param props Properties of the entity to render + * @param props Properties of the entity & text to render */ - virtual void render(const EntityProps &props) = 0; + virtual void render(const TextProps &props) = 0; /** * @brief Clear the content of the window @@ -150,5 +143,5 @@ class shared::graphics::IWindow { * but make another call `B` (directly after call `A`) `eventsB` * will result to an empty vector */ - virtual std::vector getEvents(void) = 0; + virtual std::vector getEvents(void) = 0; }; diff --git a/shared/graphics/events/IEvent.hpp b/shared/graphics/events/IEvent.hpp index ab455d0..84c9492 100644 --- a/shared/graphics/events/IEvent.hpp +++ b/shared/graphics/events/IEvent.hpp @@ -7,6 +7,8 @@ #pragma once +#include + namespace shared::graphics::events { class IEvent; @@ -21,6 +23,8 @@ namespace shared::graphics::events WINDOW_CLOSE, // Window closed WINDOW_RESIZE, // Window resized } EventType; + + typedef std::shared_ptr EventPtr; } class shared::graphics::events::IEvent @@ -31,5 +35,5 @@ class shared::graphics::events::IEvent /** * @brief Event type */ - virtual const EventType getType() const noexcept = 0; + virtual EventType getType() const noexcept = 0; }; diff --git a/shared/graphics/events/IKeyEvent.hpp b/shared/graphics/events/IKeyEvent.hpp new file mode 100644 index 0000000..db6cab4 --- /dev/null +++ b/shared/graphics/events/IKeyEvent.hpp @@ -0,0 +1,61 @@ +/* +** EPITECH PROJECT, 2024 +** arcade-shared +** File description: +** AKeyEvent +*/ + +#pragma once + +#include "IEvent.hpp" + +namespace shared::graphics::events { + class IKeyEvent; +} + +class shared::graphics::events::IKeyEvent : public IEvent { +public: + virtual ~IKeyEvent() = default; + + typedef enum { + CONTROL, // Control key (`Ctrl`, `Shift`, `Alt`) + ARROW, // Arrow key (`Up`, `Down`, `Left`, `Right`) + FUNC, // Function key (`F1`, `F2`, `F3`, etc.) + CHAR, // Character key (`a`, `1`, `&`, etc.) + UNKNOWN // Unknown key + } KeyType; + + typedef enum { + CTRL, // `Ctrl` key + SHIFT, // `Shift` key + ALT // `Alt` key + } ControlCode; + + typedef enum { + UP, // `Up` arrow key + DOWN, // `Down` arrow key + LEFT, // `Left` arrow key + RIGHT // `Right` arrow key + } ArrowCode; + + typedef union { + ControlCode control; // Control key + ArrowCode arrow; // Arrow key + char character; // ASCII character value + unsigned char func; // Function key number + } KeyCode; + + /** + * @brief Key code content + * + * @return Content of the key code + */ + virtual const KeyCode getKeyCode(void) const noexcept = 0; + + /** + * @brief Key type + * + * @return Type of the key pressed + */ + virtual const KeyType getKeyType(void) const noexcept = 0; +}; diff --git a/shared/graphics/events/IMouseButtonEvent.hpp b/shared/graphics/events/IMouseButtonEvent.hpp new file mode 100644 index 0000000..b70ab17 --- /dev/null +++ b/shared/graphics/events/IMouseButtonEvent.hpp @@ -0,0 +1,31 @@ +/* +** EPITECH PROJECT, 2024 +** arcade-shared +** File description: +** IMouseEvent +*/ + +#pragma once + +#include "IMouseEvent.hpp" + +namespace shared::graphics::events{ + class IMouseButtonEvent; +} + +class shared::graphics::events::IMouseButtonEvent : public IMouseEvent { +public: + virtual ~IMouseButtonEvent() = default; + + typedef enum { + LEFT, + RIGHT + } MouseButton; + + /** + * @brief Mouse button released + * + * @return Button released or pressed + */ + virtual const MouseButton getButton(void) const noexcept = 0; +}; diff --git a/shared/graphics/events/IMouseEvent.hpp b/shared/graphics/events/IMouseEvent.hpp new file mode 100644 index 0000000..a85ae4b --- /dev/null +++ b/shared/graphics/events/IMouseEvent.hpp @@ -0,0 +1,27 @@ +/* +** EPITECH PROJECT, 2024 +** arcade-shared +** File description: +** IMouseEvent +*/ + +#pragma once + +#include "../../types/Vector.hpp" +#include "IEvent.hpp" + +namespace shared::graphics::events { + class IMouseEvent; +} + +class shared::graphics::events::IMouseEvent : public IEvent { +public: + virtual ~IMouseEvent() = default; + + /** + * @brief Mouse position + * + * @return Position of the mouse + */ + virtual const shared::types::Vector2i getPosition(void) const noexcept = 0; +}; diff --git a/shared/graphics/events/key/AKeyEvent.hpp b/shared/graphics/events/key/AKeyEvent.hpp deleted file mode 100644 index ff4c436..0000000 --- a/shared/graphics/events/key/AKeyEvent.hpp +++ /dev/null @@ -1,87 +0,0 @@ -/* -** EPITECH PROJECT, 2024 -** arcade-shared -** File description: -** AKeyEvent -*/ - -#pragma once - -#include "../IEvent.hpp" - -namespace shared::graphics::events { - template - class AKeyEvent; - - typedef enum - { - CONTROL, // Control key (`Ctrl`, `Shift`, `Alt`) - ARROW, // Arrow key (`Up`, `Down`, `Left`, `Right`) - FUNC, // Function key (`F1`, `F2`, `F3`, etc.) - CHAR, // Character key (`a`, `1`, `&`, etc.) - UNKNOWN // Unknown key - } KeyType; - - typedef enum - { - CTRL, // `Ctrl` key - SHIFT, // `Shift` key - ALT // `Alt` key - } ControlCode; - - typedef enum - { - UP, // `Up` arrow key - DOWN, // `Down` arrow key - LEFT, // `Left` arrow key - RIGHT // `Right` arrow key - } ArrowCode; - - typedef union - { - ControlCode control; // Control key - ArrowCode arrow; // Arrow key - char character; // ASCII character value - unsigned char func; // Function key number - } KeyCode; -} - -template -class shared::graphics::events::AKeyEvent: public IEvent { - public: - ~AKeyEvent() = default; - - /** - * @brief Event type - * - */ - const EventType getType(void) const noexcept - { - return this->_type; - } - - /** - * @brief Key code content - * - */ - const KeyCode getKeyCode(void) const noexcept - { - return this->_keyCode; - } - - /** - * @brief Key type - * - */ - const KeyType getKeyType(void) const noexcept - { - return this->_keyType; - } - - protected: - AKeyEvent(KeyType keyType, KeyCode keyCode) : _keyType(keyType), _keyCode(keyCode) {} - - EventType _type = T; - KeyType _keyType; - KeyCode _keyCode; -}; diff --git a/shared/graphics/events/key/KeyPressEvent.hpp b/shared/graphics/events/key/KeyPressEvent.hpp deleted file mode 100644 index 58016b8..0000000 --- a/shared/graphics/events/key/KeyPressEvent.hpp +++ /dev/null @@ -1,19 +0,0 @@ -/* -** EPITECH PROJECT, 2024 -** arcade-shared -** File description: -** AKeyEvent -*/ - -#pragma once - -#include "AKeyEvent.hpp" - -namespace shared::graphics::events { - class KeyPressEvent; -} - -class shared::graphics::events::KeyPressEvent: public AKeyEvent { - public: - KeyPressEvent(KeyType keyType, KeyCode keyCode): AKeyEvent(keyType, keyCode) {} -}; diff --git a/shared/graphics/events/key/KeyReleaseEvent.hpp b/shared/graphics/events/key/KeyReleaseEvent.hpp deleted file mode 100644 index 8800f90..0000000 --- a/shared/graphics/events/key/KeyReleaseEvent.hpp +++ /dev/null @@ -1,18 +0,0 @@ -/* -** EPITECH PROJECT, 2024 -** arcade-shared -** File description: -** IKeyEvent -*/ - -#pragma once - -#include "AKeyEvent.hpp" - -namespace shared::graphics::events { - class KeyReleaseEvent; -} -class shared::graphics::events::KeyReleaseEvent: public AKeyEvent { - public: - KeyReleaseEvent(KeyType keyType, KeyCode keyCode): AKeyEvent(keyType, keyCode) {} -}; diff --git a/shared/graphics/events/mouse/AMouseButtonEvent.hpp b/shared/graphics/events/mouse/AMouseButtonEvent.hpp deleted file mode 100644 index 17342c3..0000000 --- a/shared/graphics/events/mouse/AMouseButtonEvent.hpp +++ /dev/null @@ -1,39 +0,0 @@ -/* -** EPITECH PROJECT, 2024 -** arcade-shared -** File description: -** IMouseEvent -*/ - -#pragma once - -#include "AMouseEvent.hpp" - -namespace shared::graphics::events -{ - template - class AMouseButtonEvent; -} - -template -class shared::graphics::events::AMouseButtonEvent: public AMouseEvent -{ - public: - ~AMouseButtonEvent() = default; - - /** - * @brief Mouse button released - * - */ - const MouseButton getButton(void) const noexcept { - return this->_button; - } - - protected: - AMouseButtonEvent( - MouseButton button, - types::Vector2f position - ): AMouseEvent(position), _button(button) {} - - MouseButton _button; -}; diff --git a/shared/graphics/events/mouse/AMouseEvent.hpp b/shared/graphics/events/mouse/AMouseEvent.hpp deleted file mode 100644 index 18bc030..0000000 --- a/shared/graphics/events/mouse/AMouseEvent.hpp +++ /dev/null @@ -1,50 +0,0 @@ -/* -** EPITECH PROJECT, 2024 -** arcade-shared -** File description: -** IMouseEvent -*/ - -#pragma once - -#include "../../../types/types.hpp" -#include "../IEvent.hpp" - -namespace shared::graphics::events -{ - template - class AMouseEvent; - - typedef enum { - LEFT, - RIGHT - } MouseButton; -} - -template -class shared::graphics::events::AMouseEvent : public IEvent -{ - public: - ~AMouseEvent() = default; - - /** - * @brief Event type - * - */ - const EventType getType(void) const noexcept { - return T; - } - - /** - * @brief Mouse position - * - */ - const shared::types::Vector2f getPosition(void) const noexcept { - return this->_position; - } - - protected: - AMouseEvent(types::Vector2f position): _position(position) {} - - types::Vector2f _position; -}; diff --git a/shared/graphics/events/mouse/MouseButtonPressEvent.hpp b/shared/graphics/events/mouse/MouseButtonPressEvent.hpp deleted file mode 100644 index 3a92d1e..0000000 --- a/shared/graphics/events/mouse/MouseButtonPressEvent.hpp +++ /dev/null @@ -1,24 +0,0 @@ -/* -** EPITECH PROJECT, 2024 -** arcade-shared -** File description: -** IMouseEvent -*/ - -#pragma once - -#include "AMouseButtonEvent.hpp" - -namespace shared::graphics::events -{ - class MouseButtonPressEvent; -} - -class shared::graphics::events::MouseButtonPressEvent : - public AMouseButtonEvent -{ - public: - MouseButtonPressEvent(MouseButton button, types::Vector2f position) - : AMouseButtonEvent(button, position) {} - ~MouseButtonPressEvent() = default; -}; diff --git a/shared/graphics/events/mouse/MouseButtonReleaseEvent.hpp b/shared/graphics/events/mouse/MouseButtonReleaseEvent.hpp deleted file mode 100644 index 960c6bc..0000000 --- a/shared/graphics/events/mouse/MouseButtonReleaseEvent.hpp +++ /dev/null @@ -1,24 +0,0 @@ -/* -** EPITECH PROJECT, 2024 -** arcade-shared -** File description: -** IMouseEvent -*/ - -#pragma once - -#include "AMouseButtonEvent.hpp" - -namespace shared::graphics::events -{ - class MouseButtonReleaseEvent; -} - -class shared::graphics::events::MouseButtonReleaseEvent : - public AMouseButtonEvent -{ - public: - MouseButtonReleaseEvent(MouseButton button, types::Vector2f position) - : AMouseButtonEvent(button, position) {} - ~MouseButtonReleaseEvent() = default; -}; diff --git a/shared/graphics/events/mouse/MouseMoveEvent.hpp b/shared/graphics/events/mouse/MouseMoveEvent.hpp deleted file mode 100644 index c0be8db..0000000 --- a/shared/graphics/events/mouse/MouseMoveEvent.hpp +++ /dev/null @@ -1,22 +0,0 @@ -/* -** EPITECH PROJECT, 2024 -** arcade-shared -** File description: -** IMouseEvent -*/ - -#pragma once - -#include "AMouseEvent.hpp" - -namespace shared::graphics::events -{ - class MouseMoveEvent; -} - -class shared::graphics::events::MouseMoveEvent : public AMouseEvent -{ - public: - MouseMoveEvent(types::Vector2f position) : AMouseEvent(position) {} - ~MouseMoveEvent() = default; -}; diff --git a/shared/graphics/events/window/WindowCloseEvent.hpp b/shared/graphics/events/window/WindowCloseEvent.hpp deleted file mode 100644 index dcf9d52..0000000 --- a/shared/graphics/events/window/WindowCloseEvent.hpp +++ /dev/null @@ -1,29 +0,0 @@ -/* -** EPITECH PROJECT, 2024 -** arcade-shared -** File description: -** IWindowCloseEvent -*/ - -#pragma once - -#include "../IEvent.hpp" - -namespace shared::graphics::events { - class WindowCloseEvent; -} - -class shared::graphics::events::WindowCloseEvent: public IEvent { - public: - WindowCloseEvent() = default; - ~WindowCloseEvent() = default; - - /** - * @brief Event type - * - */ - const EventType getType() const noexcept - { - return WINDOW_CLOSE; - } -}; diff --git a/shared/graphics/events/window/WindowResizeEvent.hpp b/shared/graphics/events/window/WindowResizeEvent.hpp deleted file mode 100644 index e8bddce..0000000 --- a/shared/graphics/events/window/WindowResizeEvent.hpp +++ /dev/null @@ -1,43 +0,0 @@ -/* -** EPITECH PROJECT, 2024 -** arcade-shared -** File description: -** IWindowResizeEvent -*/ - -#pragma once - -#include "../IEvent.hpp" -#include "../../../types/types.hpp" - -namespace shared::graphics::events { - class WindowResizeEvent; -} - -class shared::graphics::events::WindowResizeEvent: public IEvent { - public: - WindowResizeEvent(types::Vector2u newSize) : _newSize(newSize) {} - ~WindowResizeEvent() = default; - - /** - * @brief Event type - * - */ - const EventType getType() const noexcept - { - return WINDOW_RESIZE; - } - - /** - * @brief Get the new window size - * - * @return New window size - */ - const types::Vector2u &getNewSize() const noexcept - { - return this->_newSize; - } - - protected: - types::Vector2u _newSize; -}; diff --git a/shared/graphics/types/EntityProps.hpp b/shared/graphics/types/EntityProps.hpp deleted file mode 100644 index 2e3b8e5..0000000 --- a/shared/graphics/types/EntityProps.hpp +++ /dev/null @@ -1,32 +0,0 @@ -/* -** EPITECH PROJECT, 2024 -** arcade-shared -** File description: -** Texture -*/ - -#pragma once - -#include - -#include "../ITexture.hpp" -#include "../../types/types.hpp" - -using namespace shared::types; - -namespace shared::graphics -{ - typedef struct - { - const std::shared_ptr texture; // Texture of the entity - const Vector2f binTileSize; // Size of a binary tile - const Vector2u origin; // Origin of the texture - } EntityTextureProps; - - typedef struct - { - EntityTextureProps textureProps; // Properties to use with the texture for the entity - Vector2u size; // Size of the entity - Vector2i position; // Position of the entity - } EntityProps; -} diff --git a/shared/graphics/types/TextProps.hpp b/shared/graphics/types/TextProps.hpp new file mode 100644 index 0000000..2d7187a --- /dev/null +++ b/shared/graphics/types/TextProps.hpp @@ -0,0 +1,45 @@ +/* +** EPITECH PROJECT, 2024 +** arcade-shared +** File description: +** Text +*/ + +#pragma once + +#include + +#include "../IFont.hpp" +#include "../../types/Vector.hpp" +#include "../../types/Color.hpp" + +using namespace shared::types; + +namespace shared::graphics { + typedef enum { + LEFT, + CENTER, + RIGHT + } TextAlign; + + typedef enum { + BOTTOM, + MIDDLE, + TOP + } TextVerticalAlign; + + typedef struct { + std::string path; // Path of the font + types::Vector2u size; // Font size + } TextFontProps; + + typedef struct { + std::shared_ptr font; // Font of the text + std::string content; // Content of the text + TextAlign align; // Alignment of the text + TextVerticalAlign verticalAlign; // Vertical alignment of the text + types::Color color; // Color of the text + Vector2u size; // Size of the entity + Vector2i position; // Position of the entity + } TextProps; +} diff --git a/shared/graphics/types/TextureProps.hpp b/shared/graphics/types/TextureProps.hpp new file mode 100644 index 0000000..5847f37 --- /dev/null +++ b/shared/graphics/types/TextureProps.hpp @@ -0,0 +1,25 @@ +/* +** EPITECH PROJECT, 2024 +** arcade-shared +** File description: +** Texture +*/ + +#pragma once + +#include + +#include "../ITexture.hpp" +#include "../../types/Vector.hpp" + +using namespace shared::types; + +namespace shared::graphics { + typedef struct { + std::shared_ptr texture; // Texture of the entity + Vector2f binTileSize; // Size of a binary tile + Vector2u origin; // Origin of the texture + Vector2u size; // Size of the entity + Vector2i position; // Position of the entity + } TextureProps; +} diff --git a/shared/types/Color.hpp b/shared/types/Color.hpp new file mode 100644 index 0000000..b512852 --- /dev/null +++ b/shared/types/Color.hpp @@ -0,0 +1,19 @@ +/* +** EPITECH PROJECT, 2024 +** Color.hpp +** File description: +** Color class +*/ + +#pragma once + +namespace shared::types { + typedef struct ColorType { + ColorType(unsigned char r, unsigned char g, unsigned char b, unsigned char a) : r(r), g(g), b(b), a(a) {} + + unsigned char r; + unsigned char g; + unsigned char b; + unsigned char a; + } Color; +} diff --git a/shared/types/UUId.cpp b/shared/types/UUId.cpp deleted file mode 100644 index 87086f2..0000000 --- a/shared/types/UUId.cpp +++ /dev/null @@ -1,63 +0,0 @@ -/* -** EPITECH PROJECT, 2024 -** arcade-shared -** File description: -** UUId -*/ - -#include "UUId.hpp" - - -shared::types::UUId::UUId() -{ - uuid_generate(_uuid); -} - -shared::types::UUId::~UUId() -{ -} - -shared::types::UUId &shared::types::UUId::operator=(const UUId &other) -{ - if (this != &other) - uuid_copy(_uuid, other._uuid); - return *this; -} - -bool shared::types::UUId::operator==(const UUId &other) const -{ - return uuid_compare(_uuid, other._uuid) == 0; -} - -bool shared::types::UUId::operator!=(const UUId &other) const -{ - return uuid_compare(_uuid, other._uuid) != 0; -} - -bool shared::types::UUId::operator<(const UUId &other) const -{ - return uuid_compare(_uuid, other._uuid) < 0; -} - -bool shared::types::UUId::operator>(const UUId &other) const -{ - return uuid_compare(_uuid, other._uuid) > 0; -} - -bool shared::types::UUId::operator<=(const UUId &other) const -{ - return uuid_compare(_uuid, other._uuid) <= 0; -} - -bool shared::types::UUId::operator>=(const UUId &other) const -{ - return uuid_compare(_uuid, other._uuid) >= 0; -} - -std::string shared::types::UUId::toString() const -{ - char str[37]; - - uuid_unparse(_uuid, str); - return std::string(str); -} diff --git a/shared/types/UUId.hpp b/shared/types/UUId.hpp deleted file mode 100644 index 39ad2ad..0000000 --- a/shared/types/UUId.hpp +++ /dev/null @@ -1,89 +0,0 @@ -/* -** EPITECH PROJECT, 2024 -** arcade-shared -** File description: -** UUId -*/ - -#pragma once - -#include - -#include - -namespace shared::types { - class UUId; -} - -class shared::types::UUId -{ - public: - UUId(void); - ~UUId(); - - /** - * @brief Assign same value to this UUId - * - * @param other UUId in whcih value is to be assigned - * @return Passed instance of UUId - */ - UUId &operator=(const UUId &other); - - /** - * @brief Equality operator - * - * @param other UUId to be compared - * @return Equality status - */ - bool operator==(const UUId &other) const; - - /** - * @brief Different operator - * - * @param other UUId to be compared - * @return Difference status - */ - bool operator!=(const UUId &other) const; - - /** - * @brief Operator to compare if current UUId is less than other UUId - * - * @param other Other UUId to be compared - * @return Status of comparison - */ - bool operator<(const UUId &other) const; - - /** - * @brief Operator to compare if current UUId is greter than other UUId - * - * @param other Other UUId to be compared - * @return Status of comparison - */ - bool operator>(const UUId &other) const; - - /** - * @brief Operator to compare if current UUId is less than or equal to other UUId - * - * @param other Other UUId to be compared - * @return Status of comparison - */ - bool operator<=(const UUId &other) const; - - /** - * @brief Operator to compare if current UUId is greater than or equal to other UUId - * - * @param other Other UUId to be compared - * @return Status of comparison - */ - bool operator>=(const UUId &other) const; - - /** - * @brief Convert UUId to string - * - * @return String representation of UUId - */ - std::string toString(void) const; - - private: - uuid_t _uuid; -}; diff --git a/shared/types/types.hpp b/shared/types/types.hpp deleted file mode 100644 index 2fa7a26..0000000 --- a/shared/types/types.hpp +++ /dev/null @@ -1,11 +0,0 @@ -/* -** EPITECH PROJECT, 2024 -** arcade-shared -** File description: -** types -*/ - -#pragma once - -#include "Vector.hpp" -#include "UUId.hpp" From 5067c37c4177a3df1dca3cb6d1a4f08c4799ae5d Mon Sep 17 00:00:00 2001 From: Matheo Coquet Date: Wed, 27 Mar 2024 17:32:46 +0100 Subject: [PATCH 04/33] fix: compilation and dlloader --- core/src/loader/DLLoader.cpp | 20 +++++++++++++------- core/src/loader/DLLoader.hpp | 8 +++++--- core/src/types/Providers.hpp | 4 ++-- games/snake/export.cpp | 17 +++++++++-------- shared/games/components/ITextComponent.hpp | 2 +- shared/games/export.cpp.example | 11 +++++++---- shared/graphics/export.cpp.example | 13 ++++++++----- shared/graphics/types/TextProps.hpp | 9 +++------ shared/types/Color.hpp | 10 ++++++++-- shared/types/Libraries.hpp | 8 ++++---- 10 files changed, 60 insertions(+), 42 deletions(-) diff --git a/core/src/loader/DLLoader.cpp b/core/src/loader/DLLoader.cpp index a31a2bd..c9427b8 100644 --- a/core/src/loader/DLLoader.cpp +++ b/core/src/loader/DLLoader.cpp @@ -12,6 +12,15 @@ #include "DLLoader.hpp" #include "exception/ArcadeError.hpp" +DLLoader::DLLoader() = default; + +DLLoader::~DLLoader() { + for (auto &game : this->_gamesLibraries) + delete game; + for (auto &graphics : this->_graphicsLibraries) + delete graphics; +} + shared::types::LibraryType DLLoader::_getLibraryGetter(const std::string &filepath, void *handle) { shared::types::LibraryTypeGetter getter = nullptr; @@ -22,18 +31,15 @@ shared::types::LibraryType DLLoader::_getLibraryGetter(const std::string &filepa } void DLLoader::_loadGameLibrary(const std::string &filepath, void *handle) { - shared::types::GameProvider game = nullptr; + auto game = reinterpret_cast(dlsym(handle, SHARED_STRINGIFY(SHARED_GAME_PROVIDER_GETTER_NAME))); - game = reinterpret_cast(dlsym(handle, SHARED_STRINGIFY(SHARED_GAME_PROVIDER_LOADER_NAME))); if (!game) throw ArcadeError("Cannot find game provider in library: " + filepath); this->_gamesLibraries.push_back(game()); } void DLLoader::_loadGraphicsLibrary(const std::string &filepath, void *handle) { - shared::types::GraphicsProvider graphics = nullptr; - - graphics = reinterpret_cast(dlsym(handle, SHARED_STRINGIFY(SHARED_GRAPHICS_PROVIDER_LOADER_NAME))); + auto graphics = reinterpret_cast(dlsym(handle, SHARED_STRINGIFY(SHARED_GRAPHICS_PROVIDER_LOADER_NAME))); if (!graphics) throw ArcadeError("Cannot find graphics provider in library: " + filepath); this->_graphicsLibraries.push_back(graphics()); @@ -44,7 +50,7 @@ void DLLoader::registerLibrary(const std::string &filepath) { shared::types::LibraryType type; if (!handle) - throw ArcadeError("Cannot load library: " + filepath); + throw ArcadeError("Cannot load library: " + filepath + ": " + dlerror()); type = this->_getLibraryGetter(filepath, handle); if (type == shared::types::LibraryType::GAME) this->_loadGameLibrary(filepath, handle); @@ -79,4 +85,4 @@ const GameProviders &DLLoader::getGamesLibraries() const { const GraphicsProviders &DLLoader::getGraphicsLibraries() const { return this->_graphicsLibraries; -} +} \ No newline at end of file diff --git a/core/src/loader/DLLoader.hpp b/core/src/loader/DLLoader.hpp index ec7b363..a0f09e0 100644 --- a/core/src/loader/DLLoader.hpp +++ b/core/src/loader/DLLoader.hpp @@ -11,7 +11,9 @@ #include "types/Providers.hpp" class DLLoader { - public: +public: + DLLoader(); + ~DLLoader(); /** * @brief Register a library @@ -37,7 +39,7 @@ class DLLoader { */ const GraphicsProviders &getGraphicsLibraries() const; - private: +private: const std::string _path; GameProviders _gamesLibraries; GraphicsProviders _graphicsLibraries; @@ -63,4 +65,4 @@ class DLLoader { * @param handle handle pointer to the library */ void _loadGraphicsLibrary(const std::string &filepath, void *handle); -}; +}; \ No newline at end of file diff --git a/core/src/types/Providers.hpp b/core/src/types/Providers.hpp index 518f976..207b150 100644 --- a/core/src/types/Providers.hpp +++ b/core/src/types/Providers.hpp @@ -9,5 +9,5 @@ #include "shared/types/Libraries.hpp" -typedef std::vector> GameProviders; -typedef std::vector> GraphicsProviders; +typedef std::vector GameProviders; +typedef std::vector GraphicsProviders; diff --git a/games/snake/export.cpp b/games/snake/export.cpp index a5fd8e6..1cee3d2 100644 --- a/games/snake/export.cpp +++ b/games/snake/export.cpp @@ -9,14 +9,15 @@ #include "shared/games/IGameProvider.hpp" #include "shared/types/Libraries.hpp" +using namespace shared::games; +using namespace shared::types; + extern "C" { - shared::types::LibraryType SHARED_LIBRARY_TYPE_GETTER_NAME(void) - { - return shared::types::LibraryType::GAME; - } +LibraryType SHARED_LIBRARY_TYPE_GETTER_NAME(void) { + return LibraryType::GAME; +} - std::shared_ptr SHARED_GAME_PROVIDER_LOADER_NAME(void) - { - return std::make_shared(); - } +IGameProvider *SHARED_GAME_PROVIDER_GETTER_NAME(void) { + return new arcade::games::snake::SnakeGameProvider(); +} } diff --git a/shared/games/components/ITextComponent.hpp b/shared/games/components/ITextComponent.hpp index c0a269c..655d45e 100644 --- a/shared/games/components/ITextComponent.hpp +++ b/shared/games/components/ITextComponent.hpp @@ -28,7 +28,7 @@ namespace shared::games::components { typedef struct { std::string path; // Path of the font - types::Vector2u size; // Font size + unsigned int size; // Font size } TextFontProps; typedef struct { diff --git a/shared/games/export.cpp.example b/shared/games/export.cpp.example index 12b4ae3..938943b 100644 --- a/shared/games/export.cpp.example +++ b/shared/games/export.cpp.example @@ -8,14 +8,17 @@ #include "IGame.hpp" #include "../types/Libraries.hpp" +using namespace shared::games; +using namespace shared::types; + extern "C" { - shared::types::LibraryType SHARED_LIBRARY_TYPE_GETTER_NAME(void) + LibraryType SHARED_LIBRARY_TYPE_GETTER_NAME(void) { - return shared::types::LibraryType::GAME; + return LibraryType::GAME; } - std::shared_ptr SHARED_GAME_PROVIDER_LOADER_NAME(void) + IGameProvider* SHARED_GAME_PROVIDER_GETTER_NAME(void) { - return std::make_shared(...) + return new YOUR_CLASS(); } } diff --git a/shared/graphics/export.cpp.example b/shared/graphics/export.cpp.example index d3e00de..d8e1b45 100644 --- a/shared/graphics/export.cpp.example +++ b/shared/graphics/export.cpp.example @@ -5,17 +5,20 @@ ** export */ -#include "IGraphicsFactory.hpp" +#include "IGraphicsProvider.hpp" #include "../types/Libraries.hpp" +using namespace shared::graphics; +using namespace shared::types; + extern "C" { - shared::types::LibraryType SHARED_LIBRARY_TYPE_GETTER_NAME(void) + LibraryType SHARED_LIBRARY_TYPE_GETTER_NAME(void) { - return shared::types::LibraryType::GRAPHIC; + return LibraryType::GRAPHIC; } - std::shared_ptr SHARED_GRAPHICS_PROVIDER_LOADER_NAME(void) + IGraphicsProvider *SHARED_GRAPHICS_PROVIDER_GETTER_NAME(void) { - return std::make_shared(...); + return new YOUR_CLASS(); } } diff --git a/shared/graphics/types/TextProps.hpp b/shared/graphics/types/TextProps.hpp index 2d7187a..9f01dc9 100644 --- a/shared/graphics/types/TextProps.hpp +++ b/shared/graphics/types/TextProps.hpp @@ -7,6 +7,7 @@ #pragma once +#include #include #include "../IFont.hpp" @@ -29,12 +30,8 @@ namespace shared::graphics { } TextVerticalAlign; typedef struct { - std::string path; // Path of the font - types::Vector2u size; // Font size - } TextFontProps; - - typedef struct { - std::shared_ptr font; // Font of the text + std::shared_ptr font; // Font of the text + unsigned int fontSize; // Font size std::string content; // Content of the text TextAlign align; // Alignment of the text TextVerticalAlign verticalAlign; // Vertical alignment of the text diff --git a/shared/types/Color.hpp b/shared/types/Color.hpp index b512852..b6fe6e2 100644 --- a/shared/types/Color.hpp +++ b/shared/types/Color.hpp @@ -7,9 +7,15 @@ #pragma once -namespace shared::types { +namespace shared::types +{ typedef struct ColorType { - ColorType(unsigned char r, unsigned char g, unsigned char b, unsigned char a) : r(r), g(g), b(b), a(a) {} + ColorType( + unsigned char r, + unsigned char g, + unsigned char b, + unsigned char a + ) : r(r), g(g), b(b), a(a) {} unsigned char r; unsigned char g; diff --git a/shared/types/Libraries.hpp b/shared/types/Libraries.hpp index 9711994..1d2629f 100644 --- a/shared/types/Libraries.hpp +++ b/shared/types/Libraries.hpp @@ -10,8 +10,8 @@ #include "../games/IGameProvider.hpp" #include "../graphics/IGraphicsProvider.hpp" -#define SHARED_GAME_PROVIDER_LOADER_NAME arcadeLibGetGameProvider -#define SHARED_GRAPHICS_PROVIDER_LOADER_NAME arcadeLibGetGraphicsProvider +#define SHARED_GAME_PROVIDER_GETTER_NAME arcadeLibGetGameProvider +#define SHARED_GRAPHICS_PROVIDER_GETTER_NAME arcadeLibGetGraphicsProvider #define SHARED_LIBRARY_TYPE_GETTER_NAME arcadeLibGetType #define STRINGIFY(x) #x #define SHARED_STRINGIFY(x) STRINGIFY(x) @@ -23,7 +23,7 @@ namespace shared::types GRAPHIC, } LibraryType; - typedef std::shared_ptr (*GameProvider)(void); - typedef std::shared_ptr (*GraphicsProvider)(void); + typedef games::IGameProvider* (*GameProviderGetter)(void); + typedef graphics::IGraphicsProvider* (*GraphicsProviderGetter)(void); typedef LibraryType (*LibraryTypeGetter)(void); } From fca621ec0ac83bd6f7ab9ffe570f869efad3b139 Mon Sep 17 00:00:00 2001 From: Matheo Coquet Date: Thu, 28 Mar 2024 09:51:56 +0100 Subject: [PATCH 05/33] feat(games): add entity abstract --- core/main.cpp | 2 ++ games/common/CMakeLists.txt | 2 ++ games/common/entity/AEntity.cpp | 15 +++++++++++++++ games/common/entity/AEntity.hpp | 34 +++++++++++++++++++++++++++++++++ games/common/game/AGame.cpp | 4 ++-- games/common/game/AGame.hpp | 13 ++++++------- games/snake/src/Snake.cpp | 15 +++++++++++++-- games/snake/src/Snake.hpp | 24 ++++++++++++++++++----- games/snake/src/SnakeGame.cpp | 10 ++++++++-- shared/games/IGame.hpp | 2 +- 10 files changed, 102 insertions(+), 19 deletions(-) create mode 100644 games/common/entity/AEntity.cpp create mode 100644 games/common/entity/AEntity.hpp diff --git a/core/main.cpp b/core/main.cpp index 769a187..ee66021 100644 --- a/core/main.cpp +++ b/core/main.cpp @@ -25,5 +25,7 @@ int main(void) { std::cout << "Game authors: " << manifest.authors[0].name << std::endl; auto game = lib->createInstance(); + std::cout << "\n[ Compute 1 ]\n" << std::endl; + game->compute(1); return 0; } diff --git a/games/common/CMakeLists.txt b/games/common/CMakeLists.txt index 5df3b36..7114ee3 100644 --- a/games/common/CMakeLists.txt +++ b/games/common/CMakeLists.txt @@ -1,5 +1,7 @@ target_sources(${PROJECT_NAME} PUBLIC game/AGame.cpp game/AGame.hpp + entity/AEntity.cpp + entity/AEntity.hpp ) target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_LIST_DIR}/../..) diff --git a/games/common/entity/AEntity.cpp b/games/common/entity/AEntity.cpp new file mode 100644 index 0000000..8c73476 --- /dev/null +++ b/games/common/entity/AEntity.cpp @@ -0,0 +1,15 @@ +/* +** EPITECH PROJECT, 2024 +** AEntity.cpp +** File description: +** AEntity class +*/ + +#include "AEntity.hpp" + +using namespace arcade::games; +using namespace shared::games; + +const components::ComponentsMap &arcade::games::common::AEntity::getComponents() const noexcept { + return this->_components; +} diff --git a/games/common/entity/AEntity.hpp b/games/common/entity/AEntity.hpp new file mode 100644 index 0000000..3bc512d --- /dev/null +++ b/games/common/entity/AEntity.hpp @@ -0,0 +1,34 @@ +/* +** EPITECH PROJECT, 2024 +** AEntity.hpp +** File description: +** AEntity class +*/ + +#pragma once + +#include "shared/games/IEntity.hpp" + +namespace arcade::games::common { + class AEntity; +} + +class arcade::games::common::AEntity : public shared::games::entity::IEntity { +public: + ~AEntity() override = default; + + /** + * @brief Get the components of the entity + * + * @return Components of the entity + */ + const shared::games::components::ComponentsMap &getComponents() const noexcept override; + +protected: + /** + * @brief Create a entity + */ + explicit AEntity() = default; + + shared::games::components::ComponentsMap _components; +}; diff --git a/games/common/game/AGame.cpp b/games/common/game/AGame.cpp index 2b2e7a5..f8999bf 100644 --- a/games/common/game/AGame.cpp +++ b/games/common/game/AGame.cpp @@ -11,7 +11,7 @@ using namespace arcade::games; -common::AGame::AGame(shared::types::Vector2u size) : _size(size) { +common::AGame::AGame(shared::types::Vector2u size, unsigned int fps) : _size(size), _fps(fps) { this->_entities = {}; } @@ -27,6 +27,6 @@ const unsigned int common::AGame::getFps() const noexcept { return this->_fps; } -void common::AGame::_registerEntity(EntityPtr entity) { +void common::AGame::_registerEntity(shared::games::entity::EntityPtr entity) { this->_entities.push_back(std::move(entity)); } diff --git a/games/common/game/AGame.hpp b/games/common/game/AGame.hpp index 26e5748..1f9fcf3 100644 --- a/games/common/game/AGame.hpp +++ b/games/common/game/AGame.hpp @@ -13,8 +13,6 @@ namespace arcade::games::common { class AGame; - - typedef std::shared_ptr EntityPtr; } class arcade::games::common::AGame : public shared::games::IGame { @@ -22,9 +20,9 @@ class arcade::games::common::AGame : public shared::games::IGame { ~AGame() override = default; /** - * @brief Get map of entities + * @brief Get map of entity * - * @return Map of entities + * @return Map of entity */ const shared::games::entity::EntitiesMap &getEntities() const override; @@ -47,11 +45,12 @@ class arcade::games::common::AGame : public shared::games::IGame { * @brief Construct a new AGame object * * @param size Size of the game + * @param fps Fps of the game */ - explicit AGame(shared::types::Vector2u size); + explicit AGame(shared::types::Vector2u size, unsigned int fps); /** - * @brief List of game entities + * @brief List of game entity */ shared::games::entity::EntitiesMap _entities; @@ -72,5 +71,5 @@ class arcade::games::common::AGame : public shared::games::IGame { * @return Id of the entity * @warning This method is moving ownership of the entity */ - void _registerEntity(EntityPtr entity); + void _registerEntity(shared::games::entity::EntityPtr entity); }; diff --git a/games/snake/src/Snake.cpp b/games/snake/src/Snake.cpp index be77d95..802e696 100644 --- a/games/snake/src/Snake.cpp +++ b/games/snake/src/Snake.cpp @@ -6,11 +6,22 @@ */ #include "Snake.hpp" +#include "common/entity/AEntity.hpp" +using namespace shared::games::entity; using namespace arcade::games::snake; -Snake::Snake() { +Snake::Snake(unsigned int tails) { + for (size_t i = 0; i < tails; i++) { + this->addTail(); + } } -Snake::~Snake() { +Snake::~Snake() = default; + +std::vector &Snake::getTails() { + return this->_tails; +} + +EntityPtr Snake::addTail() { } diff --git a/games/snake/src/Snake.hpp b/games/snake/src/Snake.hpp index 9ee4143..3e481e8 100644 --- a/games/snake/src/Snake.hpp +++ b/games/snake/src/Snake.hpp @@ -19,18 +19,32 @@ namespace arcade::games::snake { class arcade::games::snake::Snake { public: - Snake(); + explicit Snake(unsigned int tails); ~Snake(); /** - * @brief Entities that compose the snake + * @brief Head of the snake * */ - std::vector body; + shared::games::entity::EntityPtr head; /** - * @brief Head of the snake + * @brief Add a tail to the snake body + * + * @return The entity to the new tail + */ + shared::games::entity::EntityPtr addTail(); + + /** + * Get tails of the snake + * + * @return Vector of tails + */ + std::vector &getTails(); +protected: + /** + * @brief Entities that compose the snake * */ - common::EntityPtr head; + std::vector _tails; }; diff --git a/games/snake/src/SnakeGame.cpp b/games/snake/src/SnakeGame.cpp index 4a36771..8903d2f 100644 --- a/games/snake/src/SnakeGame.cpp +++ b/games/snake/src/SnakeGame.cpp @@ -28,8 +28,13 @@ const shared::games::GameManifest snake::SnakeGame::manifest = { } }; -snake::SnakeGame::SnakeGame() : common::AGame(Vector2u(19, 19)) { - this->_snake = std::make_unique(); +snake::SnakeGame::SnakeGame() : common::AGame(Vector2u(19, 19), 60) { + this->_snake = std::make_unique(2); + this->_registerEntity(this->_snake->head); + + for (auto &tail: this->_snake->getTails()) { + this->_registerEntity(tail); + } } snake::SnakeGame::~SnakeGame() = default; @@ -41,4 +46,5 @@ const shared::games::GameManifest &snake::SnakeGame::getManifest() const noexcep void snake::SnakeGame::compute(shared::games::DeltaTime dt) { std::cout << "SnakeGame::compute" << std::endl; std::cout << "DeltaTime: " << dt << std::endl; + std::cout << "Number of entity: " << this->_entities.size() << std::endl; } diff --git a/shared/games/IGame.hpp b/shared/games/IGame.hpp index bc8353d..89df01c 100644 --- a/shared/games/IGame.hpp +++ b/shared/games/IGame.hpp @@ -56,7 +56,7 @@ class shared::games::IGame virtual const unsigned int getFps() const noexcept = 0; /** - * @brief Get map of entities + * @brief Get map of entity * * @return Entities map of the game */ From 4fb6af4942cfe0ecba40eb2878aa1bb75fdee85d Mon Sep 17 00:00:00 2001 From: Matheo Coquet Date: Thu, 28 Mar 2024 15:00:46 +0100 Subject: [PATCH 06/33] feat(games): add games components --- games/common/CMakeLists.txt | 10 +++ games/common/components/AComponent.cpp | 24 +++++++ games/common/components/AComponent.hpp | 44 +++++++++++++ .../components/ADisplayableComponent.cpp | 30 +++++++++ .../components/ADisplayableComponent.hpp | 62 +++++++++++++++++++ .../common/components/CollidableComponent.cpp | 19 ++++++ .../common/components/CollidableComponent.hpp | 33 ++++++++++ games/common/components/PositionComponent.cpp | 19 ++++++ games/common/components/PositionComponent.hpp | 36 +++++++++++ games/common/components/TextureComponent.cpp | 22 +++++++ games/common/components/TextureComponent.hpp | 33 ++++++++++ 11 files changed, 332 insertions(+) create mode 100644 games/common/components/AComponent.cpp create mode 100644 games/common/components/AComponent.hpp create mode 100644 games/common/components/ADisplayableComponent.cpp create mode 100644 games/common/components/ADisplayableComponent.hpp create mode 100644 games/common/components/CollidableComponent.cpp create mode 100644 games/common/components/CollidableComponent.hpp create mode 100644 games/common/components/PositionComponent.cpp create mode 100644 games/common/components/PositionComponent.hpp create mode 100644 games/common/components/TextureComponent.cpp create mode 100644 games/common/components/TextureComponent.hpp diff --git a/games/common/CMakeLists.txt b/games/common/CMakeLists.txt index 7114ee3..6a5390f 100644 --- a/games/common/CMakeLists.txt +++ b/games/common/CMakeLists.txt @@ -3,5 +3,15 @@ target_sources(${PROJECT_NAME} PUBLIC game/AGame.hpp entity/AEntity.cpp entity/AEntity.hpp + components/AComponent.cpp + components/AComponent.hpp + components/PositionComponent.cpp + components/PositionComponent.hpp + components/ADisplayableComponent.cpp + components/ADisplayableComponent.hpp + components/CollidableComponent.hpp + components/CollidableComponent.cpp + components/TextureComponent.hpp + components/TextureComponent.cpp ) target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_LIST_DIR}/../..) diff --git a/games/common/components/AComponent.cpp b/games/common/components/AComponent.cpp new file mode 100644 index 0000000..792cd38 --- /dev/null +++ b/games/common/components/AComponent.cpp @@ -0,0 +1,24 @@ +/* +** EPITECH PROJECT, 2024 +** AComponent.cpp +** File description: +** AComponent class +*/ + +#include +#include "AComponent.hpp" + +using namespace arcade::games::common::components; + +AComponent::AComponent(shared::games::components::ComponentType type, shared::games::entity::IEntity &entity) : _parent( + entity) { + this->_type = type; +} + +const shared::games::components::ComponentType AComponent::getType() const noexcept { + return this->_type; +} + +const shared::games::entity::IEntity &AComponent::getEntity() noexcept { + return this->_parent; +} diff --git a/games/common/components/AComponent.hpp b/games/common/components/AComponent.hpp new file mode 100644 index 0000000..93d356d --- /dev/null +++ b/games/common/components/AComponent.hpp @@ -0,0 +1,44 @@ +/* +** EPITECH PROJECT, 2024 +** AComponent.hpp +** File description: +** AComponent class +*/ + +#pragma once + +#include "shared/games/components/IComponent.hpp" + +namespace arcade::games::common::components { + class AComponent; +} + +class arcade::games::common::components::AComponent : public virtual shared::games::components::IComponent { +public: + ~AComponent() override = default; + + /** + * @brief Get the type of the component + * + * @return Type of the component + */ + const shared::games::components::ComponentType getType() const noexcept override; + + /** + * @brief Get the parent entity of the component + * + * @return Entity of the component + */ + const shared::games::entity::IEntity &getEntity() noexcept override; + +protected: + /** + * @brief Create a component + * + * @param entity Entity parent of the component + */ + explicit AComponent(shared::games::components::ComponentType type, shared::games::entity::IEntity &entity); + + shared::games::entity::IEntity &_parent; + shared::games::components::ComponentType _type; +}; diff --git a/games/common/components/ADisplayableComponent.cpp b/games/common/components/ADisplayableComponent.cpp new file mode 100644 index 0000000..e23697a --- /dev/null +++ b/games/common/components/ADisplayableComponent.cpp @@ -0,0 +1,30 @@ +/* +** EPITECH PROJECT, 2024 +** ADisplayableComponent.cpp +** File description: +** ADisplayableComponent class +*/ + +#include "ADisplayableComponent.hpp" + +using namespace arcade::games::common::components; +using namespace shared::games; + +ADisplayableComponent::ADisplayableComponent(entity::IEntity &entity, Vector2u size, unsigned int zindex) + : PositionComponent(entity), + _size(size), _zindex(zindex) { +} + +Vector2u &ADisplayableComponent::getSize() noexcept { + return this->_size; +} + +unsigned int &ADisplayableComponent::getZIndex() noexcept { + return this->_zindex; +} + +void ADisplayableComponent::onMousePress(std::shared_ptr &ctx) {} + +void ADisplayableComponent::onMouseHover(std::shared_ptr &ctx) {} + +void ADisplayableComponent::onMouseRelease(std::shared_ptr &ctx) {} diff --git a/games/common/components/ADisplayableComponent.hpp b/games/common/components/ADisplayableComponent.hpp new file mode 100644 index 0000000..de26bb7 --- /dev/null +++ b/games/common/components/ADisplayableComponent.hpp @@ -0,0 +1,62 @@ +/* +** EPITECH PROJECT, 2024 +** ADisplayableComponent.hpp +** File description: +** ADisplayableComponent class +*/ + +#pragma once + +#include "shared/games/components/IDisplayableComponent.hpp" +#include "PositionComponent.hpp" + +namespace arcade::games::common::components { + class ADisplayableComponent; +} + +class arcade::games::common::components::ADisplayableComponent : public virtual shared::games::components::IDisplayableComponent, public PositionComponent { +public: + ~ADisplayableComponent() override = default; + + /** + * @brief Get size of the entity (tiles) + * + */ + Vector2u &getSize() noexcept override; + + /** + * @brief Get Z index that is usefull for display prioroty + * + */ + unsigned int &getZIndex() noexcept override; + + /** + * @brief On click event handler for the entity + * @param ctx Context of the game + */ + void onMousePress(std::shared_ptr &ctx) override; + + /** + * @brief On release event handler for the entity + * @param ctx Context of the game + */ + void onMouseRelease(std::shared_ptr &ctx) override; + + /** + * @brief On hover event handler for the entity + * @param ctx Context of the game + */ + void onMouseHover(std::shared_ptr &ctx) override; + +protected: + /** + * Create a displayable component + * @param entity + * @param size + * @param zindex + */ + explicit ADisplayableComponent(shared::games::entity::IEntity &entity, Vector2u size, unsigned int zindex); + + Vector2u _size; + unsigned int _zindex; +}; diff --git a/games/common/components/CollidableComponent.cpp b/games/common/components/CollidableComponent.cpp new file mode 100644 index 0000000..2690679 --- /dev/null +++ b/games/common/components/CollidableComponent.cpp @@ -0,0 +1,19 @@ +/* +** EPITECH PROJECT, 2024 +** CollidableComponent.cpp +** File description: +** CollidableComponent class +*/ + +#include "CollidableComponent.hpp" +#include + +using namespace arcade::games::common::components; + +CollidableComponent::CollidableComponent(shared::games::entity::IEntity &entity) : PositionComponent(entity) { + this->_type = shared::games::components::COLLIDABLE; +} + +void CollidableComponent::onCollide(std::shared_ptr &ctx, + std::shared_ptr target) { +} diff --git a/games/common/components/CollidableComponent.hpp b/games/common/components/CollidableComponent.hpp new file mode 100644 index 0000000..cd238ce --- /dev/null +++ b/games/common/components/CollidableComponent.hpp @@ -0,0 +1,33 @@ +/* +** EPITECH PROJECT, 2024 +** CollidableComponent.hpp +** File description: +** CollidableComponent class +*/ + +#pragma once + +#include "shared/games/components/ICollidableComponent.hpp" +#include "PositionComponent.hpp" + +namespace arcade::games::common::components { + class CollidableComponent; +} + +class arcade::games::common::components::CollidableComponent : public virtual shared::games::components::ICollidableComponent, public PositionComponent { +public: + ~CollidableComponent() override = default; + + /** + * @brief Create a position component + * @param entity + */ + explicit CollidableComponent(shared::games::entity::IEntity &entity); + + /** + * @brief On collide event handler for the component + * @param ctx Context of the game + * @param target Target entity + */ + void onCollide(std::shared_ptr &ctx, std::shared_ptr target) override; +}; diff --git a/games/common/components/PositionComponent.cpp b/games/common/components/PositionComponent.cpp new file mode 100644 index 0000000..5396a19 --- /dev/null +++ b/games/common/components/PositionComponent.cpp @@ -0,0 +1,19 @@ +/* +** EPITECH PROJECT, 2024 +** PositionComponent.cpp +** File description: +** PositionComponent class +*/ + +#include "PositionComponent.hpp" + +using namespace arcade::games::common::components; +using namespace shared::games::components; + +PositionComponent::PositionComponent(shared::games::entity::IEntity &entity) : AComponent(POSITION, entity), + _position(0, 0) { +} + +shared::types::Vector2i &PositionComponent::getPosition() noexcept { + return this->_position; +} diff --git a/games/common/components/PositionComponent.hpp b/games/common/components/PositionComponent.hpp new file mode 100644 index 0000000..b64d83a --- /dev/null +++ b/games/common/components/PositionComponent.hpp @@ -0,0 +1,36 @@ +/* +** EPITECH PROJECT, 2024 +** PositionComponent.hpp +** File description: +** PositionComponent class +*/ + +#pragma once + +#include "shared/games/components/IPositionComponent.hpp" +#include "AComponent.hpp" + +namespace arcade::games::common::components { + class PositionComponent; +} + +class arcade::games::common::components::PositionComponent + : public AComponent, public virtual shared::games::components::IPositionComponent { +public: + ~PositionComponent() override = default; + + /** + * @brief Create a position component + * @param entity + */ + explicit PositionComponent(shared::games::entity::IEntity &entity); + + /** + * @brief Get position of the entity (tiles) + * + */ + shared::types::Vector2i &getPosition() noexcept override; + +protected: + shared::types::Vector2i _position; +}; diff --git a/games/common/components/TextureComponent.cpp b/games/common/components/TextureComponent.cpp new file mode 100644 index 0000000..20a79cf --- /dev/null +++ b/games/common/components/TextureComponent.cpp @@ -0,0 +1,22 @@ +/* +** EPITECH PROJECT, 2024 +** TextureComponent.cpp +** File description: +** TextureComponent class +*/ + +#include "TextureComponent.hpp" + +using namespace arcade::games::common::components; + +TextureComponent::TextureComponent(shared::games::entity::IEntity &entity, + Vector2u size, unsigned int zindex, + shared::games::components::TextureProps &props) + : ADisplayableComponent(entity, size, zindex), + _textureProps(props) { + this->_type = shared::games::components::TEXTURE; +} + +shared::games::components::TextureProps &TextureComponent::getTextureProps() noexcept { + return this->_textureProps; +} diff --git a/games/common/components/TextureComponent.hpp b/games/common/components/TextureComponent.hpp new file mode 100644 index 0000000..647cd3b --- /dev/null +++ b/games/common/components/TextureComponent.hpp @@ -0,0 +1,33 @@ +/* +** EPITECH PROJECT, 2024 +** TextureComponent.hpp +** File description: +** TextureComponent class +*/ + +#pragma once + +#include "shared/games/components/ITextureComponent.hpp" +#include "ADisplayableComponent.hpp" + +namespace arcade::games::common::components { + class TextureComponent; +} + +class arcade::games::common::components::TextureComponent + : public virtual shared::games::components::ITextureComponent, public ADisplayableComponent { +public: + ~TextureComponent() override = default; + + explicit TextureComponent(shared::games::entity::IEntity &entity, Vector2u size, unsigned int zindex, + shared::games::components::TextureProps &props); + + /** + * @brief Get texture properties + * + */ + shared::games::components::TextureProps &getTextureProps() noexcept override; + +protected: + shared::games::components::TextureProps _textureProps; +}; From cb600145008b3f603d8f6bf0679f3f3e9d88d251 Mon Sep 17 00:00:00 2001 From: Matheo Coquet Date: Thu, 28 Mar 2024 15:01:07 +0100 Subject: [PATCH 07/33] feat(snake): add snake assets --- assets/snake/snake.png | Bin 0 -> 3605 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 assets/snake/snake.png diff --git a/assets/snake/snake.png b/assets/snake/snake.png new file mode 100644 index 0000000000000000000000000000000000000000..48783589821faf3bf6a4e3baab3dd243f337b28b GIT binary patch literal 3605 zcmb`KXH*l;vcMC1?*bwn47~{`y#@m!RS=~KL_~T=X;MNb2>xTC2|*A6r6y7XL`1s8 zP$Qu#J<@v#Jbd?@_wN0EKg`bA-|o!pnVGYDHr3J`!py+O0001(O^m_T7aI9j=x8p+ zbexCWg`y8Iz8?$#FmnDCARsrN_W}Zgtsw@0szLshiwTv7zL`D%P@Bnk>Pmg#slo)T zZ}Swm_SVA35hBnXd&SY4lZAzF@FOkt2mcNWau1lf=uL6<1jT^ePy69>*(M zQ{<<}1R`k@Ui_1Cr#Bc6vmfUgxlwjmfZ{$~I_&)I%; z(44T`zv92&)tWtssSl3wlD3D7+W!eFzO!1{G;)<_H8QmvwsKqynIgp;t^M)kNZ?BJ z%|%tO7kGWv_;@P>$J1nyx>afZ;d9j5xbhVn_FCXqktd9e=ppU8mXiP@`W5%9I?@bO zAJ?Pp=np^V+4m7P}RZ|r}PuaWnXi`& znGIuL$6|3rCr_~T5<9=DF2>B&M+_mQN05~-aGa0BND70aDB)bLr2tn&gqY*v0tKx$ zWVq+g3Y?H=608`srylgdAM zyE`sNSz=#&@HO!KMiO^|+=sC}UnnY7Frmh$jhi(;?-b}46+!a{KJ~Oz4A*Kiki$AHtuHq{i zUL^o^`&_MXH$#?vaFz>IC}J8tVhjvItAy`#Ch>E?vsX)BP=rhkWfx4!)?B$Qccb-Y z2cV2|*u1IhdAw7-iqTF-o5vmrM6Yxs^eq$q90$nO2)0_o02Z<^cNBUZ9rDGFC@D~ag$G0xtK^}ub&f=418 zTJwd1SKi8pnm=e!X)zI8Qcjz63K+FS85uU1OWSibJjO_3wW_{p+pyUk!NtZ^27X(j zM(y}QmdEOEp|s0iY(t71N`4-0{DgsVy5mI~^+J1RXQX4U);;s|Fu`5_oY4a1+Q(y# zxCEa*=R(#Wd1dUElh?X*Y^j+Rn|pn;>;m=Fj=#0+p3ypx+uOt3UOTIwj9^ulLH?&L z6SpUFs-Mu<>jWH4Kz0iqG%t3X?pjS8mpt`&H42ol!nixEep@%hb*fIs>QP!(?ZmA|(QCe)kUfL;Un_7JnZtzsrC66F;QsmW` z1>qIhLu!Giv)GyCcsUpTrx8LW{K~sq-ssyrG3YlrG-o#=vu@o{AwT@-!%7egZ38d0 z1t+u}bRb%1JWp7WwpD3T89Taa*Ru}DPTq)1hN8PV#!b$Gt8spT{NYvQLH^sh7p8^G z@#|-W=eDAU`-m>~%|zYX4od1-G()#wS}$(&x%8v)O!=3G5`-7X6DFBsx96Km`&!Gr zBiuide6m;@-c8$>*5!42W0KER~JKoYqP#$LDGl`AvmJle0>iF<2B!Wt+Y zJ2~IMm_-G5|GH*pP$YpZ4bMA#Seyp z!Owm9+I$@*<8e-G4vg6cQ|^6!dy2^FxWvg>s1?f{&_jI4bsb~I;0O(|*k3EFY8Kre zZzW?xb(DG$wDur>gcV`)dT*pzosUVBRz-hU=d(|cm>roXD;e!ElTWBktwZ$=)e7f) z>3GFOE#@<>5%S}UM|vsc5Dg~W^%%45(n47W4x!A|I)PfDK{mUyQmVtn?$#N?$Gp>8>h@aItb?MQmWQcDdQ`1BWLJOAecw#vlJ7sSx|$dd#+}sTJ6zg=wk$PqpX;wn zB%&4WLE-WE6P2&ipuJ{~C1c$cU$+wTuQM<0roFAc5YD~C++uP|*BJ#rE46-z1x4f? zKC|KJ$PoTz_){vEZJ+u#id4qae}5~6DV_A4{_Hn&Q=D@lp3}-d{2wtjcC2uMoSGFv zG;2)Kfb`*Nh8TGh${_AttVQDka{%q=Vyd=#Vf>@+T}_8>w^-;PECjWk%Mdo&QG&`T zNvFcw=jc}(Tb;OC^$B$wV21NCNs~lBxLFx!A6)yu85p#%ScGgd-~OUNLUD=Y#30h@(wA zPcymx`=rYun!|cN-E-niBhv1%a}w|9v$-$(kgIF zQkGj$Y>pH+y%o0*kuzqG`wau!=!Y}yX@8+k9a*ZV^bm0B0`}F#oV_KZED6*p>>{s9 z`dSNutuG&3*>aW7M>0t=j;d_o z)7{o0rkl5GQrTb`&EII%s2elX6)RHA#pWg74;rOlMqDUa!`6UE0#!(Fh10tW#P>ECjvLz88IejnFs*E-hd!i5zW z91}LdwMx>{x&e8gQkx{@sR*2frWP&&&6Q?xIMxoHOzC&SE}B~?KcEKBgMoyUfZ8;< zvJEHko2y*Hd53Nwy@X&}AN^~;!AO;!#T=dvH^$4L=`G9`3urmG(w z+hM?hF2&THrMVBvxfg9X-%KnDv8gOo#X^d_yZzzuq(j37r$6>%v*yvIzFqDt%;ecQ36y*4SK(=DMd{KMD`ovKStPnI1hD{9I~Wtnt8 wMA<}|xjEoSzaeD_QN4a_mB^Qraz7nfM5)mOqcJ4y#V-zEVq^}kGH{9iAHE&j%m4rY literal 0 HcmV?d00001 From 57b6f9d60b7c835bb9a5f20395cd87f5aad80724 Mon Sep 17 00:00:00 2001 From: Matheo Coquet Date: Thu, 28 Mar 2024 15:01:21 +0100 Subject: [PATCH 08/33] feat(snake): add tail entity --- games/snake/CMakeLists.txt | 6 ++-- games/snake/src/SnakeGame.cpp | 2 +- games/snake/src/SnakeGame.hpp | 2 +- .../snake/src/{ => entities/snake}/Snake.cpp | 8 +++-- .../snake/src/{ => entities/snake}/Snake.hpp | 2 +- games/snake/src/entities/snake/TailEntity.cpp | 33 +++++++++++++++++++ games/snake/src/entities/snake/TailEntity.hpp | 21 ++++++++++++ 7 files changed, 67 insertions(+), 7 deletions(-) rename games/snake/src/{ => entities/snake}/Snake.cpp (72%) rename games/snake/src/{ => entities/snake}/Snake.hpp (98%) create mode 100644 games/snake/src/entities/snake/TailEntity.cpp create mode 100644 games/snake/src/entities/snake/TailEntity.hpp diff --git a/games/snake/CMakeLists.txt b/games/snake/CMakeLists.txt index 33a7066..6a7c659 100644 --- a/games/snake/CMakeLists.txt +++ b/games/snake/CMakeLists.txt @@ -3,8 +3,10 @@ add_library(${PROJECT_NAME} SHARED export.cpp src/SnakeGameProvider.cpp src/SnakeGame.cpp - src/Snake.cpp - src/Snake.hpp + src/entities/snake/Snake.cpp + src/entities/snake/Snake.hpp + src/entities/snake/TailEntity.cpp + src/entities/snake/TailEntity.hpp ) add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/../common PRIVATE) target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_LIST_DIR}/src) diff --git a/games/snake/src/SnakeGame.cpp b/games/snake/src/SnakeGame.cpp index 8903d2f..ac4e800 100644 --- a/games/snake/src/SnakeGame.cpp +++ b/games/snake/src/SnakeGame.cpp @@ -11,7 +11,7 @@ using namespace arcade::games; const shared::games::GameManifest snake::SnakeGame::manifest = { - .name = "Snake", + .name = "snake", .description = "The snake original game", .version = "1.0.0", .authors = { diff --git a/games/snake/src/SnakeGame.hpp b/games/snake/src/SnakeGame.hpp index 2787640..1193983 100644 --- a/games/snake/src/SnakeGame.hpp +++ b/games/snake/src/SnakeGame.hpp @@ -8,7 +8,7 @@ #pragma once #include "common/game/AGame.hpp" -#include "Snake.hpp" +#include "games/snake/src/entities/snake/Snake.hpp" namespace arcade::games::snake { class SnakeGame; diff --git a/games/snake/src/Snake.cpp b/games/snake/src/entities/snake/Snake.cpp similarity index 72% rename from games/snake/src/Snake.cpp rename to games/snake/src/entities/snake/Snake.cpp index 802e696..a2df832 100644 --- a/games/snake/src/Snake.cpp +++ b/games/snake/src/entities/snake/Snake.cpp @@ -2,11 +2,11 @@ ** EPITECH PROJECT, 2024 ** arcade ** File description: -** Snake.cpp +** snake.cpp */ #include "Snake.hpp" -#include "common/entity/AEntity.hpp" +#include "TailEntity.hpp" using namespace shared::games::entity; using namespace arcade::games::snake; @@ -24,4 +24,8 @@ std::vector &Snake::getTails() { } EntityPtr Snake::addTail() { + EntityPtr newTail = std::make_shared(); + + this->_tails.push_back(newTail); + return newTail; } diff --git a/games/snake/src/Snake.hpp b/games/snake/src/entities/snake/Snake.hpp similarity index 98% rename from games/snake/src/Snake.hpp rename to games/snake/src/entities/snake/Snake.hpp index 3e481e8..72183b4 100644 --- a/games/snake/src/Snake.hpp +++ b/games/snake/src/entities/snake/Snake.hpp @@ -2,7 +2,7 @@ ** EPITECH PROJECT, 2024 ** arcade ** File description: -** Snake.hpp +** snake.hpp */ #pragma once diff --git a/games/snake/src/entities/snake/TailEntity.cpp b/games/snake/src/entities/snake/TailEntity.cpp new file mode 100644 index 0000000..d489e57 --- /dev/null +++ b/games/snake/src/entities/snake/TailEntity.cpp @@ -0,0 +1,33 @@ +/* +** EPITECH PROJECT, 2024 +** TailEntity.cpp +** File description: +** TailEntity class +*/ + +#include +#include "TailEntity.hpp" +#include "common/components/CollidableComponent.hpp" +#include "common/components/TextureComponent.hpp" +#include "shared/games/components/ITextureComponent.hpp" + +using namespace arcade::games::common::components; +using namespace shared::games::components; + +arcade::games::snake::TailEntity::TailEntity() { + TextureProps tailTextureProps = { + .sources = { + .ascii = "assets/snake/snake.ascii", + .bin = "assets/snake/snake.png", + .binTileSize = Vector2f(40, 40) + }, + .origin = Vector2u(0, 0) + }; + + std::shared_ptr collide = std::make_shared(*this); + std::shared_ptr texture = std::make_shared(*this, Vector2u(1, 1), 10, + tailTextureProps); + + this->_components.push_back(collide); + this->_components.push_back(texture); +} diff --git a/games/snake/src/entities/snake/TailEntity.hpp b/games/snake/src/entities/snake/TailEntity.hpp new file mode 100644 index 0000000..93daa48 --- /dev/null +++ b/games/snake/src/entities/snake/TailEntity.hpp @@ -0,0 +1,21 @@ +/* +** EPITECH PROJECT, 2024 +** TailEntity.hpp +** File description: +** TailEntity class +*/ + +#pragma once + +#include "common/entity/AEntity.hpp" + +namespace arcade::games::snake { + class TailEntity; +} + +class arcade::games::snake::TailEntity : public common::AEntity { +public: + ~TailEntity() override = default; + + explicit TailEntity(); +}; From 2e4ce94e7e603c7c23606721fba766c0022c2784 Mon Sep 17 00:00:00 2001 From: Matheo Coquet Date: Thu, 28 Mar 2024 16:04:40 +0100 Subject: [PATCH 09/33] feat(snake): update assets with ascii and head --- assets/snake/head.ascii | 1 + assets/snake/head.png | Bin 0 -> 1868 bytes assets/snake/snake.png | Bin 3605 -> 0 bytes assets/snake/tail.ascii | 3 +++ assets/snake/tail.png | Bin 0 -> 2048 bytes 5 files changed, 4 insertions(+) create mode 100644 assets/snake/head.ascii create mode 100644 assets/snake/head.png delete mode 100644 assets/snake/snake.png create mode 100644 assets/snake/tail.ascii create mode 100644 assets/snake/tail.png diff --git a/assets/snake/head.ascii b/assets/snake/head.ascii new file mode 100644 index 0000000..71c4a23 --- /dev/null +++ b/assets/snake/head.ascii @@ -0,0 +1 @@ +@@@@ \ No newline at end of file diff --git a/assets/snake/head.png b/assets/snake/head.png new file mode 100644 index 0000000000000000000000000000000000000000..f369b2a2f9686b3eea791b5e79ea3bdd2c0cddf9 GIT binary patch literal 1868 zcmV-S2ebHzP)001Zm1^@s6c`Wgm00009a7bBm000XU z000XU0RWnu7ytkO0drDELIAGL9O(c600d`2O+f$vv5yP?l4Q9ywd2O7XZauEX+HWCFXkSG$1 zDx|{|I0!)+LQLb5Sc-(BD4d;u&pz9?%zwRm*^k-X+1c5z%l#zl_V#Ay&CR`?d2i;u zwMLS>`C~Xm6{7o=}t$vjw$2y zX0tTC_-XkT#iZR8aB`+TtWoI(JFJEjUDv5Owm4T=qa4c#q9j`Ityz75Dc=H9q(7o6 zAHX%Z7ImO5>cGWRid70%3Q$E^Ttg8_OHLTwB88wZySt5LHr*1A z)i$Vu19L>GSnn&nM5j+R>Gkn_6VRGZH$1Ek?ExX=qTVh4*(`N&#?;bNI|g)x0)WazqHUX%bRCJ1ads8pU~JU9)M0_+ERE~t?8x7thE~Novv6peb&m|1zSi~{NRXS{L+{#xJf*eoo_zjyyX4;SivLKW9 zSqy_&iZ}+jN}KuEQKy-RDcB8ejJWXX7&+1Fc#kPq0bIwEtAH?=DP{a*Vujv1#>jN> z-96tr@L8poq={O;y=|%;w*BT)H1*m5z46Lng+~dw z-vHhkrHr3Ub9=}D(_$DRW#U|GFJo^TY(7%BT7c>Pmp_>jyn2}H0blsKTZzemI#8Dz z$b@XPL6vD^GHUjf0apRdrGiumklE@Tx3|Vaq)eP^U1f~6nGT!s)q;C9%~)!&Pm?&t zIeb<$ITq+E^cjx*tlH3ZssxB6bMBjaw0isC*5oZw#3f4oNjhv8eX!ILcey1max5&z zGaYI1Xc=YJ9lG@Ezb)keShK=8dl?xd>fcM-VQUvG$20c|h>#%b*fN;0Lhoj6z2PV$ zL)7}wwk#aBb^(2tdj&*1nssa$%-9}sGh8jlHq4{ekG5suu(b>5JFel9w|G0&p1;Yq z7KnY)zVc>ks|xE>SSnDr5G_>yI&1H7);27xW??h81Dl0dTF2h2eJifMqp`mMwmo#P zoK$;AN)f0ZTXAFNaYy;&IpUdXREOI{!A~~!T(S4c4%aDr)`RweJ4B;3vR_$|cR%g7M5etX;U3UVK)gB0jHXo4r&;ypZj%6B;FwR zfjUG2eTKf{{=gWaR7aO6t{(4EWzTwOPD9KxVFE?uoTWcQUfND-a~5g04`-e{A| z(;k5lZQ@tQ)P?Qkv;sk4FkimdH!f0ERdP~0eLtZexyZO|M zX}{q4dBA7n76frLXC>ab-gCyXNG z1q%_^@E0+d(;%WlD4iaVmYgu!VhZMw<-d_o#pCdA8vX}!peU>fcGffi0000xTC2|*A6r6y7XL`1s8 zP$Qu#J<@v#Jbd?@_wN0EKg`bA-|o!pnVGYDHr3J`!py+O0001(O^m_T7aI9j=x8p+ zbexCWg`y8Iz8?$#FmnDCARsrN_W}Zgtsw@0szLshiwTv7zL`D%P@Bnk>Pmg#slo)T zZ}Swm_SVA35hBnXd&SY4lZAzF@FOkt2mcNWau1lf=uL6<1jT^ePy69>*(M zQ{<<}1R`k@Ui_1Cr#Bc6vmfUgxlwjmfZ{$~I_&)I%; z(44T`zv92&)tWtssSl3wlD3D7+W!eFzO!1{G;)<_H8QmvwsKqynIgp;t^M)kNZ?BJ z%|%tO7kGWv_;@P>$J1nyx>afZ;d9j5xbhVn_FCXqktd9e=ppU8mXiP@`W5%9I?@bO zAJ?Pp=np^V+4m7P}RZ|r}PuaWnXi`& znGIuL$6|3rCr_~T5<9=DF2>B&M+_mQN05~-aGa0BND70aDB)bLr2tn&gqY*v0tKx$ zWVq+g3Y?H=608`srylgdAM zyE`sNSz=#&@HO!KMiO^|+=sC}UnnY7Frmh$jhi(;?-b}46+!a{KJ~Oz4A*Kiki$AHtuHq{i zUL^o^`&_MXH$#?vaFz>IC}J8tVhjvItAy`#Ch>E?vsX)BP=rhkWfx4!)?B$Qccb-Y z2cV2|*u1IhdAw7-iqTF-o5vmrM6Yxs^eq$q90$nO2)0_o02Z<^cNBUZ9rDGFC@D~ag$G0xtK^}ub&f=418 zTJwd1SKi8pnm=e!X)zI8Qcjz63K+FS85uU1OWSibJjO_3wW_{p+pyUk!NtZ^27X(j zM(y}QmdEOEp|s0iY(t71N`4-0{DgsVy5mI~^+J1RXQX4U);;s|Fu`5_oY4a1+Q(y# zxCEa*=R(#Wd1dUElh?X*Y^j+Rn|pn;>;m=Fj=#0+p3ypx+uOt3UOTIwj9^ulLH?&L z6SpUFs-Mu<>jWH4Kz0iqG%t3X?pjS8mpt`&H42ol!nixEep@%hb*fIs>QP!(?ZmA|(QCe)kUfL;Un_7JnZtzsrC66F;QsmW` z1>qIhLu!Giv)GyCcsUpTrx8LW{K~sq-ssyrG3YlrG-o#=vu@o{AwT@-!%7egZ38d0 z1t+u}bRb%1JWp7WwpD3T89Taa*Ru}DPTq)1hN8PV#!b$Gt8spT{NYvQLH^sh7p8^G z@#|-W=eDAU`-m>~%|zYX4od1-G()#wS}$(&x%8v)O!=3G5`-7X6DFBsx96Km`&!Gr zBiuide6m;@-c8$>*5!42W0KER~JKoYqP#$LDGl`AvmJle0>iF<2B!Wt+Y zJ2~IMm_-G5|GH*pP$YpZ4bMA#Seyp z!Owm9+I$@*<8e-G4vg6cQ|^6!dy2^FxWvg>s1?f{&_jI4bsb~I;0O(|*k3EFY8Kre zZzW?xb(DG$wDur>gcV`)dT*pzosUVBRz-hU=d(|cm>roXD;e!ElTWBktwZ$=)e7f) z>3GFOE#@<>5%S}UM|vsc5Dg~W^%%45(n47W4x!A|I)PfDK{mUyQmVtn?$#N?$Gp>8>h@aItb?MQmWQcDdQ`1BWLJOAecw#vlJ7sSx|$dd#+}sTJ6zg=wk$PqpX;wn zB%&4WLE-WE6P2&ipuJ{~C1c$cU$+wTuQM<0roFAc5YD~C++uP|*BJ#rE46-z1x4f? zKC|KJ$PoTz_){vEZJ+u#id4qae}5~6DV_A4{_Hn&Q=D@lp3}-d{2wtjcC2uMoSGFv zG;2)Kfb`*Nh8TGh${_AttVQDka{%q=Vyd=#Vf>@+T}_8>w^-;PECjWk%Mdo&QG&`T zNvFcw=jc}(Tb;OC^$B$wV21NCNs~lBxLFx!A6)yu85p#%ScGgd-~OUNLUD=Y#30h@(wA zPcymx`=rYun!|cN-E-niBhv1%a}w|9v$-$(kgIF zQkGj$Y>pH+y%o0*kuzqG`wau!=!Y}yX@8+k9a*ZV^bm0B0`}F#oV_KZED6*p>>{s9 z`dSNutuG&3*>aW7M>0t=j;d_o z)7{o0rkl5GQrTb`&EII%s2elX6)RHA#pWg74;rOlMqDUa!`6UE0#!(Fh10tW#P>ECjvLz88IejnFs*E-hd!i5zW z91}LdwMx>{x&e8gQkx{@sR*2frWP&&&6Q?xIMxoHOzC&SE}B~?KcEKBgMoyUfZ8;< zvJEHko2y*Hd53Nwy@X&}AN^~;!AO;!#T=dvH^$4L=`G9`3urmG(w z+hM?hF2&THrMVBvxfg9X-%KnDv8gOo#X^d_yZzzuq(j37r$6>%v*yvIzFqDt%;ecQ36y*4SK(=DMd{KMD`ovKStPnI1hD{9I~Wtnt8 wMA<}|xjEoSzaeD_QN4a_mB^Qraz7nfM5)mOqcJ4y#V-zEVq^}kGH{9iAHE&j%m4rY diff --git a/assets/snake/tail.ascii b/assets/snake/tail.ascii new file mode 100644 index 0000000..2afd973 --- /dev/null +++ b/assets/snake/tail.ascii @@ -0,0 +1,3 @@ +║═ +~~~~ +╝╚╗╔ \ No newline at end of file diff --git a/assets/snake/tail.png b/assets/snake/tail.png new file mode 100644 index 0000000000000000000000000000000000000000..3910682b21de1c1ac0109855f3fd4ef9eb44b3c0 GIT binary patch literal 2048 zcmb_d`BxH%76uY9tb|ZQ(^0^+DYYrhEg}UK%>`TaZ220RsR4 zTS<-t%0|uGhzLc78mzSbflZ^Rfdb6l8)>uh&6fi zEz}s+82ycmK6w+Rh)!_l5maHRCAPrrUa{LPX`93~tkGU&8eR+oJ9_2=uIy6LAzudR z-uj<8!~Y{m(AK*8x_BX0?LQL!IZdjJdC5MqaOoekKL@(DHgzHD*s(S;x&1ZwxMrsB zjJI)}ae};!YkWp3U938E@!~l>f#>8b#ZF`t_{^#Exqk4`}t?PJCHN zXlPew%IbJ*$IMLjV-7J>4ECx0(n9pun`D~1vD=D;Q zE^?2;UZu&LDt9obzfab*$6oq6G$Aij(OKb+J8<<@%~Pi5))tCds_cu%yvZs-1p69v zL712)%lOr(#U3bry!(>kjiZX7YE8-Ox7~d(xCa<*{i0nd(g`96u%z6S6y8?VnULt3 zYDBK+90;5h*4Il^b@WMk8$i8&*oJ)0p5eT)meCkck_|oWs;ZQ9FIfaZYjoI2Oh~5~ zZP6Zgupv*+J8ttHI?!h&1`G=uRh644TIBz_!4O~TqZFB3xWQ`ivzu+bDR*vqf=d|8 zoKECm_vO+8nga>u{X~GEL`9iRNF8qC+%eTH*k>j2v zVo<)_pMGbPW2dGr-teEk{4P;jsB;qp0p0()_>ZFqRv z-@~A;0%fYXtz6L$#}0aq@2EIwfuU`t+LRl=c~W2UDAYHZD6gqe!(@xzGn~IOXPu+X zVSm1D6vXq*R!nbFLQVZ?2~!Jxl&E-Y18H2f^=t;zE$(r4nvd&M+g#b~?8Mvn;Go^~ z;t-$xAc9BVC)%$WgiBtsktJ+O5~|Z`DM%QA{8m1K%gp==3asrf%dril)VB1NZu-ip zYffKvT0m9!?z|cy6cV{7=SP3;3ACoFoNirCX?%|~YUsxt_p`UfKu-~<VbQ+v-p)Vt3_8j4~2Lx zTBBpt{OgO4&B~p#N^_-m z2eI9$Trv_3+4-;yx*r^oWNG^4iVOC0dqFcXzVU_MCX<>ADF@Af{<9rz3e$FZ7;1yM zo8Ypd-IgP%4vHN|#d=N5+=srZS>EB;aahA?Q`Q7K0m8&8Z=SqeifIyOCegcAuzL!O z$m2M)L$L)Xj~QrBKip&0vk7A-}El@-`@z+IQc2$cUIVgY|#Sf^NlY-=l#jim;k z)1N34z(;Ml=nJ61NlBbgzNWK0PI3#<2td?xl}zu;oXiOVhv*gl@(7mPS`6rGJz5FG z49)cHsFvP(Vz8vw_2&RW#OF;_LGrRxqDzifSrolgT+o1Sze z_c6^o%@v+_4F;aL0vzz>QR6boO}Z6w1I}(HLDL&%W?3BHG@%tRB#foC%Fnm^eMtYl ztIZ4L2Kr718yOngbKr!p4Oe52v-(IEWZAPSbNLhN;vIumV&j%UGB-IwWpuI7@O6Kt zVcZFMUpm`oJ&wGf#ZcBK^kg>#; Date: Thu, 28 Mar 2024 16:05:01 +0100 Subject: [PATCH 10/33] feat(snake): add snake head --- core/main.cpp | 3 ++ games/snake/CMakeLists.txt | 2 ++ games/snake/src/SnakeGame.cpp | 5 +++ games/snake/src/entities/snake/HeadEntity.cpp | 31 ++++++++++++++++++ games/snake/src/entities/snake/HeadEntity.hpp | 32 +++++++++++++++++++ games/snake/src/entities/snake/Snake.cpp | 3 ++ games/snake/src/entities/snake/TailEntity.cpp | 28 ++++++++-------- games/snake/src/entities/snake/TailEntity.hpp | 11 +++++++ 8 files changed, 100 insertions(+), 15 deletions(-) create mode 100644 games/snake/src/entities/snake/HeadEntity.cpp create mode 100644 games/snake/src/entities/snake/HeadEntity.hpp diff --git a/core/main.cpp b/core/main.cpp index ee66021..8f288e2 100644 --- a/core/main.cpp +++ b/core/main.cpp @@ -27,5 +27,8 @@ int main(void) { auto game = lib->createInstance(); std::cout << "\n[ Compute 1 ]\n" << std::endl; game->compute(1); + + std::cout << "\n[ Compute 2 ]\n" << std::endl; + game->compute(2); return 0; } diff --git a/games/snake/CMakeLists.txt b/games/snake/CMakeLists.txt index 6a7c659..6c508af 100644 --- a/games/snake/CMakeLists.txt +++ b/games/snake/CMakeLists.txt @@ -7,6 +7,8 @@ add_library(${PROJECT_NAME} SHARED src/entities/snake/Snake.hpp src/entities/snake/TailEntity.cpp src/entities/snake/TailEntity.hpp + src/entities/snake/HeadEntity.cpp + src/entities/snake/HeadEntity.hpp ) add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/../common PRIVATE) target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_LIST_DIR}/src) diff --git a/games/snake/src/SnakeGame.cpp b/games/snake/src/SnakeGame.cpp index ac4e800..196d2d6 100644 --- a/games/snake/src/SnakeGame.cpp +++ b/games/snake/src/SnakeGame.cpp @@ -7,6 +7,7 @@ #include #include "SnakeGame.hpp" +#include "common/components/TextureComponent.hpp" using namespace arcade::games; @@ -47,4 +48,8 @@ void snake::SnakeGame::compute(shared::games::DeltaTime dt) { std::cout << "SnakeGame::compute" << std::endl; std::cout << "DeltaTime: " << dt << std::endl; std::cout << "Number of entity: " << this->_entities.size() << std::endl; + + auto txcmp = std::dynamic_pointer_cast(this->_entities[1]->getComponents().at(1)); + std::cout << "Origin texture first tail: " << txcmp->getTextureProps().origin.x << std::endl; + txcmp->getTextureProps().origin.x += 2; } diff --git a/games/snake/src/entities/snake/HeadEntity.cpp b/games/snake/src/entities/snake/HeadEntity.cpp new file mode 100644 index 0000000..8c00afa --- /dev/null +++ b/games/snake/src/entities/snake/HeadEntity.cpp @@ -0,0 +1,31 @@ +/* +** EPITECH PROJECT, 2024 +** HeadEntity.cpp +** File description: +** HeadEntity class +*/ + +#include "HeadEntity.hpp" + +using namespace arcade::games::common::components; +using namespace shared::games::components; + +arcade::games::snake::HeadEntity::HeadEntity() : _textureProps( + arcade::games::snake::HeadEntity::_defaultTextureProps()) { + std::shared_ptr collide = std::make_shared(*this); + std::shared_ptr texture = std::make_shared(*this, Vector2u(1, 1), 10, + this->_textureProps); + this->_components.push_back(collide); + this->_components.push_back(texture); +} + +shared::games::components::TextureProps arcade::games::snake::HeadEntity::_defaultTextureProps() { + return { + .sources = { + .ascii = "assets/snake/head.ascii", + .bin = "assets/snake/head.png", + .binTileSize = Vector2f(40, 40) + }, + .origin = Vector2u(0, 0) + }; +} diff --git a/games/snake/src/entities/snake/HeadEntity.hpp b/games/snake/src/entities/snake/HeadEntity.hpp new file mode 100644 index 0000000..952ee28 --- /dev/null +++ b/games/snake/src/entities/snake/HeadEntity.hpp @@ -0,0 +1,32 @@ +/* +** EPITECH PROJECT, 2024 +** HeadEntity.hpp +** File description: +** HeadEntity class +*/ + +#pragma once + +#include "common/entity/AEntity.hpp" +#include "common/components/CollidableComponent.hpp" +#include "common/components/TextureComponent.hpp" + +namespace arcade::games::snake { + class HeadEntity; +} + +class arcade::games::snake::HeadEntity : public common::AEntity { +public: + ~HeadEntity() override = default; + + explicit HeadEntity(); + +protected: + /** + * @brief Get default texture props + * @return Texture props + */ + static shared::games::components::TextureProps _defaultTextureProps(); + + shared::games::components::TextureProps _textureProps; +}; diff --git a/games/snake/src/entities/snake/Snake.cpp b/games/snake/src/entities/snake/Snake.cpp index a2df832..0f1fe82 100644 --- a/games/snake/src/entities/snake/Snake.cpp +++ b/games/snake/src/entities/snake/Snake.cpp @@ -7,11 +7,14 @@ #include "Snake.hpp" #include "TailEntity.hpp" +#include "HeadEntity.hpp" using namespace shared::games::entity; using namespace arcade::games::snake; Snake::Snake(unsigned int tails) { + this->head = std::make_shared(); + for (size_t i = 0; i < tails; i++) { this->addTail(); } diff --git a/games/snake/src/entities/snake/TailEntity.cpp b/games/snake/src/entities/snake/TailEntity.cpp index d489e57..8b81aee 100644 --- a/games/snake/src/entities/snake/TailEntity.cpp +++ b/games/snake/src/entities/snake/TailEntity.cpp @@ -5,29 +5,27 @@ ** TailEntity class */ -#include #include "TailEntity.hpp" -#include "common/components/CollidableComponent.hpp" -#include "common/components/TextureComponent.hpp" -#include "shared/games/components/ITextureComponent.hpp" using namespace arcade::games::common::components; using namespace shared::games::components; -arcade::games::snake::TailEntity::TailEntity() { - TextureProps tailTextureProps = { +arcade::games::snake::TailEntity::TailEntity() : _textureProps( + arcade::games::snake::TailEntity::_defaultTextureProps()) { + std::shared_ptr collide = std::make_shared(*this); + std::shared_ptr texture = std::make_shared(*this, Vector2u(1, 1), 10, + this->_textureProps); + this->_components.push_back(collide); + this->_components.push_back(texture); +} + +shared::games::components::TextureProps arcade::games::snake::TailEntity::_defaultTextureProps() { + return { .sources = { - .ascii = "assets/snake/snake.ascii", - .bin = "assets/snake/snake.png", + .ascii = "assets/snake/tail.ascii", + .bin = "assets/snake/tail.png", .binTileSize = Vector2f(40, 40) }, .origin = Vector2u(0, 0) }; - - std::shared_ptr collide = std::make_shared(*this); - std::shared_ptr texture = std::make_shared(*this, Vector2u(1, 1), 10, - tailTextureProps); - - this->_components.push_back(collide); - this->_components.push_back(texture); } diff --git a/games/snake/src/entities/snake/TailEntity.hpp b/games/snake/src/entities/snake/TailEntity.hpp index 93daa48..1123b3d 100644 --- a/games/snake/src/entities/snake/TailEntity.hpp +++ b/games/snake/src/entities/snake/TailEntity.hpp @@ -8,6 +8,8 @@ #pragma once #include "common/entity/AEntity.hpp" +#include "common/components/CollidableComponent.hpp" +#include "common/components/TextureComponent.hpp" namespace arcade::games::snake { class TailEntity; @@ -18,4 +20,13 @@ class arcade::games::snake::TailEntity : public common::AEntity { ~TailEntity() override = default; explicit TailEntity(); + +protected: + /** + * @brief Get default texture props + * @return Texture props + */ + static shared::games::components::TextureProps _defaultTextureProps(); + + shared::games::components::TextureProps _textureProps; }; From 70cd1ec693e3775250ad72e837e388c2100550cc Mon Sep 17 00:00:00 2001 From: Matheo Coquet Date: Fri, 29 Mar 2024 14:47:54 +0100 Subject: [PATCH 11/33] feat(snake): add snake direction and forward --- core/main.cpp | 11 +++++---- games/snake/src/SnakeGame.cpp | 17 +++++++++----- games/snake/src/SnakeGame.hpp | 1 + games/snake/src/entities/snake/HeadEntity.cpp | 13 ++++++++++- games/snake/src/entities/snake/HeadEntity.hpp | 10 ++++++++ games/snake/src/entities/snake/Snake.cpp | 7 +++--- games/snake/src/entities/snake/Snake.hpp | 13 +++++++---- shared/games/IGame.hpp | 5 ++-- shared/graphics/events/IKeyEvent.hpp | 2 +- shared/graphics/events/IMouseButtonEvent.hpp | 2 +- shared/graphics/events/IMouseEvent.hpp | 2 +- shared/graphics/exceptions/IFontException.hpp | 19 +++++++++++++++ .../exceptions/IGraphicsException.hpp | 23 +++++++++++++++++++ .../graphics/exceptions/ISoundException.hpp | 19 +++++++++++++++ .../graphics/exceptions/ITextureException.hpp | 19 +++++++++++++++ .../graphics/exceptions/IWindowException.hpp | 19 +++++++++++++++ 16 files changed, 159 insertions(+), 23 deletions(-) create mode 100644 shared/graphics/exceptions/IFontException.hpp create mode 100644 shared/graphics/exceptions/IGraphicsException.hpp create mode 100644 shared/graphics/exceptions/ISoundException.hpp create mode 100644 shared/graphics/exceptions/ITextureException.hpp create mode 100644 shared/graphics/exceptions/IWindowException.hpp diff --git a/core/main.cpp b/core/main.cpp index 8f288e2..9852d23 100644 --- a/core/main.cpp +++ b/core/main.cpp @@ -25,10 +25,13 @@ int main(void) { std::cout << "Game authors: " << manifest.authors[0].name << std::endl; auto game = lib->createInstance(); - std::cout << "\n[ Compute 1 ]\n" << std::endl; - game->compute(1); - std::cout << "\n[ Compute 2 ]\n" << std::endl; - game->compute(2); + auto last = std::chrono::high_resolution_clock::now(); + while (true) { + auto current_time = std::chrono::high_resolution_clock::now(); + auto elapsed_time = duration_cast>(current_time - last); + game->compute(elapsed_time); + last = current_time; + } return 0; } diff --git a/games/snake/src/SnakeGame.cpp b/games/snake/src/SnakeGame.cpp index 196d2d6..f5d349f 100644 --- a/games/snake/src/SnakeGame.cpp +++ b/games/snake/src/SnakeGame.cpp @@ -36,6 +36,7 @@ snake::SnakeGame::SnakeGame() : common::AGame(Vector2u(19, 19), 60) { for (auto &tail: this->_snake->getTails()) { this->_registerEntity(tail); } + this->_clock = std::chrono::milliseconds(0); } snake::SnakeGame::~SnakeGame() = default; @@ -45,11 +46,15 @@ const shared::games::GameManifest &snake::SnakeGame::getManifest() const noexcep } void snake::SnakeGame::compute(shared::games::DeltaTime dt) { - std::cout << "SnakeGame::compute" << std::endl; - std::cout << "DeltaTime: " << dt << std::endl; - std::cout << "Number of entity: " << this->_entities.size() << std::endl; + this->_clock += dt; - auto txcmp = std::dynamic_pointer_cast(this->_entities[1]->getComponents().at(1)); - std::cout << "Origin texture first tail: " << txcmp->getTextureProps().origin.x << std::endl; - txcmp->getTextureProps().origin.x += 2; + if (this->_clock > std::chrono::milliseconds(300) + this->_snake->lastMove) { + this->_snake->lastMove = this->_clock; + this->_snake->head->forward(); + + // DEBUG // + auto position = std::dynamic_pointer_cast(this->_snake->head->getComponents().at(1)); + std::cout << "Snake Position [" << position->getPosition().x << ", " << position->getPosition().y << "]" << std::endl; + // END DEBUG // + } } diff --git a/games/snake/src/SnakeGame.hpp b/games/snake/src/SnakeGame.hpp index 1193983..356f86f 100644 --- a/games/snake/src/SnakeGame.hpp +++ b/games/snake/src/SnakeGame.hpp @@ -42,4 +42,5 @@ class arcade::games::snake::SnakeGame : public arcade::games::common::AGame { protected: std::unique_ptr _snake; + shared::games::DeltaTime _clock; }; diff --git a/games/snake/src/entities/snake/HeadEntity.cpp b/games/snake/src/entities/snake/HeadEntity.cpp index 8c00afa..c316ede 100644 --- a/games/snake/src/entities/snake/HeadEntity.cpp +++ b/games/snake/src/entities/snake/HeadEntity.cpp @@ -11,7 +11,8 @@ using namespace arcade::games::common::components; using namespace shared::games::components; arcade::games::snake::HeadEntity::HeadEntity() : _textureProps( - arcade::games::snake::HeadEntity::_defaultTextureProps()) { + arcade::games::snake::HeadEntity::_defaultTextureProps()), + _direction(1, 0) { std::shared_ptr collide = std::make_shared(*this); std::shared_ptr texture = std::make_shared(*this, Vector2u(1, 1), 10, this->_textureProps); @@ -29,3 +30,13 @@ shared::games::components::TextureProps arcade::games::snake::HeadEntity::_defau .origin = Vector2u(0, 0) }; } + +void arcade::games::snake::HeadEntity::forward() { + for (auto &component: this->_components) { + std::shared_ptr posCmp = std::dynamic_pointer_cast(component); + if (posCmp == nullptr) continue; + + posCmp->getPosition().x += this->_direction.x; + posCmp->getPosition().y += this->_direction.y; + } +} diff --git a/games/snake/src/entities/snake/HeadEntity.hpp b/games/snake/src/entities/snake/HeadEntity.hpp index 952ee28..30837d4 100644 --- a/games/snake/src/entities/snake/HeadEntity.hpp +++ b/games/snake/src/entities/snake/HeadEntity.hpp @@ -19,8 +19,16 @@ class arcade::games::snake::HeadEntity : public common::AEntity { public: ~HeadEntity() override = default; + /** + * @brief Create the head of a snake + */ explicit HeadEntity(); + /** + * @brief Update the position of the head of the snake + */ + void forward(); + protected: /** * @brief Get default texture props @@ -29,4 +37,6 @@ class arcade::games::snake::HeadEntity : public common::AEntity { static shared::games::components::TextureProps _defaultTextureProps(); shared::games::components::TextureProps _textureProps; + + Vector2i _direction; }; diff --git a/games/snake/src/entities/snake/Snake.cpp b/games/snake/src/entities/snake/Snake.cpp index 0f1fe82..dd9b905 100644 --- a/games/snake/src/entities/snake/Snake.cpp +++ b/games/snake/src/entities/snake/Snake.cpp @@ -13,6 +13,7 @@ using namespace shared::games::entity; using namespace arcade::games::snake; Snake::Snake(unsigned int tails) { + this->lastMove = std::chrono::milliseconds(0); this->head = std::make_shared(); for (size_t i = 0; i < tails; i++) { @@ -22,12 +23,12 @@ Snake::Snake(unsigned int tails) { Snake::~Snake() = default; -std::vector &Snake::getTails() { +std::vector> &Snake::getTails() { return this->_tails; } -EntityPtr Snake::addTail() { - EntityPtr newTail = std::make_shared(); +std::shared_ptr Snake::addTail() { + std::shared_ptr newTail = std::make_shared(); this->_tails.push_back(newTail); return newTail; diff --git a/games/snake/src/entities/snake/Snake.hpp b/games/snake/src/entities/snake/Snake.hpp index 72183b4..2fac39d 100644 --- a/games/snake/src/entities/snake/Snake.hpp +++ b/games/snake/src/entities/snake/Snake.hpp @@ -12,6 +12,9 @@ #include #include "common/game/AGame.hpp" +#include "shared/games/IEntity.hpp" +#include "HeadEntity.hpp" +#include "TailEntity.hpp" namespace arcade::games::snake { class Snake; @@ -26,25 +29,27 @@ class arcade::games::snake::Snake { * @brief Head of the snake * */ - shared::games::entity::EntityPtr head; + std::shared_ptr head; /** * @brief Add a tail to the snake body * * @return The entity to the new tail */ - shared::games::entity::EntityPtr addTail(); + std::shared_ptr addTail(); /** * Get tails of the snake * * @return Vector of tails */ - std::vector &getTails(); + std::vector> &getTails(); + + shared::games::DeltaTime lastMove; protected: /** * @brief Entities that compose the snake * */ - std::vector _tails; + std::vector> _tails; }; diff --git a/shared/games/IGame.hpp b/shared/games/IGame.hpp index 89df01c..bd684c8 100644 --- a/shared/games/IGame.hpp +++ b/shared/games/IGame.hpp @@ -8,6 +8,7 @@ #pragma once #include +#include #include "IEntity.hpp" #include "../types/Vector.hpp" #include "types/GameManifest.hpp" @@ -18,7 +19,7 @@ namespace shared::games { class IGame; - typedef unsigned long DeltaTime; + typedef std::chrono::duration DeltaTime; } class shared::games::IGame @@ -56,7 +57,7 @@ class shared::games::IGame virtual const unsigned int getFps() const noexcept = 0; /** - * @brief Get map of entity + * @brief Get map of entities * * @return Entities map of the game */ diff --git a/shared/graphics/events/IKeyEvent.hpp b/shared/graphics/events/IKeyEvent.hpp index db6cab4..81fe453 100644 --- a/shared/graphics/events/IKeyEvent.hpp +++ b/shared/graphics/events/IKeyEvent.hpp @@ -13,7 +13,7 @@ namespace shared::graphics::events { class IKeyEvent; } -class shared::graphics::events::IKeyEvent : public IEvent { +class shared::graphics::events::IKeyEvent : public virtual IEvent { public: virtual ~IKeyEvent() = default; diff --git a/shared/graphics/events/IMouseButtonEvent.hpp b/shared/graphics/events/IMouseButtonEvent.hpp index b70ab17..bac5eba 100644 --- a/shared/graphics/events/IMouseButtonEvent.hpp +++ b/shared/graphics/events/IMouseButtonEvent.hpp @@ -13,7 +13,7 @@ namespace shared::graphics::events{ class IMouseButtonEvent; } -class shared::graphics::events::IMouseButtonEvent : public IMouseEvent { +class shared::graphics::events::IMouseButtonEvent : public virtual IMouseEvent { public: virtual ~IMouseButtonEvent() = default; diff --git a/shared/graphics/events/IMouseEvent.hpp b/shared/graphics/events/IMouseEvent.hpp index a85ae4b..618e5fe 100644 --- a/shared/graphics/events/IMouseEvent.hpp +++ b/shared/graphics/events/IMouseEvent.hpp @@ -14,7 +14,7 @@ namespace shared::graphics::events { class IMouseEvent; } -class shared::graphics::events::IMouseEvent : public IEvent { +class shared::graphics::events::IMouseEvent : public virtual IEvent { public: virtual ~IMouseEvent() = default; diff --git a/shared/graphics/exceptions/IFontException.hpp b/shared/graphics/exceptions/IFontException.hpp new file mode 100644 index 0000000..7b875e6 --- /dev/null +++ b/shared/graphics/exceptions/IFontException.hpp @@ -0,0 +1,19 @@ +/* +** EPITECH PROJECT, 2024 +** arcade-shared +** File description: +** IFontException.hpp +*/ + +#pragma once + +#include "IGraphicsException.hpp" + +namespace shared::graphics::exceptions { + class IFontException; +} + +class shared::graphics::exceptions::IFontException : public virtual IGraphicsException { +public: + virtual ~IFontException() = default; +}; diff --git a/shared/graphics/exceptions/IGraphicsException.hpp b/shared/graphics/exceptions/IGraphicsException.hpp new file mode 100644 index 0000000..a899775 --- /dev/null +++ b/shared/graphics/exceptions/IGraphicsException.hpp @@ -0,0 +1,23 @@ +/* +** EPITECH PROJECT, 2024 +** arcade-shared +** File description: +** IGraphicsException.hpp +*/ + +#pragma once + +#include + +namespace shared::graphics::exceptions { + class IGraphicsException; +} + +class shared::graphics::exceptions::IGraphicsException: public std::exception { +public: + /** + * @brief Get error location + * @return String containing error location + */ + virtual const char *where() const noexcept = 0; +}; diff --git a/shared/graphics/exceptions/ISoundException.hpp b/shared/graphics/exceptions/ISoundException.hpp new file mode 100644 index 0000000..2a2e534 --- /dev/null +++ b/shared/graphics/exceptions/ISoundException.hpp @@ -0,0 +1,19 @@ +/* +** EPITECH PROJECT, 2024 +** arcade-shared +** File description: +** ISoundException.hpp +*/ + +#pragma once + +#include "IGraphicsException.hpp" + +namespace shared::graphics::exceptions { + class ISoundException; +} + +class shared::graphics::exceptions::ISoundException : public virtual IGraphicsException { +public: + virtual ~ISoundException() = default; +}; diff --git a/shared/graphics/exceptions/ITextureException.hpp b/shared/graphics/exceptions/ITextureException.hpp new file mode 100644 index 0000000..e894b71 --- /dev/null +++ b/shared/graphics/exceptions/ITextureException.hpp @@ -0,0 +1,19 @@ +/* +** EPITECH PROJECT, 2024 +** arcade-shared +** File description: +** ITextureException.hpp +*/ + +#pragma once + +#include "IGraphicsException.hpp" + +namespace shared::graphics::exceptions { + class ITextureException; +} + +class shared::graphics::exceptions::ITextureException : public virtual IGraphicsException { +public: + virtual ~ITextureException() = default; +}; diff --git a/shared/graphics/exceptions/IWindowException.hpp b/shared/graphics/exceptions/IWindowException.hpp new file mode 100644 index 0000000..ae030f3 --- /dev/null +++ b/shared/graphics/exceptions/IWindowException.hpp @@ -0,0 +1,19 @@ +/* +** EPITECH PROJECT, 2024 +** arcade-shared +** File description: +** IWindowException.hpp +*/ + +#pragma once + +#include "IGraphicsException.hpp" + +namespace shared::graphics::exceptions { + class IWindowException; +} + +class shared::graphics::exceptions::IWindowException : public virtual IGraphicsException { +public: + virtual ~IWindowException() = default; +}; From 678f9b1d47703c63057d232f3cfb73498fd3b949 Mon Sep 17 00:00:00 2001 From: Matheo Coquet Date: Fri, 29 Mar 2024 15:49:04 +0100 Subject: [PATCH 12/33] fix: remove useless code --- games/snake/export.cpp | 3 +-- games/snake/src/SnakeGame.cpp | 2 -- games/snake/src/SnakeGame.hpp | 2 +- 3 files changed, 2 insertions(+), 5 deletions(-) diff --git a/games/snake/export.cpp b/games/snake/export.cpp index 1cee3d2..3be0c08 100644 --- a/games/snake/export.cpp +++ b/games/snake/export.cpp @@ -5,8 +5,7 @@ ** export */ -#include "src/SnakeGameProvider.hpp" -#include "shared/games/IGameProvider.hpp" +#include "SnakeGameProvider.hpp" #include "shared/types/Libraries.hpp" using namespace shared::games; diff --git a/games/snake/src/SnakeGame.cpp b/games/snake/src/SnakeGame.cpp index f5d349f..f8f5b39 100644 --- a/games/snake/src/SnakeGame.cpp +++ b/games/snake/src/SnakeGame.cpp @@ -39,8 +39,6 @@ snake::SnakeGame::SnakeGame() : common::AGame(Vector2u(19, 19), 60) { this->_clock = std::chrono::milliseconds(0); } -snake::SnakeGame::~SnakeGame() = default; - const shared::games::GameManifest &snake::SnakeGame::getManifest() const noexcept { return SnakeGame::manifest; } diff --git a/games/snake/src/SnakeGame.hpp b/games/snake/src/SnakeGame.hpp index 356f86f..e4488ee 100644 --- a/games/snake/src/SnakeGame.hpp +++ b/games/snake/src/SnakeGame.hpp @@ -18,7 +18,7 @@ class arcade::games::snake::SnakeGame : public arcade::games::common::AGame { public: SnakeGame(); - ~SnakeGame() override; + ~SnakeGame() override = default; /** * @brief Game manifest From 6ac17cae4cf0410d190d6d01c040405b321e83cd Mon Sep 17 00:00:00 2001 From: Matheo Coquet Date: Mon, 1 Apr 2024 17:47:55 +0200 Subject: [PATCH 13/33] feat(snake): add keyboard events --- games/common/game/AGame.hpp | 2 +- games/snake/CMakeLists.txt | 2 + games/snake/src/SnakeGame.cpp | 1 + games/snake/src/entities/snake/HeadEntity.cpp | 11 +++-- games/snake/src/entities/snake/HeadEntity.hpp | 7 ++- .../components/HeadKeyboardComponent.cpp | 48 +++++++++++++++++++ .../components/HeadKeyboardComponent.hpp | 45 +++++++++++++++++ 7 files changed, 110 insertions(+), 6 deletions(-) create mode 100644 games/snake/src/entities/snake/components/HeadKeyboardComponent.cpp create mode 100644 games/snake/src/entities/snake/components/HeadKeyboardComponent.hpp diff --git a/games/common/game/AGame.hpp b/games/common/game/AGame.hpp index 1f9fcf3..db2dcd0 100644 --- a/games/common/game/AGame.hpp +++ b/games/common/game/AGame.hpp @@ -15,7 +15,7 @@ namespace arcade::games::common { class AGame; } -class arcade::games::common::AGame : public shared::games::IGame { +class arcade::games::common::AGame : public virtual shared::games::IGame { public: ~AGame() override = default; diff --git a/games/snake/CMakeLists.txt b/games/snake/CMakeLists.txt index 6c508af..6346afe 100644 --- a/games/snake/CMakeLists.txt +++ b/games/snake/CMakeLists.txt @@ -9,6 +9,8 @@ add_library(${PROJECT_NAME} SHARED src/entities/snake/TailEntity.hpp src/entities/snake/HeadEntity.cpp src/entities/snake/HeadEntity.hpp + src/entities/snake/components/HeadKeyboardComponent.cpp + src/entities/snake/components/HeadKeyboardComponent.hpp ) add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/../common PRIVATE) target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_LIST_DIR}/src) diff --git a/games/snake/src/SnakeGame.cpp b/games/snake/src/SnakeGame.cpp index f8f5b39..a26180a 100644 --- a/games/snake/src/SnakeGame.cpp +++ b/games/snake/src/SnakeGame.cpp @@ -8,6 +8,7 @@ #include #include "SnakeGame.hpp" #include "common/components/TextureComponent.hpp" +#include "entities/snake/components/HeadKeyboardComponent.hpp" using namespace arcade::games; diff --git a/games/snake/src/entities/snake/HeadEntity.cpp b/games/snake/src/entities/snake/HeadEntity.cpp index c316ede..247cf70 100644 --- a/games/snake/src/entities/snake/HeadEntity.cpp +++ b/games/snake/src/entities/snake/HeadEntity.cpp @@ -6,18 +6,23 @@ */ #include "HeadEntity.hpp" +#include "components/HeadKeyboardComponent.hpp" using namespace arcade::games::common::components; using namespace shared::games::components; arcade::games::snake::HeadEntity::HeadEntity() : _textureProps( arcade::games::snake::HeadEntity::_defaultTextureProps()), - _direction(1, 0) { + direction(1, 0) { std::shared_ptr collide = std::make_shared(*this); std::shared_ptr texture = std::make_shared(*this, Vector2u(1, 1), 10, this->_textureProps); + std::shared_ptr keyboard = std::make_shared( + *this); + this->_components.push_back(collide); this->_components.push_back(texture); + this->_components.push_back(keyboard); } shared::games::components::TextureProps arcade::games::snake::HeadEntity::_defaultTextureProps() { @@ -36,7 +41,7 @@ void arcade::games::snake::HeadEntity::forward() { std::shared_ptr posCmp = std::dynamic_pointer_cast(component); if (posCmp == nullptr) continue; - posCmp->getPosition().x += this->_direction.x; - posCmp->getPosition().y += this->_direction.y; + posCmp->getPosition().x += this->direction.x; + posCmp->getPosition().y += this->direction.y; } } diff --git a/games/snake/src/entities/snake/HeadEntity.hpp b/games/snake/src/entities/snake/HeadEntity.hpp index 30837d4..4f231f2 100644 --- a/games/snake/src/entities/snake/HeadEntity.hpp +++ b/games/snake/src/entities/snake/HeadEntity.hpp @@ -29,6 +29,11 @@ class arcade::games::snake::HeadEntity : public common::AEntity { */ void forward(); + /** + * @brief Direction of the snake + */ + Vector2i direction; + protected: /** * @brief Get default texture props @@ -37,6 +42,4 @@ class arcade::games::snake::HeadEntity : public common::AEntity { static shared::games::components::TextureProps _defaultTextureProps(); shared::games::components::TextureProps _textureProps; - - Vector2i _direction; }; diff --git a/games/snake/src/entities/snake/components/HeadKeyboardComponent.cpp b/games/snake/src/entities/snake/components/HeadKeyboardComponent.cpp new file mode 100644 index 0000000..28a0760 --- /dev/null +++ b/games/snake/src/entities/snake/components/HeadKeyboardComponent.cpp @@ -0,0 +1,48 @@ +/* +** EPITECH PROJECT, 2024 +** KeyboardComponent.cpp +** File description: +** HeadKeyboardComponent class +*/ + +#include "HeadKeyboardComponent.hpp" + +using namespace arcade::games::snake::components; +using namespace shared::games::components; + +HeadKeyboardComponent::HeadKeyboardComponent(HeadEntity &entity) : AComponent(KEYBOARD, entity), _parent(entity) {} + +void HeadKeyboardComponent::onKeyPress(std::shared_ptr &ctx, + shared::games::components::KeyData keyData) { + if (keyData.type == ARROW) { + if (keyData.code.arrow == UP) { + this->_parent.direction = Vector2i(0, -1); + } + if (keyData.code.arrow == DOWN) { + this->_parent.direction = Vector2i(0, 1); + } + if (keyData.code.arrow == LEFT) { + this->_parent.direction = Vector2i(-1, 0); + } + if (keyData.code.arrow == RIGHT) { + this->_parent.direction = Vector2i(1, 0); + } + } + if (keyData.type == CHAR) { + if (keyData.code.character == 'z') { + this->_parent.direction = Vector2i(0, -1); + } + if (keyData.code.character == 's') { + this->_parent.direction = Vector2i(0, 1); + } + if (keyData.code.character == 'q') { + this->_parent.direction = Vector2i(-1, 0); + } + if (keyData.code.character == 'd') { + this->_parent.direction = Vector2i(1, 0); + } + } +} + +void HeadKeyboardComponent::onKeyRelease(std::shared_ptr &ctx, + shared::games::components::KeyData keyData) {} diff --git a/games/snake/src/entities/snake/components/HeadKeyboardComponent.hpp b/games/snake/src/entities/snake/components/HeadKeyboardComponent.hpp new file mode 100644 index 0000000..bc428b1 --- /dev/null +++ b/games/snake/src/entities/snake/components/HeadKeyboardComponent.hpp @@ -0,0 +1,45 @@ +/* +** EPITECH PROJECT, 2024 +** HeadKeyboardComponent.hpp +** File description: +** HeadKeyboardComponent class +*/ + +#pragma once + +#include "shared/games/components/IKeyboardComponent.hpp" +#include "common/components/AComponent.hpp" +#include "../HeadEntity.hpp" + +namespace arcade::games::snake::components { + class HeadKeyboardComponent; +} + +class arcade::games::snake::components::HeadKeyboardComponent + : public common::components::AComponent, public virtual shared::games::components::IKeyboardComponent { +public: + ~HeadKeyboardComponent() override = default; + + /** + * @brief Create a keyboard component + * @param entity + */ + explicit HeadKeyboardComponent(HeadEntity &entity); + + /** + * @brief On key pressed event handler for the entity + * @param ctx Context of the game + * @param keyData Key data of key pressed + */ + void onKeyPress(std::shared_ptr &ctx, shared::games::components::KeyData keyData) override; + + /** + * @brief On key release event handler for the entity + * @param ctx Context of the game + * @param keyData Key data of key released + */ + void onKeyRelease(std::shared_ptr &ctx, shared::games::components::KeyData keyData) override; + +protected: + HeadEntity &_parent; +}; From 5e75a5ff9a727f5e59af311537d263f4d300d809 Mon Sep 17 00:00:00 2001 From: Matheo Coquet Date: Mon, 1 Apr 2024 19:20:59 +0200 Subject: [PATCH 14/33] feat(snake): add wall and head setup position --- assets/snake/wall.ascii | 1 + assets/snake/wall.png | Bin 0 -> 237 bytes games/snake/CMakeLists.txt | 2 + games/snake/src/SnakeGame.cpp | 6 +- games/snake/src/entities/snake/HeadEntity.cpp | 6 ++ games/snake/src/entities/wall/WallEntity.cpp | 56 ++++++++++++++++++ games/snake/src/entities/wall/WallEntity.hpp | 41 +++++++++++++ 7 files changed, 111 insertions(+), 1 deletion(-) create mode 100644 assets/snake/wall.ascii create mode 100644 assets/snake/wall.png create mode 100644 games/snake/src/entities/wall/WallEntity.cpp create mode 100644 games/snake/src/entities/wall/WallEntity.hpp diff --git a/assets/snake/wall.ascii b/assets/snake/wall.ascii new file mode 100644 index 0000000..4287ca8 --- /dev/null +++ b/assets/snake/wall.ascii @@ -0,0 +1 @@ +# \ No newline at end of file diff --git a/assets/snake/wall.png b/assets/snake/wall.png new file mode 100644 index 0000000000000000000000000000000000000000..e0f8498430e5d7cd28e2666bf5e0cc6495fb329c GIT binary patch literal 237 zcmeAS@N?(olHy`uVBq!ia0vp^6+o=P!3HEvU)iYwDb50q$YKTtZeb8+WSBKa0w~B> z9OUlAu{WG~X$9(_S+d22RS=zTf=V#os@(`9$x9}^N^T6U@Vbf!l #include "SnakeGame.hpp" +#include "entities/wall/WallEntity.hpp" #include "common/components/TextureComponent.hpp" #include "entities/snake/components/HeadKeyboardComponent.hpp" @@ -30,13 +31,16 @@ const shared::games::GameManifest snake::SnakeGame::manifest = { } }; -snake::SnakeGame::SnakeGame() : common::AGame(Vector2u(19, 19), 60) { +snake::SnakeGame::SnakeGame() : common::AGame(Vector2u(20, 20), 60) { this->_snake = std::make_unique(2); this->_registerEntity(this->_snake->head); for (auto &tail: this->_snake->getTails()) { this->_registerEntity(tail); } + + this->_registerEntity(std::make_unique(Vector2u(20, 20))); + this->_clock = std::chrono::milliseconds(0); } diff --git a/games/snake/src/entities/snake/HeadEntity.cpp b/games/snake/src/entities/snake/HeadEntity.cpp index 247cf70..2acba3a 100644 --- a/games/snake/src/entities/snake/HeadEntity.cpp +++ b/games/snake/src/entities/snake/HeadEntity.cpp @@ -20,8 +20,14 @@ arcade::games::snake::HeadEntity::HeadEntity() : _textureProps( std::shared_ptr keyboard = std::make_shared( *this); + collide->getPosition().x = 8; + collide->getPosition().y = 4; this->_components.push_back(collide); + + texture->getPosition().x = 8; + texture->getPosition().y = 4; this->_components.push_back(texture); + this->_components.push_back(keyboard); } diff --git a/games/snake/src/entities/wall/WallEntity.cpp b/games/snake/src/entities/wall/WallEntity.cpp new file mode 100644 index 0000000..71dedf0 --- /dev/null +++ b/games/snake/src/entities/wall/WallEntity.cpp @@ -0,0 +1,56 @@ +/* +** EPITECH PROJECT, 2024 +** WallEntity.cpp +** File description: +** WallEntity class +*/ + +#include "WallEntity.hpp" +#include "common/components/CollidableComponent.hpp" +#include "common/components/TextureComponent.hpp" + +using namespace arcade::games::snake; +using namespace arcade::games::common::components; + +WallEntity::WallEntity(shared::types::Vector2u size) { + if (size.x < 3 || size.y < 3) + throw WallExeption("Invalid size of map"); + + for (std::size_t y = 0; y < size.y; y++) { + this->_createWall(Vector2i(0, y)); + } + for (std::size_t x = 1; x < size.x - 1; x++) { + this->_createWall(Vector2i(x, 0)); + this->_createWall(Vector2i(x, size.y - 1)); + } + for (std::size_t y = 0; y < size.y; y++) { + this->_createWall(Vector2i(size.x - 1, y)); + } +} + +void WallEntity::_createWall(shared::types::Vector2i position) { + shared::games::components::TextureProps textureProps = { + .sources = { + .ascii = "assets/snake/wall.ascii", + .bin = "assets/snake/wall.png", + .binTileSize = Vector2f(40, 40) + }, + .origin = Vector2u(0, 0) + }; + std::shared_ptr collision = std::make_shared(*this); + std::shared_ptr texture = std::make_shared(*this, Vector2u(1, 1), 10, + textureProps); + + collision->getPosition().x = position.x; + collision->getPosition().y = position.y; + this->_components.push_back(collision); + texture->getPosition().x = position.x; + texture->getPosition().y = position.y; + this->_components.push_back(texture); +} + +WallEntity::WallExeption::WallExeption(const std::string &message) : _message(message) {} + +const char *WallEntity::WallExeption::what() const noexcept { + return this->_message.c_str(); +} diff --git a/games/snake/src/entities/wall/WallEntity.hpp b/games/snake/src/entities/wall/WallEntity.hpp new file mode 100644 index 0000000..49744b7 --- /dev/null +++ b/games/snake/src/entities/wall/WallEntity.hpp @@ -0,0 +1,41 @@ +/* +** EPITECH PROJECT, 2024 +** WallEntity.hpp +** File description: +** WallEntity class +*/ + +#pragma once + +#include +#include "common/entity/AEntity.hpp" +#include "shared/types/Vector.hpp" + +namespace arcade::games::snake { + class WallEntity; +} + + +class arcade::games::snake::WallEntity : public common::AEntity { +public: + ~WallEntity() override = default; + + explicit WallEntity(shared::types::Vector2u size); + + class WallExeption : public std::exception { + public: + WallExeption(const std::string &message); + + const char *what() const noexcept override; + + private: + const std::string &_message; + }; + +protected: + /** + * @brief Create a wall (part of) (Component creation) + * @param position Position of the wall + */ + void _createWall(shared::types::Vector2i position); +}; From 5b852bdc4d1481777cdc843eb35485e1c752242d Mon Sep 17 00:00:00 2001 From: Matheo Coquet Date: Mon, 1 Apr 2024 19:35:14 +0200 Subject: [PATCH 15/33] refacto(games): update position component and keydata with new shared version --- games/common/CMakeLists.txt | 4 +- .../components/ADisplayableComponent.cpp | 2 +- .../components/ADisplayableComponent.hpp | 4 +- .../common/components/CollidableComponent.cpp | 2 +- .../common/components/CollidableComponent.hpp | 4 +- games/common/components/PositionComponent.cpp | 19 -------- games/common/components/PositionComponent.hpp | 36 ---------------- .../components/PositionableComponent.cpp | 23 ++++++++++ .../components/PositionableComponent.hpp | 43 +++++++++++++++++++ games/snake/src/SnakeGame.cpp | 2 +- games/snake/src/entities/snake/HeadEntity.cpp | 2 +- .../components/HeadKeyboardComponent.cpp | 4 +- .../components/HeadKeyboardComponent.hpp | 4 +- .../games/components/ICollidableComponent.hpp | 4 +- shared/games/components/IComponent.hpp | 3 +- .../components/IDisplayableComponent.hpp | 10 +---- .../games/components/IKeyboardComponent.hpp | 8 ++-- ...mponent.hpp => IPositionableComponent.hpp} | 14 ++++-- shared/games/components/ITextComponent.hpp | 6 +-- shared/graphics/events/IKeyEvent.hpp | 2 +- shared/graphics/events/IMouseButtonEvent.hpp | 2 +- shared/graphics/events/IMouseEvent.hpp | 2 +- 22 files changed, 106 insertions(+), 94 deletions(-) delete mode 100644 games/common/components/PositionComponent.cpp delete mode 100644 games/common/components/PositionComponent.hpp create mode 100644 games/common/components/PositionableComponent.cpp create mode 100644 games/common/components/PositionableComponent.hpp rename shared/games/components/{IPositionComponent.hpp => IPositionableComponent.hpp} (51%) diff --git a/games/common/CMakeLists.txt b/games/common/CMakeLists.txt index 6a5390f..87ef00d 100644 --- a/games/common/CMakeLists.txt +++ b/games/common/CMakeLists.txt @@ -5,8 +5,8 @@ target_sources(${PROJECT_NAME} PUBLIC entity/AEntity.hpp components/AComponent.cpp components/AComponent.hpp - components/PositionComponent.cpp - components/PositionComponent.hpp + components/PositionableComponent.cpp + components/PositionableComponent.hpp components/ADisplayableComponent.cpp components/ADisplayableComponent.hpp components/CollidableComponent.hpp diff --git a/games/common/components/ADisplayableComponent.cpp b/games/common/components/ADisplayableComponent.cpp index e23697a..b8d9ff2 100644 --- a/games/common/components/ADisplayableComponent.cpp +++ b/games/common/components/ADisplayableComponent.cpp @@ -11,7 +11,7 @@ using namespace arcade::games::common::components; using namespace shared::games; ADisplayableComponent::ADisplayableComponent(entity::IEntity &entity, Vector2u size, unsigned int zindex) - : PositionComponent(entity), + : PositionableComponent(entity), _size(size), _zindex(zindex) { } diff --git a/games/common/components/ADisplayableComponent.hpp b/games/common/components/ADisplayableComponent.hpp index de26bb7..97fbdfc 100644 --- a/games/common/components/ADisplayableComponent.hpp +++ b/games/common/components/ADisplayableComponent.hpp @@ -8,13 +8,13 @@ #pragma once #include "shared/games/components/IDisplayableComponent.hpp" -#include "PositionComponent.hpp" +#include "PositionableComponent.hpp" namespace arcade::games::common::components { class ADisplayableComponent; } -class arcade::games::common::components::ADisplayableComponent : public virtual shared::games::components::IDisplayableComponent, public PositionComponent { +class arcade::games::common::components::ADisplayableComponent : public virtual shared::games::components::IDisplayableComponent, public PositionableComponent { public: ~ADisplayableComponent() override = default; diff --git a/games/common/components/CollidableComponent.cpp b/games/common/components/CollidableComponent.cpp index 2690679..7a14cd7 100644 --- a/games/common/components/CollidableComponent.cpp +++ b/games/common/components/CollidableComponent.cpp @@ -10,7 +10,7 @@ using namespace arcade::games::common::components; -CollidableComponent::CollidableComponent(shared::games::entity::IEntity &entity) : PositionComponent(entity) { +CollidableComponent::CollidableComponent(shared::games::entity::IEntity &entity) : PositionableComponent(entity) { this->_type = shared::games::components::COLLIDABLE; } diff --git a/games/common/components/CollidableComponent.hpp b/games/common/components/CollidableComponent.hpp index cd238ce..d3b0975 100644 --- a/games/common/components/CollidableComponent.hpp +++ b/games/common/components/CollidableComponent.hpp @@ -8,13 +8,13 @@ #pragma once #include "shared/games/components/ICollidableComponent.hpp" -#include "PositionComponent.hpp" +#include "PositionableComponent.hpp" namespace arcade::games::common::components { class CollidableComponent; } -class arcade::games::common::components::CollidableComponent : public virtual shared::games::components::ICollidableComponent, public PositionComponent { +class arcade::games::common::components::CollidableComponent : public virtual shared::games::components::ICollidableComponent, public PositionableComponent { public: ~CollidableComponent() override = default; diff --git a/games/common/components/PositionComponent.cpp b/games/common/components/PositionComponent.cpp deleted file mode 100644 index 5396a19..0000000 --- a/games/common/components/PositionComponent.cpp +++ /dev/null @@ -1,19 +0,0 @@ -/* -** EPITECH PROJECT, 2024 -** PositionComponent.cpp -** File description: -** PositionComponent class -*/ - -#include "PositionComponent.hpp" - -using namespace arcade::games::common::components; -using namespace shared::games::components; - -PositionComponent::PositionComponent(shared::games::entity::IEntity &entity) : AComponent(POSITION, entity), - _position(0, 0) { -} - -shared::types::Vector2i &PositionComponent::getPosition() noexcept { - return this->_position; -} diff --git a/games/common/components/PositionComponent.hpp b/games/common/components/PositionComponent.hpp deleted file mode 100644 index b64d83a..0000000 --- a/games/common/components/PositionComponent.hpp +++ /dev/null @@ -1,36 +0,0 @@ -/* -** EPITECH PROJECT, 2024 -** PositionComponent.hpp -** File description: -** PositionComponent class -*/ - -#pragma once - -#include "shared/games/components/IPositionComponent.hpp" -#include "AComponent.hpp" - -namespace arcade::games::common::components { - class PositionComponent; -} - -class arcade::games::common::components::PositionComponent - : public AComponent, public virtual shared::games::components::IPositionComponent { -public: - ~PositionComponent() override = default; - - /** - * @brief Create a position component - * @param entity - */ - explicit PositionComponent(shared::games::entity::IEntity &entity); - - /** - * @brief Get position of the entity (tiles) - * - */ - shared::types::Vector2i &getPosition() noexcept override; - -protected: - shared::types::Vector2i _position; -}; diff --git a/games/common/components/PositionableComponent.cpp b/games/common/components/PositionableComponent.cpp new file mode 100644 index 0000000..2dd5be7 --- /dev/null +++ b/games/common/components/PositionableComponent.cpp @@ -0,0 +1,23 @@ +/* +** EPITECH PROJECT, 2024 +** PositionableComponent.cpp +** File description: +** PositionableComponent class +*/ + +#include "PositionableComponent.hpp" + +using namespace arcade::games::common::components; +using namespace shared::games::components; + +PositionableComponent::PositionableComponent(shared::games::entity::IEntity &entity) : AComponent(POSITIONABLE, entity), + _position(0, 0), _size(1, 1) { +} + +shared::types::Vector2i &PositionableComponent::getPosition() noexcept { + return this->_position; +} + +shared::types::Vector2u &PositionableComponent::getSize() noexcept { + return this->_size; +} diff --git a/games/common/components/PositionableComponent.hpp b/games/common/components/PositionableComponent.hpp new file mode 100644 index 0000000..557e4f5 --- /dev/null +++ b/games/common/components/PositionableComponent.hpp @@ -0,0 +1,43 @@ +/* +** EPITECH PROJECT, 2024 +** PositionableComponent.hpp +** File description: +** PositionableComponent class +*/ + +#pragma once + +#include "shared/games/components/IPositionableComponent.hpp" +#include "AComponent.hpp" + +namespace arcade::games::common::components { + class PositionableComponent; +} + +class arcade::games::common::components::PositionableComponent + : public AComponent, public virtual shared::games::components::IPositionableComponent { +public: + ~PositionableComponent() override = default; + + /** + * @brief Create a position component + * @param entity + */ + explicit PositionableComponent(shared::games::entity::IEntity &entity); + + /** + * @brief Get position of the entity (tiles) + * + */ + shared::types::Vector2i &getPosition() noexcept override; + + /** + * @brief Get size of the entity (tiles) + * + */ + shared::types::Vector2u &getSize() noexcept override; + +protected: + shared::types::Vector2i _position; + shared::types::Vector2u _size; +}; diff --git a/games/snake/src/SnakeGame.cpp b/games/snake/src/SnakeGame.cpp index 65bf21c..198c077 100644 --- a/games/snake/src/SnakeGame.cpp +++ b/games/snake/src/SnakeGame.cpp @@ -56,7 +56,7 @@ void snake::SnakeGame::compute(shared::games::DeltaTime dt) { this->_snake->head->forward(); // DEBUG // - auto position = std::dynamic_pointer_cast(this->_snake->head->getComponents().at(1)); + auto position = std::dynamic_pointer_cast(this->_snake->head->getComponents().at(1)); std::cout << "Snake Position [" << position->getPosition().x << ", " << position->getPosition().y << "]" << std::endl; // END DEBUG // } diff --git a/games/snake/src/entities/snake/HeadEntity.cpp b/games/snake/src/entities/snake/HeadEntity.cpp index 2acba3a..a09f2a4 100644 --- a/games/snake/src/entities/snake/HeadEntity.cpp +++ b/games/snake/src/entities/snake/HeadEntity.cpp @@ -44,7 +44,7 @@ shared::games::components::TextureProps arcade::games::snake::HeadEntity::_defau void arcade::games::snake::HeadEntity::forward() { for (auto &component: this->_components) { - std::shared_ptr posCmp = std::dynamic_pointer_cast(component); + std::shared_ptr posCmp = std::dynamic_pointer_cast(component); if (posCmp == nullptr) continue; posCmp->getPosition().x += this->direction.x; diff --git a/games/snake/src/entities/snake/components/HeadKeyboardComponent.cpp b/games/snake/src/entities/snake/components/HeadKeyboardComponent.cpp index 28a0760..bf7e17a 100644 --- a/games/snake/src/entities/snake/components/HeadKeyboardComponent.cpp +++ b/games/snake/src/entities/snake/components/HeadKeyboardComponent.cpp @@ -13,7 +13,7 @@ using namespace shared::games::components; HeadKeyboardComponent::HeadKeyboardComponent(HeadEntity &entity) : AComponent(KEYBOARD, entity), _parent(entity) {} void HeadKeyboardComponent::onKeyPress(std::shared_ptr &ctx, - shared::games::components::KeyData keyData) { + shared::games::components::IKeyboardComponent::KeyData keyData) { if (keyData.type == ARROW) { if (keyData.code.arrow == UP) { this->_parent.direction = Vector2i(0, -1); @@ -45,4 +45,4 @@ void HeadKeyboardComponent::onKeyPress(std::shared_ptr &ct } void HeadKeyboardComponent::onKeyRelease(std::shared_ptr &ctx, - shared::games::components::KeyData keyData) {} + shared::games::components::IKeyboardComponent::KeyData keyData) {} diff --git a/games/snake/src/entities/snake/components/HeadKeyboardComponent.hpp b/games/snake/src/entities/snake/components/HeadKeyboardComponent.hpp index bc428b1..742983f 100644 --- a/games/snake/src/entities/snake/components/HeadKeyboardComponent.hpp +++ b/games/snake/src/entities/snake/components/HeadKeyboardComponent.hpp @@ -31,14 +31,14 @@ class arcade::games::snake::components::HeadKeyboardComponent * @param ctx Context of the game * @param keyData Key data of key pressed */ - void onKeyPress(std::shared_ptr &ctx, shared::games::components::KeyData keyData) override; + void onKeyPress(std::shared_ptr &ctx, shared::games::components::IKeyboardComponent::KeyData keyData) override; /** * @brief On key release event handler for the entity * @param ctx Context of the game * @param keyData Key data of key released */ - void onKeyRelease(std::shared_ptr &ctx, shared::games::components::KeyData keyData) override; + void onKeyRelease(std::shared_ptr &ctx, shared::games::components::IKeyboardComponent::KeyData keyData) override; protected: HeadEntity &_parent; diff --git a/shared/games/components/ICollidableComponent.hpp b/shared/games/components/ICollidableComponent.hpp index f6ce1c3..ba65ba0 100644 --- a/shared/games/components/ICollidableComponent.hpp +++ b/shared/games/components/ICollidableComponent.hpp @@ -8,14 +8,14 @@ #pragma once #include "../IGame.hpp" -#include "IPositionComponent.hpp" +#include "IPositionableComponent.hpp" #include "../../types/Vector.hpp" namespace shared::games::components { class ICollidableComponent; } -class shared::games::components::ICollidableComponent: public virtual IPositionComponent +class shared::games::components::ICollidableComponent: public virtual IPositionableComponent { public: virtual ~ICollidableComponent() = default; diff --git a/shared/games/components/IComponent.hpp b/shared/games/components/IComponent.hpp index e03cc51..db6c260 100644 --- a/shared/games/components/IComponent.hpp +++ b/shared/games/components/IComponent.hpp @@ -13,9 +13,10 @@ namespace shared::games::components { typedef enum { TEXTURE, TEXT, + DISPLAYABLE, SOUND, COLLIDABLE, - POSITION, + POSITIONABLE, KEYBOARD } ComponentType; diff --git a/shared/games/components/IDisplayableComponent.hpp b/shared/games/components/IDisplayableComponent.hpp index 0a60cec..8732895 100644 --- a/shared/games/components/IDisplayableComponent.hpp +++ b/shared/games/components/IDisplayableComponent.hpp @@ -7,7 +7,7 @@ #pragma once -#include "IPositionComponent.hpp" +#include "IPositionableComponent.hpp" #include "../IGame.hpp" #include "../../types/Vector.hpp" @@ -15,16 +15,10 @@ namespace shared::games::components { class IDisplayableComponent; } -class shared::games::components::IDisplayableComponent : public virtual IPositionComponent { +class shared::games::components::IDisplayableComponent : public virtual IPositionableComponent { public: virtual ~IDisplayableComponent() = default; - /** - * @brief Get size of the entity (tiles) - * - */ - virtual Vector2u &getSize() noexcept = 0; - /** * @brief Get Z index that is usefull for display prioroty * diff --git a/shared/games/components/IKeyboardComponent.hpp b/shared/games/components/IKeyboardComponent.hpp index 097b293..f2f474a 100644 --- a/shared/games/components/IKeyboardComponent.hpp +++ b/shared/games/components/IKeyboardComponent.hpp @@ -12,7 +12,11 @@ namespace shared::games::components { class IKeyboardComponent; +} +class shared::games::components::IKeyboardComponent: public virtual IComponent +{ +public: typedef enum { CONTROL, // Control key (`Ctrl`, `Shift`, `Alt`) @@ -50,11 +54,7 @@ namespace shared::games::components { KeyCode code; // Key code. Interpretation depends on the type KeyType type; // Type of the key } KeyData; -} -class shared::games::components::IKeyboardComponent: public virtual IComponent -{ -public: virtual ~IKeyboardComponent() = default; /** diff --git a/shared/games/components/IPositionComponent.hpp b/shared/games/components/IPositionableComponent.hpp similarity index 51% rename from shared/games/components/IPositionComponent.hpp rename to shared/games/components/IPositionableComponent.hpp index 4e508df..bc51501 100644 --- a/shared/games/components/IPositionComponent.hpp +++ b/shared/games/components/IPositionableComponent.hpp @@ -2,7 +2,7 @@ ** EPITECH PROJECT, 2024 ** arcade-shared ** File description: -** IPositionComponent +** IPositionableComponent */ #pragma once @@ -11,17 +11,23 @@ #include "../../types/Vector.hpp" namespace shared::games::components { - class IPositionComponent; + class IPositionableComponent; } -class shared::games::components::IPositionComponent: public virtual IComponent +class shared::games::components::IPositionableComponent: public virtual IComponent { public: - virtual ~IPositionComponent() = default; + virtual ~IPositionableComponent() = default; /** * @brief Get position of the entity (tiles) * */ virtual types::Vector2i &getPosition(void) noexcept = 0; + + /** + * @brief Get size of the entity (tiles) + * + */ + virtual types::Vector2u &getSize(void) noexcept = 0; }; diff --git a/shared/games/components/ITextComponent.hpp b/shared/games/components/ITextComponent.hpp index 655d45e..64dd5cf 100644 --- a/shared/games/components/ITextComponent.hpp +++ b/shared/games/components/ITextComponent.hpp @@ -13,7 +13,10 @@ namespace shared::games::components { class ITextComponent; +} +class shared::games::components::ITextComponent : public virtual IDisplayableComponent { +public: typedef enum { LEFT, CENTER, @@ -38,10 +41,7 @@ namespace shared::games::components { TextFontProps font; // Font of the text types::Color color; // Color of the text } TextProps; -} -class shared::games::components::ITextComponent : public virtual IDisplayableComponent { -public: virtual ~ITextComponent() = default; /** diff --git a/shared/graphics/events/IKeyEvent.hpp b/shared/graphics/events/IKeyEvent.hpp index db6cab4..81fe453 100644 --- a/shared/graphics/events/IKeyEvent.hpp +++ b/shared/graphics/events/IKeyEvent.hpp @@ -13,7 +13,7 @@ namespace shared::graphics::events { class IKeyEvent; } -class shared::graphics::events::IKeyEvent : public IEvent { +class shared::graphics::events::IKeyEvent : public virtual IEvent { public: virtual ~IKeyEvent() = default; diff --git a/shared/graphics/events/IMouseButtonEvent.hpp b/shared/graphics/events/IMouseButtonEvent.hpp index b70ab17..bac5eba 100644 --- a/shared/graphics/events/IMouseButtonEvent.hpp +++ b/shared/graphics/events/IMouseButtonEvent.hpp @@ -13,7 +13,7 @@ namespace shared::graphics::events{ class IMouseButtonEvent; } -class shared::graphics::events::IMouseButtonEvent : public IMouseEvent { +class shared::graphics::events::IMouseButtonEvent : public virtual IMouseEvent { public: virtual ~IMouseButtonEvent() = default; diff --git a/shared/graphics/events/IMouseEvent.hpp b/shared/graphics/events/IMouseEvent.hpp index a85ae4b..618e5fe 100644 --- a/shared/graphics/events/IMouseEvent.hpp +++ b/shared/graphics/events/IMouseEvent.hpp @@ -14,7 +14,7 @@ namespace shared::graphics::events { class IMouseEvent; } -class shared::graphics::events::IMouseEvent : public IEvent { +class shared::graphics::events::IMouseEvent : public virtual IEvent { public: virtual ~IMouseEvent() = default; From 419bd5d05fd8f11683e91da6438db3ba34a5c801 Mon Sep 17 00:00:00 2001 From: Matheo Coquet Date: Tue, 2 Apr 2024 14:09:58 +0200 Subject: [PATCH 16/33] feat(snake): add wall collision --- games/common/components/CollidableComponent.cpp | 4 +++- games/common/components/CollidableComponent.hpp | 7 ++++++- games/snake/src/entities/snake/HeadEntity.cpp | 12 +++++++++++- games/snake/src/entities/snake/HeadEntity.hpp | 11 +++++++++++ games/snake/src/entities/snake/TailEntity.cpp | 2 +- games/snake/src/entities/wall/WallEntity.cpp | 2 +- 6 files changed, 33 insertions(+), 5 deletions(-) diff --git a/games/common/components/CollidableComponent.cpp b/games/common/components/CollidableComponent.cpp index 7a14cd7..bc890d1 100644 --- a/games/common/components/CollidableComponent.cpp +++ b/games/common/components/CollidableComponent.cpp @@ -10,10 +10,12 @@ using namespace arcade::games::common::components; -CollidableComponent::CollidableComponent(shared::games::entity::IEntity &entity) : PositionableComponent(entity) { +CollidableComponent::CollidableComponent(shared::games::entity::IEntity &entity, onCollideFunction function) : PositionableComponent(entity) { this->_type = shared::games::components::COLLIDABLE; + this->_collideFunction = function; } void CollidableComponent::onCollide(std::shared_ptr &ctx, std::shared_ptr target) { + return this->_collideFunction(ctx, target); } diff --git a/games/common/components/CollidableComponent.hpp b/games/common/components/CollidableComponent.hpp index d3b0975..59e2158 100644 --- a/games/common/components/CollidableComponent.hpp +++ b/games/common/components/CollidableComponent.hpp @@ -16,13 +16,15 @@ namespace arcade::games::common::components { class arcade::games::common::components::CollidableComponent : public virtual shared::games::components::ICollidableComponent, public PositionableComponent { public: + typedef void (*onCollideFunction)(std::shared_ptr &ctx, std::shared_ptr target); + ~CollidableComponent() override = default; /** * @brief Create a position component * @param entity */ - explicit CollidableComponent(shared::games::entity::IEntity &entity); + explicit CollidableComponent(shared::games::entity::IEntity &entity, onCollideFunction function); /** * @brief On collide event handler for the component @@ -30,4 +32,7 @@ class arcade::games::common::components::CollidableComponent : public virtual sh * @param target Target entity */ void onCollide(std::shared_ptr &ctx, std::shared_ptr target) override; + +protected: + onCollideFunction _collideFunction; }; diff --git a/games/snake/src/entities/snake/HeadEntity.cpp b/games/snake/src/entities/snake/HeadEntity.cpp index a09f2a4..de07a2d 100644 --- a/games/snake/src/entities/snake/HeadEntity.cpp +++ b/games/snake/src/entities/snake/HeadEntity.cpp @@ -5,7 +5,9 @@ ** HeadEntity class */ +#include "SnakeGame.hpp" #include "HeadEntity.hpp" +#include "../wall/WallEntity.hpp" #include "components/HeadKeyboardComponent.hpp" using namespace arcade::games::common::components; @@ -14,7 +16,7 @@ using namespace shared::games::components; arcade::games::snake::HeadEntity::HeadEntity() : _textureProps( arcade::games::snake::HeadEntity::_defaultTextureProps()), direction(1, 0) { - std::shared_ptr collide = std::make_shared(*this); + std::shared_ptr collide = std::make_shared(*this, HeadEntity::_onCollide); std::shared_ptr texture = std::make_shared(*this, Vector2u(1, 1), 10, this->_textureProps); std::shared_ptr keyboard = std::make_shared( @@ -51,3 +53,11 @@ void arcade::games::snake::HeadEntity::forward() { posCmp->getPosition().y += this->direction.y; } } + +void arcade::games::snake::HeadEntity::_onCollide(std::shared_ptr &ctx, + std::shared_ptr target) { + const auto &wall = dynamic_cast(&target->getEntity()); + auto game = std::dynamic_pointer_cast(ctx); + if (!wall) + return; +} diff --git a/games/snake/src/entities/snake/HeadEntity.hpp b/games/snake/src/entities/snake/HeadEntity.hpp index 4f231f2..630c9ca 100644 --- a/games/snake/src/entities/snake/HeadEntity.hpp +++ b/games/snake/src/entities/snake/HeadEntity.hpp @@ -12,6 +12,8 @@ #include "common/components/TextureComponent.hpp" namespace arcade::games::snake { + class SnakeGame; + class HeadEntity; } @@ -41,5 +43,14 @@ class arcade::games::snake::HeadEntity : public common::AEntity { */ static shared::games::components::TextureProps _defaultTextureProps(); + /** + * @brief Represent the function that will be executed + * when the snake will collide with an other collidable component + * @param ctx Context of the game + * @param target Target component + */ + static void _onCollide(std::shared_ptr &ctx, + std::shared_ptr target); + shared::games::components::TextureProps _textureProps; }; diff --git a/games/snake/src/entities/snake/TailEntity.cpp b/games/snake/src/entities/snake/TailEntity.cpp index 8b81aee..ad9076d 100644 --- a/games/snake/src/entities/snake/TailEntity.cpp +++ b/games/snake/src/entities/snake/TailEntity.cpp @@ -12,7 +12,7 @@ using namespace shared::games::components; arcade::games::snake::TailEntity::TailEntity() : _textureProps( arcade::games::snake::TailEntity::_defaultTextureProps()) { - std::shared_ptr collide = std::make_shared(*this); + std::shared_ptr collide = std::make_shared(*this, nullptr); std::shared_ptr texture = std::make_shared(*this, Vector2u(1, 1), 10, this->_textureProps); this->_components.push_back(collide); diff --git a/games/snake/src/entities/wall/WallEntity.cpp b/games/snake/src/entities/wall/WallEntity.cpp index 71dedf0..1822855 100644 --- a/games/snake/src/entities/wall/WallEntity.cpp +++ b/games/snake/src/entities/wall/WallEntity.cpp @@ -37,7 +37,7 @@ void WallEntity::_createWall(shared::types::Vector2i position) { }, .origin = Vector2u(0, 0) }; - std::shared_ptr collision = std::make_shared(*this); + std::shared_ptr collision = std::make_shared(*this, nullptr); std::shared_ptr texture = std::make_shared(*this, Vector2u(1, 1), 10, textureProps); From b52c2dc42ef9f5554efddd4d3709a8051fb20d35 Mon Sep 17 00:00:00 2001 From: Matheo Coquet Date: Tue, 2 Apr 2024 15:18:00 +0200 Subject: [PATCH 17/33] feat(snake): add loose methods --- .../components/ADisplayableComponent.cpp | 6 ++--- .../components/ADisplayableComponent.hpp | 6 ++--- .../common/components/CollidableComponent.cpp | 5 ++-- .../common/components/CollidableComponent.hpp | 4 +-- games/snake/src/SnakeGame.cpp | 21 ++++++++++++++++ games/snake/src/SnakeGame.hpp | 5 ++++ games/snake/src/entities/snake/HeadEntity.cpp | 25 ++++++++++++------- games/snake/src/entities/snake/HeadEntity.hpp | 7 +++++- games/snake/src/entities/snake/Snake.cpp | 5 ++++ games/snake/src/entities/snake/Snake.hpp | 5 ++++ .../components/HeadKeyboardComponent.cpp | 4 +-- .../components/HeadKeyboardComponent.hpp | 4 +-- .../games/components/ICollidableComponent.hpp | 2 +- .../components/IDisplayableComponent.hpp | 6 ++--- .../games/components/IKeyboardComponent.hpp | 4 +-- .../components/IPositionableComponent.hpp | 4 +-- shared/games/components/ISoundComponent.hpp | 10 ++++---- 17 files changed, 85 insertions(+), 38 deletions(-) diff --git a/games/common/components/ADisplayableComponent.cpp b/games/common/components/ADisplayableComponent.cpp index b8d9ff2..b0e7c75 100644 --- a/games/common/components/ADisplayableComponent.cpp +++ b/games/common/components/ADisplayableComponent.cpp @@ -23,8 +23,8 @@ unsigned int &ADisplayableComponent::getZIndex() noexcept { return this->_zindex; } -void ADisplayableComponent::onMousePress(std::shared_ptr &ctx) {} +void ADisplayableComponent::onMousePress(std::shared_ptr ctx) {} -void ADisplayableComponent::onMouseHover(std::shared_ptr &ctx) {} +void ADisplayableComponent::onMouseHover(std::shared_ptr ctx) {} -void ADisplayableComponent::onMouseRelease(std::shared_ptr &ctx) {} +void ADisplayableComponent::onMouseRelease(std::shared_ptr ctx) {} diff --git a/games/common/components/ADisplayableComponent.hpp b/games/common/components/ADisplayableComponent.hpp index 97fbdfc..a333f3c 100644 --- a/games/common/components/ADisplayableComponent.hpp +++ b/games/common/components/ADisplayableComponent.hpp @@ -34,19 +34,19 @@ class arcade::games::common::components::ADisplayableComponent : public virtual * @brief On click event handler for the entity * @param ctx Context of the game */ - void onMousePress(std::shared_ptr &ctx) override; + void onMousePress(std::shared_ptr ctx) override; /** * @brief On release event handler for the entity * @param ctx Context of the game */ - void onMouseRelease(std::shared_ptr &ctx) override; + void onMouseRelease(std::shared_ptr ctx) override; /** * @brief On hover event handler for the entity * @param ctx Context of the game */ - void onMouseHover(std::shared_ptr &ctx) override; + void onMouseHover(std::shared_ptr ctx) override; protected: /** diff --git a/games/common/components/CollidableComponent.cpp b/games/common/components/CollidableComponent.cpp index bc890d1..be4687e 100644 --- a/games/common/components/CollidableComponent.cpp +++ b/games/common/components/CollidableComponent.cpp @@ -10,12 +10,11 @@ using namespace arcade::games::common::components; -CollidableComponent::CollidableComponent(shared::games::entity::IEntity &entity, onCollideFunction function) : PositionableComponent(entity) { +CollidableComponent::CollidableComponent(shared::games::entity::IEntity &entity, onCollideFunction function) : PositionableComponent(entity), _collideFunction(function) { this->_type = shared::games::components::COLLIDABLE; - this->_collideFunction = function; } -void CollidableComponent::onCollide(std::shared_ptr &ctx, +void CollidableComponent::onCollide(std::shared_ptr ctx, std::shared_ptr target) { return this->_collideFunction(ctx, target); } diff --git a/games/common/components/CollidableComponent.hpp b/games/common/components/CollidableComponent.hpp index 59e2158..82574c5 100644 --- a/games/common/components/CollidableComponent.hpp +++ b/games/common/components/CollidableComponent.hpp @@ -16,7 +16,7 @@ namespace arcade::games::common::components { class arcade::games::common::components::CollidableComponent : public virtual shared::games::components::ICollidableComponent, public PositionableComponent { public: - typedef void (*onCollideFunction)(std::shared_ptr &ctx, std::shared_ptr target); + typedef void (*onCollideFunction)(std::shared_ptr ctx, std::shared_ptr target); ~CollidableComponent() override = default; @@ -31,7 +31,7 @@ class arcade::games::common::components::CollidableComponent : public virtual sh * @param ctx Context of the game * @param target Target entity */ - void onCollide(std::shared_ptr &ctx, std::shared_ptr target) override; + void onCollide(std::shared_ptr ctx, std::shared_ptr target) override; protected: onCollideFunction _collideFunction; diff --git a/games/snake/src/SnakeGame.cpp b/games/snake/src/SnakeGame.cpp index 198c077..5485fe0 100644 --- a/games/snake/src/SnakeGame.cpp +++ b/games/snake/src/SnakeGame.cpp @@ -58,6 +58,27 @@ void snake::SnakeGame::compute(shared::games::DeltaTime dt) { // DEBUG // auto position = std::dynamic_pointer_cast(this->_snake->head->getComponents().at(1)); std::cout << "Snake Position [" << position->getPosition().x << ", " << position->getPosition().y << "]" << std::endl; + + this->loose(); // END DEBUG // } } + +void snake::SnakeGame::loose() { + this->_clock = std::chrono::milliseconds(0); + this->_snake->lastMove = std::chrono::milliseconds(0); + + this->_entities.erase(std::remove_if(this->_entities.begin(), this->_entities.end(), [](const shared::games::entity::EntityPtr& entity) { + auto tail = std::dynamic_pointer_cast(entity); + return !(tail == nullptr); + }), this->_entities.end()); + + this->_snake->reset(); + + for (size_t i = 0; i < 2; i++) { + this->_snake->addTail(); + } + for (auto &tail: this->_snake->getTails()) { + this->_registerEntity(tail); + } +} diff --git a/games/snake/src/SnakeGame.hpp b/games/snake/src/SnakeGame.hpp index e4488ee..c7ff8fc 100644 --- a/games/snake/src/SnakeGame.hpp +++ b/games/snake/src/SnakeGame.hpp @@ -40,6 +40,11 @@ class arcade::games::snake::SnakeGame : public arcade::games::common::AGame { */ void compute(shared::games::DeltaTime dt) override; + /** + * @brief Execute the process of the end of the game when the player loose + */ + void loose(); + protected: std::unique_ptr _snake; shared::games::DeltaTime _clock; diff --git a/games/snake/src/entities/snake/HeadEntity.cpp b/games/snake/src/entities/snake/HeadEntity.cpp index de07a2d..8e69dee 100644 --- a/games/snake/src/entities/snake/HeadEntity.cpp +++ b/games/snake/src/entities/snake/HeadEntity.cpp @@ -22,15 +22,10 @@ arcade::games::snake::HeadEntity::HeadEntity() : _textureProps( std::shared_ptr keyboard = std::make_shared( *this); - collide->getPosition().x = 8; - collide->getPosition().y = 4; this->_components.push_back(collide); - - texture->getPosition().x = 8; - texture->getPosition().y = 4; this->_components.push_back(texture); - this->_components.push_back(keyboard); + this->reset(); } shared::games::components::TextureProps arcade::games::snake::HeadEntity::_defaultTextureProps() { @@ -54,10 +49,22 @@ void arcade::games::snake::HeadEntity::forward() { } } -void arcade::games::snake::HeadEntity::_onCollide(std::shared_ptr &ctx, +void arcade::games::snake::HeadEntity::_onCollide(std::shared_ptr ctx, std::shared_ptr target) { - const auto &wall = dynamic_cast(&target->getEntity()); auto game = std::dynamic_pointer_cast(ctx); - if (!wall) + + if (!dynamic_cast(&target->getEntity()) || !game) return; + game->loose(); +} + +void arcade::games::snake::HeadEntity::reset() { + this->direction = Vector2i(1, 0); + for (auto &component: this->_components) { + std::shared_ptr posCmp = std::dynamic_pointer_cast(component); + if (posCmp == nullptr) continue; + + posCmp->getPosition().x = 8; + posCmp->getPosition().y = 4; + } } diff --git a/games/snake/src/entities/snake/HeadEntity.hpp b/games/snake/src/entities/snake/HeadEntity.hpp index 630c9ca..5b410c2 100644 --- a/games/snake/src/entities/snake/HeadEntity.hpp +++ b/games/snake/src/entities/snake/HeadEntity.hpp @@ -36,6 +36,11 @@ class arcade::games::snake::HeadEntity : public common::AEntity { */ Vector2i direction; + /** + * @brief Set the head at default position + */ + void reset(); + protected: /** * @brief Get default texture props @@ -49,7 +54,7 @@ class arcade::games::snake::HeadEntity : public common::AEntity { * @param ctx Context of the game * @param target Target component */ - static void _onCollide(std::shared_ptr &ctx, + static void _onCollide(std::shared_ptr ctx, std::shared_ptr target); shared::games::components::TextureProps _textureProps; diff --git a/games/snake/src/entities/snake/Snake.cpp b/games/snake/src/entities/snake/Snake.cpp index dd9b905..d995be8 100644 --- a/games/snake/src/entities/snake/Snake.cpp +++ b/games/snake/src/entities/snake/Snake.cpp @@ -33,3 +33,8 @@ std::shared_ptr Snake::addTail() { this->_tails.push_back(newTail); return newTail; } + +void Snake::reset() { + this->head->reset(); + this->_tails.clear(); +} diff --git a/games/snake/src/entities/snake/Snake.hpp b/games/snake/src/entities/snake/Snake.hpp index 2fac39d..b34ac6b 100644 --- a/games/snake/src/entities/snake/Snake.hpp +++ b/games/snake/src/entities/snake/Snake.hpp @@ -45,6 +45,11 @@ class arcade::games::snake::Snake { */ std::vector> &getTails(); + /** + * @brief Reset the snake + */ + void reset(); + shared::games::DeltaTime lastMove; protected: /** diff --git a/games/snake/src/entities/snake/components/HeadKeyboardComponent.cpp b/games/snake/src/entities/snake/components/HeadKeyboardComponent.cpp index bf7e17a..d9893b5 100644 --- a/games/snake/src/entities/snake/components/HeadKeyboardComponent.cpp +++ b/games/snake/src/entities/snake/components/HeadKeyboardComponent.cpp @@ -12,7 +12,7 @@ using namespace shared::games::components; HeadKeyboardComponent::HeadKeyboardComponent(HeadEntity &entity) : AComponent(KEYBOARD, entity), _parent(entity) {} -void HeadKeyboardComponent::onKeyPress(std::shared_ptr &ctx, +void HeadKeyboardComponent::onKeyPress(std::shared_ptr ctx, shared::games::components::IKeyboardComponent::KeyData keyData) { if (keyData.type == ARROW) { if (keyData.code.arrow == UP) { @@ -44,5 +44,5 @@ void HeadKeyboardComponent::onKeyPress(std::shared_ptr &ct } } -void HeadKeyboardComponent::onKeyRelease(std::shared_ptr &ctx, +void HeadKeyboardComponent::onKeyRelease(std::shared_ptr ctx, shared::games::components::IKeyboardComponent::KeyData keyData) {} diff --git a/games/snake/src/entities/snake/components/HeadKeyboardComponent.hpp b/games/snake/src/entities/snake/components/HeadKeyboardComponent.hpp index 742983f..5f42113 100644 --- a/games/snake/src/entities/snake/components/HeadKeyboardComponent.hpp +++ b/games/snake/src/entities/snake/components/HeadKeyboardComponent.hpp @@ -31,14 +31,14 @@ class arcade::games::snake::components::HeadKeyboardComponent * @param ctx Context of the game * @param keyData Key data of key pressed */ - void onKeyPress(std::shared_ptr &ctx, shared::games::components::IKeyboardComponent::KeyData keyData) override; + void onKeyPress(std::shared_ptr ctx, shared::games::components::IKeyboardComponent::KeyData keyData) override; /** * @brief On key release event handler for the entity * @param ctx Context of the game * @param keyData Key data of key released */ - void onKeyRelease(std::shared_ptr &ctx, shared::games::components::IKeyboardComponent::KeyData keyData) override; + void onKeyRelease(std::shared_ptr ctx, shared::games::components::IKeyboardComponent::KeyData keyData) override; protected: HeadEntity &_parent; diff --git a/shared/games/components/ICollidableComponent.hpp b/shared/games/components/ICollidableComponent.hpp index ba65ba0..feec546 100644 --- a/shared/games/components/ICollidableComponent.hpp +++ b/shared/games/components/ICollidableComponent.hpp @@ -25,5 +25,5 @@ class shared::games::components::ICollidableComponent: public virtual IPositiona * @param ctx Context of the game * @param target Target entity */ - virtual void onCollide(std::shared_ptr &ctx, std::shared_ptr target) = 0; + virtual void onCollide(std::shared_ptr ctx, std::shared_ptr target) = 0; }; diff --git a/shared/games/components/IDisplayableComponent.hpp b/shared/games/components/IDisplayableComponent.hpp index 8732895..df1f6b1 100644 --- a/shared/games/components/IDisplayableComponent.hpp +++ b/shared/games/components/IDisplayableComponent.hpp @@ -29,17 +29,17 @@ class shared::games::components::IDisplayableComponent : public virtual IPositio * @brief On click event handler for the entity * @param ctx Context of the game */ - virtual void onMousePress(std::shared_ptr &ctx) = 0; + virtual void onMousePress(std::shared_ptr ctx) = 0; /** * @brief On release event handler for the entity * @param ctx Context of the game */ - virtual void onMouseRelease(std::shared_ptr &ctx) = 0; + virtual void onMouseRelease(std::shared_ptr ctx) = 0; /** * @brief On hover event handler for the entity * @param ctx Context of the game */ - virtual void onMouseHover(std::shared_ptr &ctx) = 0; + virtual void onMouseHover(std::shared_ptr ctx) = 0; }; diff --git a/shared/games/components/IKeyboardComponent.hpp b/shared/games/components/IKeyboardComponent.hpp index f2f474a..a6bb8f8 100644 --- a/shared/games/components/IKeyboardComponent.hpp +++ b/shared/games/components/IKeyboardComponent.hpp @@ -62,12 +62,12 @@ class shared::games::components::IKeyboardComponent: public virtual IComponent * @param ctx Context of the game * @param keyData Key data of key pressed */ - virtual void onKeyPress(std::shared_ptr &ctx, KeyData keyData) = 0; + virtual void onKeyPress(std::shared_ptr ctx, KeyData keyData) = 0; /** * @brief On key release event handler for the entity * @param ctx Context of the game * @param keyData Key data of key released */ - virtual void onKeyRelease(std::shared_ptr &ctx, KeyData keyData) = 0; + virtual void onKeyRelease(std::shared_ptr ctx, KeyData keyData) = 0; }; diff --git a/shared/games/components/IPositionableComponent.hpp b/shared/games/components/IPositionableComponent.hpp index bc51501..6eac1cc 100644 --- a/shared/games/components/IPositionableComponent.hpp +++ b/shared/games/components/IPositionableComponent.hpp @@ -23,11 +23,11 @@ class shared::games::components::IPositionableComponent: public virtual ICompone * @brief Get position of the entity (tiles) * */ - virtual types::Vector2i &getPosition(void) noexcept = 0; + virtual types::Vector2i &getPosition() noexcept = 0; /** * @brief Get size of the entity (tiles) * */ - virtual types::Vector2u &getSize(void) noexcept = 0; + virtual types::Vector2u &getSize() noexcept = 0; }; diff --git a/shared/games/components/ISoundComponent.hpp b/shared/games/components/ISoundComponent.hpp index fd4ab9c..43d6f02 100644 --- a/shared/games/components/ISoundComponent.hpp +++ b/shared/games/components/ISoundComponent.hpp @@ -34,28 +34,28 @@ class shared::games::components::ISoundComponent: public virtual IComponent * * @return Sound path */ - virtual const std::string &getPath(void) const noexcept = 0; + virtual const std::string &getPath() const noexcept = 0; /** * @brief Get state of the sound * * @return Sound state */ - virtual SoundState &getState(void) noexcept = 0; + virtual SoundState &getState() noexcept = 0; /** * @brief Get volume of the sound * * @return Sound volume */ - virtual SoundVolume &getVolume(void) noexcept = 0; + virtual SoundVolume &getVolume() noexcept = 0; /** * @brief Get loop of the sound * * @return Sound loop */ - virtual bool &getLoop(void) noexcept = 0; + virtual bool &getLoop() noexcept = 0; /** * @brief On state change event handler for the component @@ -63,5 +63,5 @@ class shared::games::components::ISoundComponent: public virtual IComponent * @param ctx Context of the game * @param state New state of the sound */ - virtual void onStateChange(std::shared_ptr &ctx, SoundState state) = 0; + virtual void onStateChange(std::shared_ptr ctx, SoundState state) = 0; }; From 70c36346f6ee89cbef8fa2e8e91b0a3ee362bca0 Mon Sep 17 00:00:00 2001 From: Matheo Coquet Date: Tue, 2 Apr 2024 15:22:58 +0200 Subject: [PATCH 18/33] feat(snake): add loose condition when snake collide with tail --- games/snake/src/entities/snake/HeadEntity.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/games/snake/src/entities/snake/HeadEntity.cpp b/games/snake/src/entities/snake/HeadEntity.cpp index 8e69dee..1474ce2 100644 --- a/games/snake/src/entities/snake/HeadEntity.cpp +++ b/games/snake/src/entities/snake/HeadEntity.cpp @@ -53,7 +53,10 @@ void arcade::games::snake::HeadEntity::_onCollide(std::shared_ptr target) { auto game = std::dynamic_pointer_cast(ctx); - if (!dynamic_cast(&target->getEntity()) || !game) + if ( + !dynamic_cast(&target->getEntity()) || + !dynamic_cast(&target->getEntity()) || + !game) return; game->loose(); } From 1198402ffeef50e1473c7f67e7679cd559cbef80 Mon Sep 17 00:00:00 2001 From: Matheo Coquet Date: Tue, 2 Apr 2024 15:29:36 +0200 Subject: [PATCH 19/33] fix(snake): add a loose state to prevent delete of entities during events --- games/snake/src/SnakeGame.cpp | 14 ++++++++++---- games/snake/src/SnakeGame.hpp | 12 ++++++++++-- games/snake/src/entities/snake/HeadEntity.cpp | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/games/snake/src/SnakeGame.cpp b/games/snake/src/SnakeGame.cpp index 5485fe0..1cc0da5 100644 --- a/games/snake/src/SnakeGame.cpp +++ b/games/snake/src/SnakeGame.cpp @@ -42,6 +42,7 @@ snake::SnakeGame::SnakeGame() : common::AGame(Vector2u(20, 20), 60) { this->_registerEntity(std::make_unique(Vector2u(20, 20))); this->_clock = std::chrono::milliseconds(0); + this->_looseGame = false; } const shared::games::GameManifest &snake::SnakeGame::getManifest() const noexcept { @@ -51,6 +52,9 @@ const shared::games::GameManifest &snake::SnakeGame::getManifest() const noexcep void snake::SnakeGame::compute(shared::games::DeltaTime dt) { this->_clock += dt; + if (this->_looseGame) { + return this->_loose(); + } if (this->_clock > std::chrono::milliseconds(300) + this->_snake->lastMove) { this->_snake->lastMove = this->_clock; this->_snake->head->forward(); @@ -58,15 +62,13 @@ void snake::SnakeGame::compute(shared::games::DeltaTime dt) { // DEBUG // auto position = std::dynamic_pointer_cast(this->_snake->head->getComponents().at(1)); std::cout << "Snake Position [" << position->getPosition().x << ", " << position->getPosition().y << "]" << std::endl; - - this->loose(); // END DEBUG // } } -void snake::SnakeGame::loose() { +void snake::SnakeGame::_loose() { this->_clock = std::chrono::milliseconds(0); - this->_snake->lastMove = std::chrono::milliseconds(0); + this->_snake->lastMove = std::chrono::milliseconds(900); this->_entities.erase(std::remove_if(this->_entities.begin(), this->_entities.end(), [](const shared::games::entity::EntityPtr& entity) { auto tail = std::dynamic_pointer_cast(entity); @@ -82,3 +84,7 @@ void snake::SnakeGame::loose() { this->_registerEntity(tail); } } + +void snake::SnakeGame::setLooseGame(bool state) { + this->_looseGame = state; +} diff --git a/games/snake/src/SnakeGame.hpp b/games/snake/src/SnakeGame.hpp index c7ff8fc..fde5a78 100644 --- a/games/snake/src/SnakeGame.hpp +++ b/games/snake/src/SnakeGame.hpp @@ -41,11 +41,19 @@ class arcade::games::snake::SnakeGame : public arcade::games::common::AGame { void compute(shared::games::DeltaTime dt) override; /** - * @brief Execute the process of the end of the game when the player loose + * @brief Set loose game state + * + * @param state If the game is loose or not */ - void loose(); + void setLooseGame(bool state); protected: + /** + * @brief Execute the process of the end of the game when the player _loose + */ + void _loose(); + std::unique_ptr _snake; shared::games::DeltaTime _clock; + bool _looseGame; }; diff --git a/games/snake/src/entities/snake/HeadEntity.cpp b/games/snake/src/entities/snake/HeadEntity.cpp index 1474ce2..b440b4d 100644 --- a/games/snake/src/entities/snake/HeadEntity.cpp +++ b/games/snake/src/entities/snake/HeadEntity.cpp @@ -58,7 +58,7 @@ void arcade::games::snake::HeadEntity::_onCollide(std::shared_ptr(&target->getEntity()) || !game) return; - game->loose(); + game->setLooseGame(true); } void arcade::games::snake::HeadEntity::reset() { From 9a241e1561025d02638ab4a83f3c32cc967f0655 Mon Sep 17 00:00:00 2001 From: Matheo Coquet Date: Tue, 2 Apr 2024 15:41:08 +0200 Subject: [PATCH 20/33] feat(snake): add texture horientation for head --- games/snake/src/entities/snake/HeadEntity.cpp | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/games/snake/src/entities/snake/HeadEntity.cpp b/games/snake/src/entities/snake/HeadEntity.cpp index b440b4d..373feac 100644 --- a/games/snake/src/entities/snake/HeadEntity.cpp +++ b/games/snake/src/entities/snake/HeadEntity.cpp @@ -9,6 +9,7 @@ #include "HeadEntity.hpp" #include "../wall/WallEntity.hpp" #include "components/HeadKeyboardComponent.hpp" +#include using namespace arcade::games::common::components; using namespace shared::games::components; @@ -35,17 +36,29 @@ shared::games::components::TextureProps arcade::games::snake::HeadEntity::_defau .bin = "assets/snake/head.png", .binTileSize = Vector2f(40, 40) }, - .origin = Vector2u(0, 0) + .origin = Vector2u(3, 0) }; } void arcade::games::snake::HeadEntity::forward() { for (auto &component: this->_components) { - std::shared_ptr posCmp = std::dynamic_pointer_cast(component); + auto posCmp = std::dynamic_pointer_cast(component); if (posCmp == nullptr) continue; posCmp->getPosition().x += this->direction.x; posCmp->getPosition().y += this->direction.y; + + auto textureCmp = std::dynamic_pointer_cast(component); + if (textureCmp == nullptr) continue; + + textureCmp->getTextureProps().origin = Vector2u(0, 0); + if (this->direction.y == 0) + textureCmp->getTextureProps().origin.x = 2; + if (this->direction.x > 0) + textureCmp->getTextureProps().origin.x += 1; + if (this->direction.y < 0) + textureCmp->getTextureProps().origin.x += 1; + std::cout << textureCmp->getTextureProps().origin.x << std::endl; } } From 8b2b5db8fb81626c941c95df8091927223f68bb3 Mon Sep 17 00:00:00 2001 From: Matheo Coquet Date: Tue, 2 Apr 2024 16:14:24 +0200 Subject: [PATCH 21/33] merge main --- core/CMakeLists.txt | 6 +- core/main.cpp | 35 +- core/src/CMakeLists.txt | 5 + core/src/Core.cpp | 402 ++++++++++++++++++ core/src/Core.hpp | 273 ++++++++++++ core/src/exception/CMakeLists.txt | 3 +- core/src/loader/CMakeLists.txt | 3 +- core/src/loader/Loader.cpp | 10 +- core/src/loader/Loader.hpp | 11 +- core/src/types/CMakeLists.txt | 3 + core/src/types/Providers.hpp | 4 +- core/src/utils/DLLoader/CMakeLists.txt | 2 +- graphics/CMakeLists.txt | 3 +- graphics/common/CMakeLists.txt | 3 + graphics/common/events/CMakeLists.txt | 3 + graphics/common/events/key/AKeyEvent.hpp | 46 ++ graphics/common/events/key/CMakeLists.txt | 6 + graphics/common/events/key/KeyPressEvent.hpp | 21 + .../common/events/key/KeyReleaseEvent.hpp | 20 + graphics/common/events/key/key.hpp | 11 + .../common/events/mouse/AMouseButtonEvent.hpp | 52 +++ graphics/common/events/mouse/AMouseEvent.hpp | 42 ++ graphics/common/events/mouse/CMakeLists.txt | 8 + .../events/mouse/MouseButtonPressEvent.hpp | 24 ++ .../events/mouse/MouseButtonReleaseEvent.hpp | 23 + .../common/events/mouse/MouseMoveEvent.hpp | 24 ++ graphics/common/events/mouse/mouse.hpp | 12 + graphics/common/events/window/CMakeLists.txt | 5 + .../common/events/window/WindowCloseEvent.hpp | 27 ++ .../events/window/WindowResizeEvent.hpp | 27 ++ graphics/common/events/window/window.hpp | 11 + graphics/common/exceptions/CMakeLists.txt | 8 + graphics/common/exceptions/FontException.hpp | 22 + .../common/exceptions/GraphicsException.cpp | 24 ++ .../common/exceptions/GraphicsException.hpp | 31 ++ graphics/common/exceptions/SoundException.hpp | 22 + .../common/exceptions/TextureException.hpp | 22 + .../common/exceptions/WindowException.hpp | 22 + graphics/sfml/CMakeLists.txt | 25 ++ graphics/sfml/export.cpp | 26 ++ graphics/sfml/src/GraphicsProvider.cpp | 57 +++ graphics/sfml/src/GraphicsProvider.hpp | 68 +++ graphics/sfml/src/font/Font.cpp | 26 ++ graphics/sfml/src/font/Font.hpp | 32 ++ graphics/sfml/src/sound/Sound.cpp | 63 +++ graphics/sfml/src/sound/Sound.hpp | 34 ++ graphics/sfml/src/texture/Texture.cpp | 25 ++ graphics/sfml/src/texture/Texture.hpp | 31 ++ graphics/sfml/src/window/EventsHandler.cpp | 227 ++++++++++ graphics/sfml/src/window/EventsHandler.hpp | 137 ++++++ graphics/sfml/src/window/Renderer.cpp | 135 ++++++ graphics/sfml/src/window/Renderer.hpp | 112 +++++ graphics/sfml/src/window/Window.cpp | 171 ++++++++ graphics/sfml/src/window/Window.hpp | 171 ++++++++ utils/compiler.hpp | 10 + 55 files changed, 2582 insertions(+), 44 deletions(-) create mode 100644 core/src/Core.cpp create mode 100644 core/src/Core.hpp create mode 100644 core/src/types/CMakeLists.txt create mode 100644 graphics/common/CMakeLists.txt create mode 100644 graphics/common/events/CMakeLists.txt create mode 100644 graphics/common/events/key/AKeyEvent.hpp create mode 100644 graphics/common/events/key/CMakeLists.txt create mode 100644 graphics/common/events/key/KeyPressEvent.hpp create mode 100644 graphics/common/events/key/KeyReleaseEvent.hpp create mode 100644 graphics/common/events/key/key.hpp create mode 100644 graphics/common/events/mouse/AMouseButtonEvent.hpp create mode 100644 graphics/common/events/mouse/AMouseEvent.hpp create mode 100644 graphics/common/events/mouse/CMakeLists.txt create mode 100644 graphics/common/events/mouse/MouseButtonPressEvent.hpp create mode 100644 graphics/common/events/mouse/MouseButtonReleaseEvent.hpp create mode 100644 graphics/common/events/mouse/MouseMoveEvent.hpp create mode 100644 graphics/common/events/mouse/mouse.hpp create mode 100644 graphics/common/events/window/CMakeLists.txt create mode 100644 graphics/common/events/window/WindowCloseEvent.hpp create mode 100644 graphics/common/events/window/WindowResizeEvent.hpp create mode 100644 graphics/common/events/window/window.hpp create mode 100644 graphics/common/exceptions/CMakeLists.txt create mode 100644 graphics/common/exceptions/FontException.hpp create mode 100644 graphics/common/exceptions/GraphicsException.cpp create mode 100644 graphics/common/exceptions/GraphicsException.hpp create mode 100644 graphics/common/exceptions/SoundException.hpp create mode 100644 graphics/common/exceptions/TextureException.hpp create mode 100644 graphics/common/exceptions/WindowException.hpp create mode 100644 graphics/sfml/CMakeLists.txt create mode 100644 graphics/sfml/export.cpp create mode 100644 graphics/sfml/src/GraphicsProvider.cpp create mode 100644 graphics/sfml/src/GraphicsProvider.hpp create mode 100644 graphics/sfml/src/font/Font.cpp create mode 100644 graphics/sfml/src/font/Font.hpp create mode 100644 graphics/sfml/src/sound/Sound.cpp create mode 100644 graphics/sfml/src/sound/Sound.hpp create mode 100644 graphics/sfml/src/texture/Texture.cpp create mode 100644 graphics/sfml/src/texture/Texture.hpp create mode 100644 graphics/sfml/src/window/EventsHandler.cpp create mode 100644 graphics/sfml/src/window/EventsHandler.hpp create mode 100644 graphics/sfml/src/window/Renderer.cpp create mode 100644 graphics/sfml/src/window/Renderer.hpp create mode 100644 graphics/sfml/src/window/Window.cpp create mode 100644 graphics/sfml/src/window/Window.hpp create mode 100644 utils/compiler.hpp diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt index 2b63a86..95198b9 100644 --- a/core/CMakeLists.txt +++ b/core/CMakeLists.txt @@ -1,8 +1,8 @@ -add_executable(${PROJECT_NAME} +add_executable(arcade main.cpp ) -target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_LIST_DIR}/..) -target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_LIST_DIR}/src) +target_include_directories(arcade PUBLIC ${CMAKE_CURRENT_LIST_DIR}/..) +target_include_directories(arcade PUBLIC ${CMAKE_CURRENT_LIST_DIR}/src) add_subdirectory(src) diff --git a/core/main.cpp b/core/main.cpp index 2965389..db25d09 100644 --- a/core/main.cpp +++ b/core/main.cpp @@ -5,34 +5,21 @@ ** main */ +#include "Core.hpp" #include "loader/Loader.hpp" int main(void) { Loader loader; - try { - loader.loadLibraries("./lib"); - std::cout << "Games libraries:" << loader.getGamesLibraries().size() << std::endl; - std::cout << "Graphics libraries:" << loader.getGraphicsLibraries().size() << std::endl; - } catch (const std::exception &e) { - std::cerr << e.what() << std::endl; - } - auto lib = loader.getGamesLibraries().at(0).get(); - auto manifest = lib->getManifest(); - std::cout << "Game name: " << manifest.name << std::endl; - std::cout << "Game description: " << manifest.description << std::endl; - std::cout << "Game version: " << manifest.version << std::endl; - std::cout << "Game authors: " << manifest.authors[0].name << std::endl; - - auto game = lib->createInstance(); - - auto last = std::chrono::high_resolution_clock::now(); - while (true) { - auto current_time = std::chrono::high_resolution_clock::now(); - auto elapsed_time = duration_cast>(current_time - last); - game->compute(elapsed_time); - last = current_time; - } - return 0; + try { + loader.loadLibraries("./lib"); + std::cout << "Games libraries:" << loader.getGamesLibraries().size() << std::endl; + std::cout << "Graphics libraries:" << loader.getGraphicsLibraries().size() << std::endl; + Core core(loader.getGamesLibraries(), loader.getGraphicsLibraries()); + core.run(); + } catch (const std::exception &e) { + std::cerr << e.what() << std::endl; + } + return 0; } diff --git a/core/src/CMakeLists.txt b/core/src/CMakeLists.txt index ea744bc..e2576e8 100644 --- a/core/src/CMakeLists.txt +++ b/core/src/CMakeLists.txt @@ -1,3 +1,8 @@ +target_sources(arcade PRIVATE + Core.cpp + Core.hpp +) + add_subdirectory(exception) add_subdirectory(loader) add_subdirectory(utils) diff --git a/core/src/Core.cpp b/core/src/Core.cpp new file mode 100644 index 0000000..48f4526 --- /dev/null +++ b/core/src/Core.cpp @@ -0,0 +1,402 @@ +/* +** EPITECH PROJECT, 2024 +** arcade +** File description: +** Core +*/ + +#include + +#include +#include +#include "Core.hpp" +#include "shared/games/components/IComponent.hpp" + +Core::Core(GameProviders &gameProviders, GraphicsProviders &graphicsProviders) : + _gameProviders(gameProviders), _graphicsProviders(graphicsProviders), + _gameProvider(gameProviders.at(0)), _graphicsProvider(graphicsProviders.at(0)) {} + +Core::~Core() {} + +void Core::_initGame() +{ + this->_game = this->_gameProvider->createInstance(); +} + +void Core::_initWindow() +{ + auto gameManifest = this->_game->getManifest(); + IWindow::WindowInitProps windowInitProps { + this->_game->getSize(), + IWindow::WINDOWED, + this->_game->getFps(), + gameManifest.name, + gameManifest.iconPath + }; + + this->_window = this->_graphicsProvider->createWindow(windowInitProps); +} + +std::shared_ptr Core::_getTexture(std::string bin, std::string ascii) +{ + if (this->_textures.find(bin + ascii) == this->_textures.end()) + this->_textures[bin + ascii] = this->_graphicsProvider->createTexture(bin, ascii); + return this->_textures[bin + ascii]; +} + +std::shared_ptr Core::_getFont(std::string path) +{ + if (this->_fonts.find(path) == this->_fonts.end()) + this->_fonts[path] = this->_graphicsProvider->createFont(path); + return this->_fonts[path]; +} + +Core::SoundProps Core::_getSound(std::string path) +{ + if (this->_sounds.find(path) == this->_sounds.end()) { + SoundProps soundProps { + this->_graphicsProvider->createSound(path), + ISound::SoundState::STOP, + components::STOP + }; + soundProps.sound->setState(ISound::SoundState::STOP); + this->_sounds[path] = soundProps; + } + return this->_sounds[path]; +} + +TextureProps Core::_getTextureEntity(std::shared_ptr texture) +{ + auto textureProps = texture->getTextureProps(); + TextureProps entityTextureProps { + this->_getTexture(textureProps.sources.bin, textureProps.sources.ascii), + textureProps.sources.binTileSize, + textureProps.origin, + texture->getSize(), + texture->getPosition() + }; + + return entityTextureProps; +} + +TextProps Core::_getTextEntity(std::shared_ptr text) +{ + auto textProps = text->getTextProps(); + TextProps entityTextProps { + this->_getFont(textProps.font.path), + textProps.font.size, + textProps.content, + static_cast(textProps.align), + static_cast(textProps.verticalAlign), + textProps.color, + text->getSize(), + text->getPosition() + }; + + return entityTextProps; +} + +void Core::_renderTextureProps(std::map> &textures, std::map>::iterator &texturePropsIt) +{ + if (texturePropsIt == textures.end()) + return; + for (auto &textureProps : texturePropsIt->second) + this->_window->render(textureProps); + texturePropsIt++; +} + +void Core::_renderTextProps(std::map> &texts, std::map>::iterator &textPropsIt) +{ + if (textPropsIt == texts.end()) + return; + for (auto &textureProps : textPropsIt->second) + this->_window->render(textureProps); + textPropsIt++; +} + +void Core::_renderProps(std::map> &textures, std::map> &texts) +{ + auto textPropsIt = texts.begin(); + auto texturePropsIt = textures.begin(); + + while (texturePropsIt != textures.end() || textPropsIt != texts.end()) { + if (textPropsIt != texts.end()) { + if (texturePropsIt->first <= textPropsIt->first) + this->_renderTextureProps(textures, texturePropsIt); + } else { + this->_renderTextureProps(textures, texturePropsIt); + } + if (texturePropsIt != textures.end()) { + if (textPropsIt->first <= texturePropsIt->first) + this->_renderTextProps(texts, textPropsIt); + } else { + this->_renderTextProps(texts, textPropsIt); + } + } +} + +void Core::_renderEntities() +{ + std::map> entitiesTextureProps; + std::map> entitiesTextProps; + + for (auto &entity : this->_gameEntities) { + auto components = entity->getComponents(); + for (auto &component : components) { + if (component->getType() == components::TEXTURE) { + auto texture = std::dynamic_pointer_cast(component); + unsigned int index = texture->getZIndex(); + entitiesTextureProps[index].push_back(this->_getTextureEntity(texture)); + } + if (component->getType() == components::TEXT) { + auto texture = std::dynamic_pointer_cast(component); + unsigned int index = texture->getZIndex(); + entitiesTextProps[index].push_back(this->_getTextEntity(texture)); + } + } + } + this->_window->clear(); + this->_renderProps(entitiesTextureProps, entitiesTextProps); + this->_window->display(); +} + +components::IKeyboardComponent::KeyData Core::_convertKeyPressData(events::IKeyEvent::KeyType type, events::IKeyEvent::KeyCode code) +{ + components::IKeyboardComponent::KeyData keyCodeData; + + if (type == events::IKeyEvent::CHAR) { + keyCodeData.code.character = code.character; + keyCodeData.type = components::IKeyboardComponent::CHAR; + } else if (type == events::IKeyEvent::CONTROL) { + keyCodeData.code.control = static_cast(code.control); + keyCodeData.type = components::IKeyboardComponent::CONTROL; + } else if (type == events::IKeyEvent::ARROW) { + keyCodeData.code.arrow = static_cast(code.arrow); + keyCodeData.type = components::IKeyboardComponent::ARROW; + } else if (type == events::IKeyEvent::FUNC) { + keyCodeData.code.func = code.func; + keyCodeData.type = components::IKeyboardComponent::FUNC; + } + return keyCodeData; +} + +void Core::_preventWindowClose(std::vector events) +{ + for (auto &event : events) { + auto type = event->getType(); + if (type == events::WINDOW_CLOSE) + this->_handleWindowClose(); + } +} + +void Core::_handleKeyPress(std::shared_ptr &keyEvent, std::shared_ptr &keyboard) +{ + auto keyCode = keyEvent->getKeyCode(); + auto keyType = keyEvent->getKeyType(); + auto keyCodeData = this->_convertKeyPressData(keyType, keyCode); + + keyboard->onKeyPress(this->_game, keyCodeData); +} + +void Core::_handleKeyRelease(std::shared_ptr &keyEvent, std::shared_ptr &keyboard) +{ + auto keyCode = keyEvent->getKeyCode(); + auto keyType = keyEvent->getKeyType(); + auto keyCodeData = this->_convertKeyPressData(keyType, keyCode); + + keyboard->onKeyRelease(this->_game, keyCodeData); +} + +void Core::_handleMouseButtonPress(std::shared_ptr &event, std::shared_ptr &component) +{ + auto button = event->getButton(); + auto mousePosition = event->getPosition(); + auto entityPosition = component->getPosition(); + auto entitySize = component->getSize(); + + if (mousePosition.x >= entityPosition.x && mousePosition.x <= entityPosition.x + entitySize.x && + mousePosition.y >= entityPosition.y && mousePosition.y <= entityPosition.y + entitySize.y) + component->onMousePress(this->_game); +} + +void Core::_handleMouseButtonRelease(std::shared_ptr &event, std::shared_ptr &component) +{ + auto button = event->getButton(); + auto mousePosition = event->getPosition(); + auto entityPosition = component->getPosition(); + auto entitySize = component->getSize(); + + if (mousePosition.x >= entityPosition.x && mousePosition.x <= entityPosition.x + entitySize.x && + mousePosition.y >= entityPosition.y && mousePosition.y <= entityPosition.y + entitySize.y) + component->onMouseRelease(this->_game); +} + +void Core::_handleMouseMove(std::shared_ptr &event, std::shared_ptr &component) +{ + auto mousePosition = event->getPosition(); + auto entityPosition = component->getPosition(); + auto entitySize = component->getSize(); + + if (mousePosition.x >= entityPosition.x && mousePosition.x <= entityPosition.x + entitySize.x && + mousePosition.y >= entityPosition.y && mousePosition.y <= entityPosition.y + entitySize.y) + component->onMouseHover(this->_game); +} + +void Core::_handleWindowClose() +{ + this->_window->close(); +} + +void Core::_handleWindowResize() +{ + std::cout << "Window resized" << std::endl; +} + +void Core::_handleKeyboardEvents(std::vector &events, std::shared_ptr &component) +{ + for (auto &event : events) { + auto type = event->getType(); + if (type == events::KEY_PRESS) { + auto keyEvent = std::dynamic_pointer_cast(event); + this->_handleKeyPress(keyEvent, component); + } + if (type == events::KEY_RELEASE) { + auto keyEvent = std::dynamic_pointer_cast(event); + this->_handleKeyRelease(keyEvent, component); + } + } +} + +void Core::_handleDisplayableEvents(std::vector &events, std::shared_ptr &component) +{ + for (auto &event : events) { + auto type = event->getType(); + if (type == events::MOUSE_BTN_PRESS) { + auto mouseButtonEvent = std::dynamic_pointer_cast(event); + this->_handleMouseButtonPress(mouseButtonEvent, component); + } + if (type == events::MOUSE_BTN_RELEASE) { + auto mouseButtonEvent = std::dynamic_pointer_cast(event); + this->_handleMouseButtonRelease(mouseButtonEvent, component); + } + if (type == events::MOUSE_MOVE) { + auto mouseEvent = std::dynamic_pointer_cast(event); + this->_handleMouseMove(mouseEvent, component); + } + } +} + +void Core::_handleCollisions(std::shared_ptr &component, std::shared_ptr &target) +{ + auto componentPosition = component->getPosition(); + auto componentSize = component->getSize(); + auto targetPosition = target->getPosition(); + auto targetSize = target->getSize(); + + if (componentPosition.x < targetPosition.x + targetSize.x && + componentPosition.x + componentSize.x > targetPosition.x && + componentPosition.y < targetPosition.y + targetSize.y && + componentPosition.y + componentSize.y > targetPosition.y) + component->onCollide(this->_game, target); +} + +void Core::_handleCollidableComponents(std::shared_ptr &component) +{ + for (auto &entity : this->_gameEntities) { + auto components = entity->getComponents(); + for (auto &entityComponent : components) { + if (entityComponent->getType() == components::COLLIDABLE) { + auto collidable = std::dynamic_pointer_cast(entityComponent); + this->_handleCollisions(component, collidable); + } + } + } +} + +void Core::_handleSoundComponent(std::shared_ptr &gameSound) +{ + auto gameSoundPath = gameSound->getPath(); + auto sound = this->_getSound(gameSoundPath); + + auto gameSoundState = gameSound->getState(); + auto gameSoundVolume = gameSound->getVolume(); + auto gameSoundLoop = gameSound->getLoop(); + auto graphicSoundState = sound.sound->getState(); + auto graphicSoundVolume = sound.sound->getVolume(); + auto graphicSoundLoop = sound.sound->getLoopState(); + + if (gameSoundState != sound.previousGameState) { + if (gameSoundState == components::PLAY) + sound.sound->setState(ISound::SoundState::PLAY); + if (gameSoundState == components::PAUSE) + sound.sound->setState(ISound::SoundState::PAUSE); + if (gameSoundState == components::STOP) + sound.sound->setState(ISound::SoundState::STOP); + sound.previousGameState = gameSoundState; + } + if (graphicSoundState != sound.previousGraphicState) { + if (graphicSoundState == ISound::SoundState::PLAY) + gameSound->onStateChange(this->_game, components::PLAY); + if (graphicSoundState == ISound::SoundState::PAUSE) + gameSound->onStateChange(this->_game, components::PAUSE); + if (graphicSoundState == ISound::SoundState::STOP) + gameSound->onStateChange(this->_game, components::STOP); + } + if (gameSoundVolume != graphicSoundVolume) + sound.sound->setVolume(gameSoundVolume); + if (gameSoundLoop != graphicSoundLoop) + sound.sound->setLoopState(gameSoundLoop); +} + +void Core::_handleComponentEvents(std::vector &events, std::shared_ptr &component) +{ + auto type = component->getType(); + + if (type == components::KEYBOARD) { + auto keyboard = std::dynamic_pointer_cast(component); + this->_handleKeyboardEvents(events, keyboard); + } + if (type == components::TEXT || type == components::TEXTURE) { + auto displayable = std::dynamic_pointer_cast(component); + this->_handleDisplayableEvents(events, displayable); + } + if (type == components::COLLIDABLE) { + auto collidable = std::dynamic_pointer_cast(component); + this->_handleCollidableComponents(collidable); + } + if (type == components::SOUND) { + auto sound = std::dynamic_pointer_cast(component); + this->_handleSoundComponent(sound); + } +} + +void Core::_handleEvents() +{ + auto gameEvents = this->_window->getEvents(); + + this->_preventWindowClose(gameEvents); + for (auto &entity : this->_gameEntities) { + auto components = entity->getComponents(); + for (auto &component : components) { + this->_handleComponentEvents(gameEvents, component); + } + } +} + +void Core::run() +{ + auto previousTime = std::chrono::high_resolution_clock::now(); + + this->_initGame(); + this->_initWindow(); + while (this->_window->isOpen()) { + auto currentTime = std::chrono::high_resolution_clock::now(); + auto deltaTime = std::chrono::duration_cast(previousTime - currentTime); + previousTime = currentTime; + + this->_game->compute(deltaTime); + this->_gameEntities = this->_game->getEntities(); + this->_handleEvents(); + this->_renderEntities(); + } +} diff --git a/core/src/Core.hpp b/core/src/Core.hpp new file mode 100644 index 0000000..bcab8cc --- /dev/null +++ b/core/src/Core.hpp @@ -0,0 +1,273 @@ +/* +** EPITECH PROJECT, 2024 +** arcade +** File description: +** Core +*/ + +#pragma once + +#include +#include "types/Providers.hpp" +#include "shared/graphics/ISound.hpp" +#include "shared/graphics/events/IKeyEvent.hpp" +#include "shared/graphics/events/IMouseEvent.hpp" +#include "shared/graphics/events/IMouseButtonEvent.hpp" +#include "shared/games/components/ITextComponent.hpp" +#include "shared/games/components/ITextureComponent.hpp" +#include "shared/games/components/IKeyboardComponent.hpp" +#include "shared/games/components/IDisplayableComponent.hpp" +#include "shared/games/components/ICollidableComponent.hpp" +#include "shared/games/components/ISoundComponent.hpp" + +using namespace shared::graphics; +using namespace shared::games; + +class Core { + public: + Core(GameProviders &gameProviders, GraphicsProviders &graphicsProviders); + ~Core(); + + /** + * @brief Run the core + * + */ + void run(); + + private: + + typedef struct { + std::shared_ptr sound; + ISound::SoundState previousGraphicState; + components::SoundState previousGameState; + } SoundProps; + + std::shared_ptr _game; + std::shared_ptr _window; + std::shared_ptr &_gameProvider; + std::shared_ptr &_graphicsProvider; + std::map> _fonts; + std::map> _textures; + std::map _sounds; + GameProviders &_gameProviders; + GraphicsProviders &_graphicsProviders; + entity::EntitiesMap _gameEntities; + + /** + * @brief Initialize the window + * + */ + void _initWindow(); + + /** + * @brief Initialize the game + * + */ + void _initGame(); + + /** + * @brief Render all entities + * + */ + void _renderEntities(); + + /** + * @brief Get a texture + * + * @param bin Path to the binary file + * @param ascii Path to the ascii file + * @return The correct texture + */ + std::shared_ptr _getTexture(std::string bin, std::string ascii); + + /** + * @brief Get a font + * + * @param path Path to the font file + * @return The correct font + */ + std::shared_ptr _getFont(std::string path); + + /** + * @brief Get a sound + * + * @param path Path to the sound file + * @return The correct sound + */ + SoundProps _getSound(std::string path); + + /** + * @brief Get the texture entity + * + * @param texture The texture component + * @return The texture entity + */ + TextureProps _getTextureEntity(std::shared_ptr texture); + + /** + * @brief Get the text entity + * + * @param text The text component + * @return The text entity + */ + TextProps _getTextEntity(std::shared_ptr text); + + /** + * @brief Render the props + * + * @param textures The textures + * @param texts The texts + */ + void _renderProps(std::map> &textures, std::map> &texts); + + /** + * @brief Render the texture props + * + * @param textures The textures + * @param texturePropsIt The iterator + */ + void _renderTextureProps(std::map> &textures, std::map>::iterator &texturePropsIt); + + /** + * @brief Render the text props + * + * @param texts The texts + * @param textPropsIt The iterator + */ + void _renderTextProps(std::map> &texts, std::map>::iterator &textPropsIt); + + /** + * @brief Handle the events + * + */ + void _handleEvents(); + + /** + * @brief Handle the component events + * + * @param events Events to handle + * @param component The component + */ + void _handleComponentEvents(std::vector &events, std::shared_ptr &component); + + /** + * @brief Handle the keyboard events + * + * @param events Events to handle + * @param component The keyboard component + */ + void _handleKeyboardEvents(std::vector &events, std::shared_ptr &component); + + /** + * @brief Handle the displayable events + * + * @param events Events to handle + * @param component The displayable component + */ + void _handleDisplayableEvents(std::vector &events, std::shared_ptr &component); + + /** + * @brief Handle the collidable events + * + * @param events Events to handle + * @param component The collidable component + */ + void _handleCollidableComponents(std::shared_ptr &component); + + /** + * @brief Handle the collisions + * + * @param component The collidable component + * @param target The target collidable component + */ + void _handleCollisions(std::shared_ptr &component, std::shared_ptr &target); + + /** + * @brief Handle the key press event + * + * @param event The key event + * @param component The keyboard component + */ + void _handleKeyPress(std::shared_ptr &event, std::shared_ptr &component); + + /** + * @brief Handle the key release event + * + * @param event The key event + * @param component The keyboard component + */ + void _handleKeyRelease(std::shared_ptr &event, std::shared_ptr &component); + + /** + * @brief Handle the mouse button press event + * + * @param event The mouse button event + * @param component The displayable component + */ + void _handleMouseButtonPress(std::shared_ptr &event, std::shared_ptr &component); + + /** + * @brief Handle the mouse button release event + * + * @param event The mouse button event + * @param component The displayable component + */ + void _handleMouseButtonRelease(std::shared_ptr &event, std::shared_ptr &component); + + /** + * @brief Handle the mouse move event + * + * @param event The mouse event + * @param component The displayable component + */ + void _handleMouseMove(std::shared_ptr &event, std::shared_ptr &component); + + /** + * @brief Handle the window close event + * + */ + void _handleWindowClose(); + + /** + * @brief Handle the window resize event + * + */ + void _handleWindowResize(); + + /** + * @brief Prevent the window from closing + * + * @param events The events + */ + void _preventWindowClose(std::vector events); + + /** + * @brief Handle the key press event + * + * @param event The key event + */ + void _handleKeyPress(std::shared_ptr &event); + + /** + * @brief Handle the key release event + * + * @param event The key event + */ + void _handleKeyRelease(std::shared_ptr &event); + + /** + * @brief Convert the key press data + * + * @param type The type of the key + * @param code The code of the key + * @return The converted key press data + */ + components::IKeyboardComponent::KeyData _convertKeyPressData(events::IKeyEvent::KeyType type, events::IKeyEvent::KeyCode code); + + /** + * @brief Handle the mouse button press event + * + * @param event The mouse button event + */ + void _handleSoundComponent(std::shared_ptr &component); +}; diff --git a/core/src/exception/CMakeLists.txt b/core/src/exception/CMakeLists.txt index 7f3f3dc..36668bd 100644 --- a/core/src/exception/CMakeLists.txt +++ b/core/src/exception/CMakeLists.txt @@ -1,3 +1,4 @@ -target_sources(${CMAKE_PROJECT_NAME} PRIVATE +target_sources(arcade PRIVATE ArcadeError.cpp + ArcadeError.hpp ) diff --git a/core/src/loader/CMakeLists.txt b/core/src/loader/CMakeLists.txt index 99592b3..65d16a2 100644 --- a/core/src/loader/CMakeLists.txt +++ b/core/src/loader/CMakeLists.txt @@ -1,3 +1,4 @@ -target_sources(${CMAKE_PROJECT_NAME} PRIVATE +target_sources(arcade PRIVATE Loader.cpp + Loader.hpp ) diff --git a/core/src/loader/Loader.cpp b/core/src/loader/Loader.cpp index 97bbd9d..6ad23e5 100644 --- a/core/src/loader/Loader.cpp +++ b/core/src/loader/Loader.cpp @@ -13,14 +13,14 @@ Loader::Loader() {} Loader::~Loader() {} -shared::types::LibraryType Loader::_getLibraryGetter(const std::string &filepath, std::shared_ptr &dlLoader) { +shared::types::LibraryType Loader::_getLibraryGetter(const std::string &filepath, std::shared_ptr dlLoader) { shared::types::LibraryTypeGetter getter = nullptr; getter = dlLoader->loadSymbol(SHARED_STRINGIFY(SHARED_LIBRARY_TYPE_GETTER_NAME)); return getter(); } -void Loader::_loadGameLibrary(const std::string &filepath, std::shared_ptr &dlLoader) { +void Loader::_loadGameLibrary(const std::string &filepath, std::shared_ptr dlLoader) { shared::types::GameProviderGetter game = nullptr; game = dlLoader->loadSymbol(SHARED_STRINGIFY(SHARED_GAME_PROVIDER_GETTER_NAME)); @@ -28,7 +28,7 @@ void Loader::_loadGameLibrary(const std::string &filepath, std::shared_ptr_libraries.push_back(dlLoader); } -void Loader::_loadGraphicsLibrary(const std::string &filepath, std::shared_ptr &dlLoader) { +void Loader::_loadGraphicsLibrary(const std::string &filepath, std::shared_ptr dlLoader) { shared::types::GraphicsProviderGetter graphics = nullptr; graphics = dlLoader->loadSymbol(SHARED_STRINGIFY(SHARED_GRAPHICS_PROVIDER_GETTER_NAME)); @@ -56,10 +56,10 @@ void Loader::loadLibraries(std::string path) { } } -const GameProviders &Loader::getGamesLibraries() const { +GameProviders &Loader::getGamesLibraries() { return this->_gamesLibraries; } -const GraphicsProviders &Loader::getGraphicsLibraries() const { +GraphicsProviders &Loader::getGraphicsLibraries() { return this->_graphicsLibraries; } diff --git a/core/src/loader/Loader.hpp b/core/src/loader/Loader.hpp index deed716..9bcc4b9 100644 --- a/core/src/loader/Loader.hpp +++ b/core/src/loader/Loader.hpp @@ -13,7 +13,6 @@ class Loader { public: - /** * @brief Construct a new Loader object */ @@ -40,13 +39,13 @@ class Loader { * @brief Get all games libraries * @return Loaded games libraries */ - const GameProviders &getGamesLibraries() const; + GameProviders &getGamesLibraries(); /** * @brief Get all graphics libraries * @return Loaded graphics libraries */ - const GraphicsProviders &getGraphicsLibraries() const; + GraphicsProviders &getGraphicsLibraries(); private: const std::string _path; @@ -60,21 +59,21 @@ class Loader { * @param loader DLLoader * @return getter function */ - shared::types::LibraryType _getLibraryGetter(const std::string &filepath, std::shared_ptr &loader); + shared::types::LibraryType _getLibraryGetter(const std::string &filepath, std::shared_ptr loader); /** * @brief Load a game library * @param filepath file path of the library * @param loader DLLoader */ - void _loadGameLibrary(const std::string &filepath, std::shared_ptr &loader); + void _loadGameLibrary(const std::string &filepath, std::shared_ptr loader); /** * @brief Load a graphics library * @param filepath file path of the library * @param loader DLLoader */ - void _loadGraphicsLibrary(const std::string &filepath, std::shared_ptr &loader); + void _loadGraphicsLibrary(const std::string &filepath, std::shared_ptr loader); /** * @brief Throw an error when loading a library diff --git a/core/src/types/CMakeLists.txt b/core/src/types/CMakeLists.txt new file mode 100644 index 0000000..3904d4b --- /dev/null +++ b/core/src/types/CMakeLists.txt @@ -0,0 +1,3 @@ +target_sources(arcade PRIVATE + Providers.hpp +) diff --git a/core/src/types/Providers.hpp b/core/src/types/Providers.hpp index c40fb9e..518f976 100644 --- a/core/src/types/Providers.hpp +++ b/core/src/types/Providers.hpp @@ -9,5 +9,5 @@ #include "shared/types/Libraries.hpp" -typedef std::vector> GameProviders; -typedef std::vector> GraphicsProviders; +typedef std::vector> GameProviders; +typedef std::vector> GraphicsProviders; diff --git a/core/src/utils/DLLoader/CMakeLists.txt b/core/src/utils/DLLoader/CMakeLists.txt index 00db786..7b85e37 100644 --- a/core/src/utils/DLLoader/CMakeLists.txt +++ b/core/src/utils/DLLoader/CMakeLists.txt @@ -1,3 +1,3 @@ -target_sources(${CMAKE_PROJECT_NAME} PRIVATE +target_sources(arcade PRIVATE DLLoader.cpp ) diff --git a/graphics/CMakeLists.txt b/graphics/CMakeLists.txt index c166dc2..2715642 100644 --- a/graphics/CMakeLists.txt +++ b/graphics/CMakeLists.txt @@ -1 +1,2 @@ -add_subdirectory(ncurses) +#add_subdirectory(ncurses) +add_subdirectory(sfml) diff --git a/graphics/common/CMakeLists.txt b/graphics/common/CMakeLists.txt new file mode 100644 index 0000000..a655d16 --- /dev/null +++ b/graphics/common/CMakeLists.txt @@ -0,0 +1,3 @@ +add_subdirectory(events) +add_subdirectory(exceptions) +target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_LIST_DIR}/../..) diff --git a/graphics/common/events/CMakeLists.txt b/graphics/common/events/CMakeLists.txt new file mode 100644 index 0000000..b6abb48 --- /dev/null +++ b/graphics/common/events/CMakeLists.txt @@ -0,0 +1,3 @@ +add_subdirectory(mouse) +add_subdirectory(key) +add_subdirectory(window) diff --git a/graphics/common/events/key/AKeyEvent.hpp b/graphics/common/events/key/AKeyEvent.hpp new file mode 100644 index 0000000..b428723 --- /dev/null +++ b/graphics/common/events/key/AKeyEvent.hpp @@ -0,0 +1,46 @@ +/* +** EPITECH PROJECT, 2024 +** arcade +** File description: +** AKeyEvent.hpp +*/ + +#pragma once + +#include "shared/graphics/events/IKeyEvent.hpp" + +using namespace shared::graphics::events; + +namespace arcade::graphics::common::events { + template + concept KeyEventType = T == EventType::KEY_PRESS || T == EventType::KEY_RELEASE; + + template requires KeyEventType + class AKeyEvent; +} + +using namespace arcade::graphics::common::events; + +template requires KeyEventType +class arcade::graphics::common::events::AKeyEvent: public IKeyEvent { +public: + ~AKeyEvent() override = default; + + EventType getType() const noexcept override { + return T; + } + + const KeyCode getKeyCode() const noexcept override { + return _code; + } + + const KeyType getKeyType() const noexcept override { + return _keyType; + } + +protected: + AKeyEvent(const KeyType keyType, const KeyCode code) : _keyType(keyType), _code(code) {}; + + const KeyType _keyType; + const KeyCode _code; +}; diff --git a/graphics/common/events/key/CMakeLists.txt b/graphics/common/events/key/CMakeLists.txt new file mode 100644 index 0000000..ea02f33 --- /dev/null +++ b/graphics/common/events/key/CMakeLists.txt @@ -0,0 +1,6 @@ +target_sources(${PROJECT_NAME} PUBLIC + AKeyEvent.hpp + KeyPressEvent.hpp + KeyReleaseEvent.hpp + key.hpp +) diff --git a/graphics/common/events/key/KeyPressEvent.hpp b/graphics/common/events/key/KeyPressEvent.hpp new file mode 100644 index 0000000..f1655a0 --- /dev/null +++ b/graphics/common/events/key/KeyPressEvent.hpp @@ -0,0 +1,21 @@ +/* +** EPITECH PROJECT, 2024 +** arcade +** File description: +** KeyPressEvent.hpp +*/ + +#pragma once + +#include "AKeyEvent.hpp" + +namespace arcade::graphics::common::events { + class KeyPressEvent; +} + +class arcade::graphics::common::events::KeyPressEvent: public AKeyEvent { +public: + explicit KeyPressEvent(const KeyType type, const KeyCode code = { .character = 0 }) + : AKeyEvent(type, code) {}; + ~KeyPressEvent() override = default; +}; diff --git a/graphics/common/events/key/KeyReleaseEvent.hpp b/graphics/common/events/key/KeyReleaseEvent.hpp new file mode 100644 index 0000000..7b868b5 --- /dev/null +++ b/graphics/common/events/key/KeyReleaseEvent.hpp @@ -0,0 +1,20 @@ +/* +** EPITECH PROJECT, 2024 +** arcade +** File description: +** KeyPressEvent.hpp +*/ + +#pragma once + +#include "AKeyEvent.hpp" + +namespace arcade::graphics::common::events { + class KeyReleaseEvent; +} + +class arcade::graphics::common::events::KeyReleaseEvent: public AKeyEvent { +public: + KeyReleaseEvent(const KeyType type, const KeyCode code) : AKeyEvent(type, code) {}; + ~KeyReleaseEvent() override = default; +}; diff --git a/graphics/common/events/key/key.hpp b/graphics/common/events/key/key.hpp new file mode 100644 index 0000000..4702d1c --- /dev/null +++ b/graphics/common/events/key/key.hpp @@ -0,0 +1,11 @@ +/* +** EPITECH PROJECT, 2024 +** arcade +** File description: +** mouse.hpp +*/ + +#pragma once + +#include "KeyPressEvent.hpp" +#include "KeyReleaseEvent.hpp" diff --git a/graphics/common/events/mouse/AMouseButtonEvent.hpp b/graphics/common/events/mouse/AMouseButtonEvent.hpp new file mode 100644 index 0000000..0071cb0 --- /dev/null +++ b/graphics/common/events/mouse/AMouseButtonEvent.hpp @@ -0,0 +1,52 @@ +/* +** EPITECH PROJECT, 2024 +** arcade +** File description: +** AMouseEvent.hpp +*/ + +#pragma once + +#include "AMouseEvent.hpp" +#include "shared/graphics/events/IMouseButtonEvent.hpp" + +using namespace shared::graphics::events; +using namespace shared::types; +using namespace arcade::graphics::common::events; + +namespace arcade::graphics::common::events { + template + concept MouseButtonEventType = T == EventType::MOUSE_BTN_PRESS || T == EventType::MOUSE_BTN_RELEASE; + + template requires MouseButtonEventType + class AMouseButtonEvent; +} + +template requires MouseButtonEventType +class arcade::graphics::common::events::AMouseButtonEvent: public AMouseEvent, public virtual IMouseButtonEvent { +public: + /** + * @brief Construct a new AMouseButtonEvent object + * + * @param pos Position of the mouse + * @param button Targeted button + */ + explicit AMouseButtonEvent( + Vector2i pos, + MouseButton button + ): AMouseEvent(pos), _button(button) {}; + + ~AMouseButtonEvent() override = default; + + /** + * @brief Get the button object + * + * @return Target button type + */ + const MouseButton getButton() const noexcept override { + return _button; + } + +protected: + const MouseButton _button; +}; diff --git a/graphics/common/events/mouse/AMouseEvent.hpp b/graphics/common/events/mouse/AMouseEvent.hpp new file mode 100644 index 0000000..2bf413a --- /dev/null +++ b/graphics/common/events/mouse/AMouseEvent.hpp @@ -0,0 +1,42 @@ +/* +** EPITECH PROJECT, 2024 +** arcade +** File description: +** AMouseEvent.hpp +*/ + +#pragma once + +#include "shared/graphics/events/IMouseEvent.hpp" + +using namespace shared::graphics::events; +using namespace shared::types; + +namespace arcade::graphics::common::events { + template + class AMouseEvent; +} + +template +class arcade::graphics::common::events::AMouseEvent: public virtual IMouseEvent { +public: + ~AMouseEvent() override = default; + + EventType getType() const noexcept override { + return T; + } + + const Vector2i getPosition() const noexcept override { + return _pos; + } + +protected: + /** + * @brief Construct a new AMouseEvent object + * + * @param pos Position of the mouse + */ + explicit AMouseEvent(Vector2i pos): _pos(pos){}; + + Vector2i _pos; +}; diff --git a/graphics/common/events/mouse/CMakeLists.txt b/graphics/common/events/mouse/CMakeLists.txt new file mode 100644 index 0000000..23a780a --- /dev/null +++ b/graphics/common/events/mouse/CMakeLists.txt @@ -0,0 +1,8 @@ +target_sources(${PROJECT_NAME} PUBLIC + AMouseEvent.hpp + MouseButtonPressEvent.hpp + MouseButtonReleaseEvent.hpp + AMouseButtonEvent.hpp + MouseMoveEvent.hpp + mouse.hpp +) diff --git a/graphics/common/events/mouse/MouseButtonPressEvent.hpp b/graphics/common/events/mouse/MouseButtonPressEvent.hpp new file mode 100644 index 0000000..f2865c2 --- /dev/null +++ b/graphics/common/events/mouse/MouseButtonPressEvent.hpp @@ -0,0 +1,24 @@ +/* +** EPITECH PROJECT, 2024 +** arcade +** File description: +** MouseButtonPressEvent.hpp +*/ + +#pragma once + +#include "AMouseButtonEvent.hpp" + +using namespace shared::graphics::events; +using namespace arcade::graphics::common::events; + +namespace arcade::graphics::common::events { + class MouseButtonPressEvent; +}; + +class arcade::graphics::common::events::MouseButtonPressEvent : + public AMouseButtonEvent { +public: + MouseButtonPressEvent(Vector2i pos, MouseButton button) : AMouseButtonEvent(pos, button){}; + ~MouseButtonPressEvent() override = default; +}; diff --git a/graphics/common/events/mouse/MouseButtonReleaseEvent.hpp b/graphics/common/events/mouse/MouseButtonReleaseEvent.hpp new file mode 100644 index 0000000..98638e6 --- /dev/null +++ b/graphics/common/events/mouse/MouseButtonReleaseEvent.hpp @@ -0,0 +1,23 @@ +/* +** EPITECH PROJECT, 2024 +** arcade +** File description: +** MouseButtonPressEvent.hpp +*/ + +#pragma once + +#include "AMouseButtonEvent.hpp" + +using namespace shared::graphics::events; +using namespace arcade::graphics::common::events; + +namespace arcade::graphics::common::events { + class MouseButtonReleaseEvent; +}; + +class arcade::graphics::common::events::MouseButtonReleaseEvent : + public AMouseButtonEvent { +public: + using AMouseButtonEvent::AMouseButtonEvent; +}; diff --git a/graphics/common/events/mouse/MouseMoveEvent.hpp b/graphics/common/events/mouse/MouseMoveEvent.hpp new file mode 100644 index 0000000..76cefef --- /dev/null +++ b/graphics/common/events/mouse/MouseMoveEvent.hpp @@ -0,0 +1,24 @@ +/* +** EPITECH PROJECT, 2024 +** arcade +** File description: +** AMouseEvent.hpp +*/ + +#pragma once + +#include "AMouseEvent.hpp" + +using namespace shared::graphics::events; +using namespace shared::types; + +namespace arcade::graphics::common::events { + class MouseMoveEvent; +} + +class arcade::graphics::common::events::MouseMoveEvent: public AMouseEvent { +public: + explicit MouseMoveEvent(const Vector2i pos): AMouseEvent(pos) {} + + ~MouseMoveEvent() override = default; +}; diff --git a/graphics/common/events/mouse/mouse.hpp b/graphics/common/events/mouse/mouse.hpp new file mode 100644 index 0000000..662df31 --- /dev/null +++ b/graphics/common/events/mouse/mouse.hpp @@ -0,0 +1,12 @@ +/* +** EPITECH PROJECT, 2024 +** arcade +** File description: +** mouse.hpp +*/ + +#pragma once + +#include "MouseButtonPressEvent.hpp" +#include "MouseButtonReleaseEvent.hpp" +#include "MouseMoveEvent.hpp" diff --git a/graphics/common/events/window/CMakeLists.txt b/graphics/common/events/window/CMakeLists.txt new file mode 100644 index 0000000..103c201 --- /dev/null +++ b/graphics/common/events/window/CMakeLists.txt @@ -0,0 +1,5 @@ +target_sources(${PROJECT_NAME} PUBLIC + WindowCloseEvent.hpp + WindowResizeEvent.hpp + window.hpp +) diff --git a/graphics/common/events/window/WindowCloseEvent.hpp b/graphics/common/events/window/WindowCloseEvent.hpp new file mode 100644 index 0000000..1ad3100 --- /dev/null +++ b/graphics/common/events/window/WindowCloseEvent.hpp @@ -0,0 +1,27 @@ +/* +** EPITECH PROJECT, 2024 +** arcade +** File description: +** WindowCloseEvent.hpp +*/ + +#pragma once + +#include "shared/graphics/events/IEvent.hpp" + +using namespace shared::graphics::events; + +namespace arcade::graphics::common::events { + class WindowCloseEvent; +} + + +class arcade::graphics::common::events::WindowCloseEvent: public IEvent { +public: + WindowCloseEvent() = default; + ~WindowCloseEvent() override = default; + + EventType getType() const noexcept override { + return WINDOW_CLOSE; + } +}; diff --git a/graphics/common/events/window/WindowResizeEvent.hpp b/graphics/common/events/window/WindowResizeEvent.hpp new file mode 100644 index 0000000..da75768 --- /dev/null +++ b/graphics/common/events/window/WindowResizeEvent.hpp @@ -0,0 +1,27 @@ +/* +** EPITECH PROJECT, 2024 +** arcade +** File description: +** WindowCloseEvent.hpp +*/ + +#pragma once + +#include "shared/graphics/events/IEvent.hpp" + +using namespace shared::graphics::events; + +namespace arcade::graphics::common::events { + class WindowResizeEvent; +} + + +class arcade::graphics::common::events::WindowResizeEvent: public IEvent { +public: + WindowResizeEvent() = default; + ~WindowResizeEvent() override = default; + + EventType getType() const noexcept override { + return WINDOW_RESIZE; + } +}; diff --git a/graphics/common/events/window/window.hpp b/graphics/common/events/window/window.hpp new file mode 100644 index 0000000..7edf622 --- /dev/null +++ b/graphics/common/events/window/window.hpp @@ -0,0 +1,11 @@ +/* +** EPITECH PROJECT, 2024 +** arcade +** File description: +** window.hpp +*/ + +#pragma once + +#include "WindowCloseEvent.hpp" +#include "WindowResizeEvent.hpp" diff --git a/graphics/common/exceptions/CMakeLists.txt b/graphics/common/exceptions/CMakeLists.txt new file mode 100644 index 0000000..82dcf6d --- /dev/null +++ b/graphics/common/exceptions/CMakeLists.txt @@ -0,0 +1,8 @@ +target_sources(${PROJECT_NAME} PUBLIC + GraphicsException.cpp + GraphicsException.hpp + SoundException.hpp + TextureException.hpp + WindowException.hpp + FontException.hpp +) diff --git a/graphics/common/exceptions/FontException.hpp b/graphics/common/exceptions/FontException.hpp new file mode 100644 index 0000000..0039eb0 --- /dev/null +++ b/graphics/common/exceptions/FontException.hpp @@ -0,0 +1,22 @@ +/* +** EPITECH PROJECT, 2024 +** arcade +** File description: +** FontException.hpp +*/ + +#pragma once + +#include "GraphicsException.hpp" +#include "shared/graphics/exceptions/IFontException.hpp" + +using namespace shared::graphics::exceptions; + +namespace arcade::graphics::common::exceptions { + class FontException; +} + +class arcade::graphics::common::exceptions::FontException: public GraphicsException, public IFontException { +public: + using GraphicsException::GraphicsException; +}; diff --git a/graphics/common/exceptions/GraphicsException.cpp b/graphics/common/exceptions/GraphicsException.cpp new file mode 100644 index 0000000..5e1da56 --- /dev/null +++ b/graphics/common/exceptions/GraphicsException.cpp @@ -0,0 +1,24 @@ +/* +** EPITECH PROJECT, 2024 +** arcade +** File description: +** GraphicsException.cpp +*/ + +#include "GraphicsException.hpp" + +using namespace arcade::graphics::common::exceptions; + +GraphicsException::GraphicsException(const std::string &message, const std::string &where) +{ + this->_message = message; + this->_where = where; +} + +const char *GraphicsException::what() const noexcept { + return this->_message.c_str(); +} + +const char *GraphicsException::where() const noexcept { + return this->_where.c_str(); +} diff --git a/graphics/common/exceptions/GraphicsException.hpp b/graphics/common/exceptions/GraphicsException.hpp new file mode 100644 index 0000000..5cff65a --- /dev/null +++ b/graphics/common/exceptions/GraphicsException.hpp @@ -0,0 +1,31 @@ +/* +** EPITECH PROJECT, 2024 +** arcade +** File description: +** GraphicsException.hpp +*/ + +#pragma once + +#include +#include "shared/graphics/exceptions/IGraphicsException.hpp" + +using namespace shared::graphics::exceptions; + +namespace arcade::graphics::common::exceptions { + class GraphicsException; +} + +class arcade::graphics::common::exceptions::GraphicsException : public virtual IGraphicsException { +public: + GraphicsException(const std::string &message, const std::string &where); + ~GraphicsException() override = default; + + const char *what() const noexcept override; + + const char *where() const noexcept override; + +protected: + std::string _message; + std::string _where; +}; diff --git a/graphics/common/exceptions/SoundException.hpp b/graphics/common/exceptions/SoundException.hpp new file mode 100644 index 0000000..4518994 --- /dev/null +++ b/graphics/common/exceptions/SoundException.hpp @@ -0,0 +1,22 @@ +/* +** EPITECH PROJECT, 2024 +** arcade +** File description: +** SoundException.hpp +*/ + +#pragma once + +#include "GraphicsException.hpp" +#include "shared/graphics/exceptions/ISoundException.hpp" + +using namespace shared::graphics::exceptions; + +namespace arcade::graphics::common::exceptions { + class SoundException; +} + +class arcade::graphics::common::exceptions::SoundException: public GraphicsException, public ISoundException { +public: + using GraphicsException::GraphicsException; +}; diff --git a/graphics/common/exceptions/TextureException.hpp b/graphics/common/exceptions/TextureException.hpp new file mode 100644 index 0000000..187fe00 --- /dev/null +++ b/graphics/common/exceptions/TextureException.hpp @@ -0,0 +1,22 @@ +/* +** EPITECH PROJECT, 2024 +** arcade +** File description: +** TextureException.hpp +*/ + +#pragma once + +#include "GraphicsException.hpp" +#include "shared/graphics/exceptions/ITextureException.hpp" + +using namespace shared::graphics::exceptions; + +namespace arcade::graphics::common::exceptions { + class TextureException; +} + +class arcade::graphics::common::exceptions::TextureException: public GraphicsException, public ITextureException { +public: + using GraphicsException::GraphicsException; +}; diff --git a/graphics/common/exceptions/WindowException.hpp b/graphics/common/exceptions/WindowException.hpp new file mode 100644 index 0000000..e3ab418 --- /dev/null +++ b/graphics/common/exceptions/WindowException.hpp @@ -0,0 +1,22 @@ +/* +** EPITECH PROJECT, 2024 +** arcade +** File description: +** WindowException.hpp +*/ + +#pragma once + +#include "GraphicsException.hpp" +#include "shared/graphics/exceptions/IWindowException.hpp" + +using namespace shared::graphics::exceptions; + +namespace arcade::graphics::common::exceptions { + class WindowException; +} + +class arcade::graphics::common::exceptions::WindowException: public GraphicsException, public IWindowException { +public: + using GraphicsException::GraphicsException; +}; diff --git a/graphics/sfml/CMakeLists.txt b/graphics/sfml/CMakeLists.txt new file mode 100644 index 0000000..9a4ffd1 --- /dev/null +++ b/graphics/sfml/CMakeLists.txt @@ -0,0 +1,25 @@ +project(sfml) +add_library(sfml SHARED + export.cpp + src/GraphicsProvider.cpp + src/GraphicsProvider.hpp + src/window/Window.cpp + src/window/Window.hpp + src/window/EventsHandler.cpp + src/window/EventsHandler.hpp + src/sound/Sound.cpp + src/sound/Sound.hpp + src/texture/Texture.cpp + src/texture/Texture.hpp + src/font/Font.cpp + src/font/Font.hpp + src/window/Renderer.cpp + src/window/Renderer.hpp +) +add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/../common PRIVATE) + +target_include_directories(sfml PUBLIC ${CMAKE_CURRENT_LIST_DIR}/src) +target_include_directories(sfml PUBLIC ${CMAKE_CURRENT_LIST_DIR}/../..) +target_include_directories(sfml PUBLIC ${CMAKE_CURRENT_LIST_DIR}/..) + +target_link_libraries(sfml sfml-graphics sfml-window sfml-system sfml-audio) diff --git a/graphics/sfml/export.cpp b/graphics/sfml/export.cpp new file mode 100644 index 0000000..4373075 --- /dev/null +++ b/graphics/sfml/export.cpp @@ -0,0 +1,26 @@ +/* +** EPITECH PROJECT, 2024 +** arcade-shared +** File description: +** export +*/ + +#include "shared/games/IGameProvider.hpp" +#include "shared/types/Libraries.hpp" +#include "src/GraphicsProvider.hpp" + +using namespace arcade::graphics; +using namespace shared::graphics; +using namespace shared::types; + +extern "C" { + LibraryType SHARED_LIBRARY_TYPE_GETTER_NAME(void) + { + return LibraryType::GRAPHIC; + } + + IGraphicsProvider *SHARED_GRAPHICS_PROVIDER_GETTER_NAME(void) + { + return new sfml::GraphicsProvider(); + } +} diff --git a/graphics/sfml/src/GraphicsProvider.cpp b/graphics/sfml/src/GraphicsProvider.cpp new file mode 100644 index 0000000..20031d4 --- /dev/null +++ b/graphics/sfml/src/GraphicsProvider.cpp @@ -0,0 +1,57 @@ +/* +** EPITECH PROJECT, 2024 +** GraphicsProvider.cpp +** File description: +** GraphicsProvider class +*/ + +#include +#include "GraphicsProvider.hpp" +#include "utils/compiler.hpp" +#include "window/Window.hpp" +#include "font/Font.hpp" +#include "sound/Sound.hpp" +#include "texture/Texture.hpp" + +using namespace shared::graphics; +using namespace arcade::graphics::sfml; + +const shared::graphics::GraphicsManifest GraphicsProvider::_manifest = { + .name = "sfml", + .description = "SFML Library", + .version = "1.0", + .authors = { + { + .name = "tekmath", + .email = "matheo.coquet@epitech.eu", + .website = "thismath.com" + }, + { + .name = "Flavien Chenu", + .email = "flavien.chenu@epitech.eu", + .website = "https://github.com/flavien-chenu" + } + } +}; + +GraphicsProvider::GraphicsProvider() = default; + +const GraphicsManifest &GraphicsProvider::getManifest() const noexcept { + return GraphicsProvider::_manifest; +} + +std::unique_ptr GraphicsProvider::createWindow(const IWindow::WindowInitProps &props) { + return std::make_unique(props); +} + +std::shared_ptr GraphicsProvider::createSound(const std::string &path) { + return std::make_shared(path); +} + +std::shared_ptr GraphicsProvider::createTexture(const std::string &bin, unused const std::string &ascii) { + return std::make_shared(bin); +} + +std::shared_ptr GraphicsProvider::createFont(const std::string &path) { + return std::make_shared(path); +} diff --git a/graphics/sfml/src/GraphicsProvider.hpp b/graphics/sfml/src/GraphicsProvider.hpp new file mode 100644 index 0000000..e9ff58d --- /dev/null +++ b/graphics/sfml/src/GraphicsProvider.hpp @@ -0,0 +1,68 @@ +/* +** EPITECH PROJECT, 2024 +** GraphicsProvider.hpp +** File description: +** GraphicsProvider class +*/ + +#pragma once + +#include "shared/graphics/ITexture.hpp" +#include "shared/graphics/IGraphicsProvider.hpp" + +using namespace shared::graphics; + +namespace arcade::graphics::sfml +{ + class GraphicsProvider; +} + +class arcade::graphics::sfml::GraphicsProvider : public shared::graphics::IGraphicsProvider +{ +public: + GraphicsProvider(); + ~GraphicsProvider() override = default; + + /** + * @brief Get the manifest of the graphics library + * + * @return Manifest of the graphics library + */ + const shared::graphics::GraphicsManifest &getManifest() const noexcept override; + + /** + * @brief Create a renderer object + * + * @param windowProps Properties to use to init the window + * @return Created renderer object + */ + std::unique_ptr createWindow(const IWindow::WindowInitProps &windowProps) override; + + /** + * @brief Create a sound object + * + * @param path Path of the sound file + * @return Created sound object + */ + std::shared_ptr createSound(const std::string &path) override; + + /** + * @brief Create a texture object + * + * @param bin Path of the binary texture file + * @param ascii Path of the ascii texture file + * @return Created texture object + */ + std::shared_ptr createTexture(const std::string &bin, const std::string &ascii) override; + + /** + * @brief Create a font object + * + * @param path Path of the font file + * @return Created font object + */ + std::shared_ptr createFont(const std::string &path) override; + +protected: + static const shared::graphics::GraphicsManifest _manifest; +}; diff --git a/graphics/sfml/src/font/Font.cpp b/graphics/sfml/src/font/Font.cpp new file mode 100644 index 0000000..ce8b063 --- /dev/null +++ b/graphics/sfml/src/font/Font.cpp @@ -0,0 +1,26 @@ +/* +** EPITECH PROJECT, 2024 +** arcade +** File description: +** Font.cpp +*/ + +#include "Font.hpp" +#include "common/exceptions/FontException.hpp" + +using namespace arcade::graphics::sfml::font; +using namespace arcade::graphics::common::exceptions; + +Font::Font(const std::string &path) +{ + if (!_font.loadFromFile(path)) + throw FontException( + "Failed to load font at: " + path, + "Font constructor in SFML library" + ); +} + +sf::Font &Font::getInnerFont() +{ + return _font; +} diff --git a/graphics/sfml/src/font/Font.hpp b/graphics/sfml/src/font/Font.hpp new file mode 100644 index 0000000..1460376 --- /dev/null +++ b/graphics/sfml/src/font/Font.hpp @@ -0,0 +1,32 @@ +/* +** EPITECH PROJECT, 2024 +** arcade +** File description: +** Font.hpp +*/ + +#pragma once + +#include +#include +#include "shared/graphics/IFont.hpp" +#include "utils/compiler.hpp" + +namespace arcade::graphics::sfml::font { + class Font; +} + +class arcade::graphics::sfml::font::Font : public shared::graphics::IFont { +public: + explicit Font(const std::string &path); + ~Font() override = default; + + /** + * @brief Get the inner SFML font + * @return Reference to the inner SFML font + */ + sf::Font &getInnerFont(); + +private: + sf::Font _font; +}; diff --git a/graphics/sfml/src/sound/Sound.cpp b/graphics/sfml/src/sound/Sound.cpp new file mode 100644 index 0000000..c53a4ed --- /dev/null +++ b/graphics/sfml/src/sound/Sound.cpp @@ -0,0 +1,63 @@ +/* +** EPITECH PROJECT, 2024 +** arcade +** File description: +** Sound.cpp +*/ + +#include "Sound.hpp" +#include "common/exceptions/SoundException.hpp" + +using namespace arcade::graphics::sfml::sound; +using namespace arcade::graphics::common::exceptions; + +Sound::Sound(const std::string &path, SoundState state) { + if(!_buffer.loadFromFile(path)) { + throw SoundException( + "Failed to load sound at: " + path, + "Sound constructor in SFML library" + ); + } + _sound.setBuffer(_buffer); + _sound.stop(); +} + +Sound::SoundVolume Sound::getVolume() const { + return static_cast(_sound.getVolume()); +} + +void Sound::setVolume(SoundVolume volume) { + _sound.setVolume(volume); +} + +void Sound::setState(SoundState state) { + switch (state) { + case PLAY: + return _sound.play(); + case PAUSE: + return _sound.pause(); + case STOP: + return _sound.stop(); + } +} + +Sound::SoundState Sound::getState() const { + auto state = _sound.getStatus(); + + switch (state) { + case sf::Sound::Playing: + return PLAY; + case sf::Sound::Paused: + return PAUSE; + default: + return STOP; + } +} + +void Sound::setLoopState(bool loop) { + _sound.setLoop(loop); +} + +bool Sound::getLoopState() const { + return _sound.getLoop(); +} diff --git a/graphics/sfml/src/sound/Sound.hpp b/graphics/sfml/src/sound/Sound.hpp new file mode 100644 index 0000000..ed69710 --- /dev/null +++ b/graphics/sfml/src/sound/Sound.hpp @@ -0,0 +1,34 @@ +/* +** EPITECH PROJECT, 2024 +** arcade +** File description: +** Sound.hpp +*/ + +#pragma once + +#include +#include + +#include "shared/graphics/ISound.hpp" + +namespace arcade::graphics::sfml::sound { + class Sound; +} + +class arcade::graphics::sfml::sound::Sound : public shared::graphics::ISound { +public: + explicit Sound(const std::string &path, SoundState state = STOP); + ~Sound() override = default; + + SoundVolume getVolume() const override; + SoundState getState() const override; + void setVolume(SoundVolume volume) override; + void setState(SoundState state) override; + void setLoopState(bool loop) override; + bool getLoopState() const override; + +private: + sf::SoundBuffer _buffer; + sf::Sound _sound; +}; diff --git a/graphics/sfml/src/texture/Texture.cpp b/graphics/sfml/src/texture/Texture.cpp new file mode 100644 index 0000000..a1e4c4e --- /dev/null +++ b/graphics/sfml/src/texture/Texture.cpp @@ -0,0 +1,25 @@ +/* +** EPITECH PROJECT, 2024 +** arcade +** File description: +** Texture.cpp +*/ + +#include "Texture.hpp" +#include "common/exceptions/TextureException.hpp" + +using namespace arcade::graphics::sfml::texture; +using namespace arcade::graphics::common::exceptions; + +Texture::Texture(const std::string &path) { + if (!_texture.loadFromFile(path)) + throw TextureException( + "Failed to load texture at: " + path, + "Texture constructor in SFML library" + ); +} + +sf::Texture &Texture::getInnerTexture() +{ + return _texture; +} diff --git a/graphics/sfml/src/texture/Texture.hpp b/graphics/sfml/src/texture/Texture.hpp new file mode 100644 index 0000000..3f51e42 --- /dev/null +++ b/graphics/sfml/src/texture/Texture.hpp @@ -0,0 +1,31 @@ +/* +** EPITECH PROJECT, 2024 +** arcade +** File description: +** Texture.hpp +*/ + +#pragma once + +#include +#include +#include "shared/graphics/ITexture.hpp" + +namespace arcade::graphics::sfml::texture { + class Texture; +} + +class arcade::graphics::sfml::texture::Texture: public shared::graphics::ITexture { +public: + explicit Texture(const std::string &path); + ~Texture() override = default; + + /** + * @brief Get the inner SFML texture + * @return Reference to the inner SFML texture + */ + sf::Texture &getInnerTexture(); + +private: + sf::Texture _texture; +}; diff --git a/graphics/sfml/src/window/EventsHandler.cpp b/graphics/sfml/src/window/EventsHandler.cpp new file mode 100644 index 0000000..877a4d8 --- /dev/null +++ b/graphics/sfml/src/window/EventsHandler.cpp @@ -0,0 +1,227 @@ +/* +** EPITECH PROJECT, 2024 +** arcade +** File description: +** EventHandler.cpp +*/ + +#include + +#include "Window.hpp" +#include "EventsHandler.hpp" +#include "utils/compiler.hpp" + +using namespace arcade::graphics::sfml::window; + +EventsHandler::EventHandler EventsHandler::_getHandler(sf::Event::EventType type) { + static std::map handlers = { + {sf::Event::KeyPressed, _handleKeyPressEvent}, + {sf::Event::KeyReleased, _handleKeyReleaseEvent}, + {sf::Event::MouseButtonPressed, _handleMouseButtonPressEvent}, + {sf::Event::MouseButtonReleased, _handleMouseBtnReleaseEvent}, + {sf::Event::MouseMoved, _handleMouseMoveEvent}, + {sf::Event::Closed, _handleWindowCloseEvent}, + {sf::Event::Resized, _handleWindowResizeEvent} + }; + auto handler = handlers.find(type); + + return handler != handlers.end() ? handler->second : nullptr; +} + +EventsHandler::EventsHandler(Window &window): _window(window) {} + +std::vector EventsHandler::handleEvents() { + std::vector events; + sf::Event SFMLEvent{}; + + while (_window.getInnerWindow().pollEvent(SFMLEvent)) { + auto handler = _getHandler(SFMLEvent.type); + auto event = handler ? handler(SFMLEvent, _window) : nullptr; + + if (event) + events.push_back(event); + } + return events; +} + +bool EventsHandler::_handleControlKey( + sf::Event::KeyEvent event, + IKeyEvent::KeyCode &code +) { + switch (event.code) { + case sf::Keyboard::LControl: + case sf::Keyboard::RControl: + case sf::Keyboard::LShift: + case sf::Keyboard::RShift: + case sf::Keyboard::LAlt: + case sf::Keyboard::RAlt: + return true; + + default: + return false; + } +} + +bool EventsHandler::_handleArrowKey( + sf::Event::KeyEvent event, + IKeyEvent::KeyCode &code +) { + switch (event.code) { + case sf::Keyboard::Left: + code.arrow = IKeyEvent::ArrowCode::LEFT; + return true; + case sf::Keyboard::Right: + code.arrow = IKeyEvent::ArrowCode::RIGHT; + return true; + case sf::Keyboard::Up: + code.arrow = IKeyEvent::ArrowCode::UP; + return true; + case sf::Keyboard::Down: + code.arrow = IKeyEvent::ArrowCode::DOWN; + return true; + default: + return false; + } +} + +bool EventsHandler::_handleFunctionKey( + sf::Event::KeyEvent event, + IKeyEvent::KeyCode &code +) +{ + if (event.code >= sf::Keyboard::F1 && event.code <= sf::Keyboard::F12) { + code.func = event.code - sf::Keyboard::F1 + 1; + return true; + } else { + return false; + } +} + +bool EventsHandler::_handleCharKey( + sf::Event::KeyEvent event, + IKeyEvent::KeyCode &code +) { + static const std::map specials = { + {sf::Keyboard::Space, ' '}, + {sf::Keyboard::LBracket, '['}, + {sf::Keyboard::RBracket, ']'}, + {sf::Keyboard::Semicolon, ';'}, + {sf::Keyboard::Comma, ','}, + {sf::Keyboard::Period, '.'}, + {sf::Keyboard::Quote, '\''}, + {sf::Keyboard::Slash, '/'}, + {sf::Keyboard::Backslash, '\\'}, + {sf::Keyboard::Tilde, '~'}, + {sf::Keyboard::Equal, '='}, + {sf::Keyboard::Hyphen, '-'}, + {sf::Keyboard::Enter, '\n'}, + {sf::Keyboard::Backspace, '\b'}, + {sf::Keyboard::Tab, '\t'}, + {sf::Keyboard::Escape, 0x1B}, + {sf::Keyboard::Add, '+'}, + {sf::Keyboard::Subtract, '-'}, + {sf::Keyboard::Multiply, '*'}, + {sf::Keyboard::Divide, '/'} + }; + + if (event.code >= sf::Keyboard::A && event.code <= sf::Keyboard::Z) { + code.character = static_cast(event.code - sf::Keyboard::A + 'a'); + } else if (event.code >= sf::Keyboard::Num0 && event.code <= sf::Keyboard::Num9) { + code.character = static_cast(event.code - sf::Keyboard::Num0 + '0'); + } else if (event.code >= sf::Keyboard::Numpad0 && event.code <= sf::Keyboard::Numpad9) { + code.character = static_cast(event.code - sf::Keyboard::Numpad0 + '0'); + } else { + auto special = specials.find(event.code); + + if (special != specials.end()) { + code.character = special->second; + } else { + return false; + } + } + return true; +} + +EventPtr EventsHandler::_handleKeyPressEvent(sf::Event &event, unused Window &window) { + IKeyEvent::KeyType type = IKeyEvent::KeyType::UNKNOWN; + IKeyEvent::KeyCode code; + + if (_handleControlKey(event.key, code)) + type = IKeyEvent::KeyType::CONTROL; + else if (_handleArrowKey(event.key, code)) + type = IKeyEvent::KeyType::ARROW; + else if (_handleFunctionKey(event.key, code)) + type = IKeyEvent::KeyType::FUNC; + else if (_handleCharKey(event.key, code)) + type = IKeyEvent::KeyType::CHAR; + return std::make_shared(type, code); +} + +EventPtr EventsHandler::_handleKeyReleaseEvent( + sf::Event &event, + unused Window &window +) { + IKeyEvent::KeyType type = IKeyEvent::KeyType::UNKNOWN; + IKeyEvent::KeyCode code; + + if (_handleControlKey(event.key, code)) + type = IKeyEvent::KeyType::CONTROL; + else if (_handleArrowKey(event.key, code)) + type = IKeyEvent::KeyType::ARROW; + else if (_handleFunctionKey(event.key, code)) + type = IKeyEvent::KeyType::FUNC; + else if (_handleCharKey(event.key, code)) + type = IKeyEvent::KeyType::CHAR; + return std::make_shared(type, code); +} + +EventPtr EventsHandler::_handleWindowCloseEvent( + unused sf::Event &event, + unused Window &window +) { + return std::make_shared(); +} + +EventPtr EventsHandler::_handleWindowResizeEvent( + unused sf::Event &event, + Window &window +) { + return std::make_shared(); +} + +EventPtr EventsHandler::_handleMouseMoveEvent( + sf::Event &event, + Window &window +) { + return std::make_shared( + window.pixelsToTiles(Vector2i(event.mouseMove.x, event.mouseMove.y)) + ); +} + +EventPtr EventsHandler::_handleMouseButtonPressEvent( + sf::Event &event, + Window &window +) { + Vector2i pos = window.pixelsToTiles(Vector2i(event.mouseButton.x, event.mouseButton.y)); + + if (event.mouseButton.button == sf::Mouse::Button::Left) + return std::make_shared(pos, IMouseButtonEvent::MouseButton::LEFT); + else if (event.mouseButton.button == sf::Mouse::Button::Right) + return std::make_shared(pos, IMouseButtonEvent::MouseButton::RIGHT); + else + return nullptr; +} + +EventPtr EventsHandler::_handleMouseBtnReleaseEvent( + sf::Event &event, + unused Window &window +) { + Vector2i pos = window.pixelsToTiles(Vector2i(event.mouseButton.x, event.mouseButton.y)); + + if (event.mouseButton.button == sf::Mouse::Button::Left) + return std::make_shared(pos, IMouseButtonEvent::MouseButton::LEFT); + else if (event.mouseButton.button == sf::Mouse::Button::Right) + return std::make_shared(pos, IMouseButtonEvent::MouseButton::RIGHT); + else + return nullptr; +} diff --git a/graphics/sfml/src/window/EventsHandler.hpp b/graphics/sfml/src/window/EventsHandler.hpp new file mode 100644 index 0000000..e78132b --- /dev/null +++ b/graphics/sfml/src/window/EventsHandler.hpp @@ -0,0 +1,137 @@ +/* +** EPITECH PROJECT, 2024 +** arcade +** File description: +** EventHandler.hpp +*/ + +#pragma once + +#include +#include + +#include "common/events/window/window.hpp" +#include "common/events/mouse/mouse.hpp" +#include "common/events/key/key.hpp" + +namespace arcade::graphics::sfml::window { + class EventsHandler; + class Window; +} + +class arcade::graphics::sfml::window::EventsHandler { +public: + explicit EventsHandler(Window &window); + ~EventsHandler() = default; + + typedef EventPtr (*EventHandler)(sf::Event &event, Window &window); + + /** + * @brief Handle events from SFML + * @param window Window object + * @return Vector of events + */ + std::vector handleEvents(); + +private: + + static EventHandler _getHandler(sf::Event::EventType type); + + /** + * @brief Handle control key event if it's a control key + * @param event Event from SFML + * @param code Code of the key to set + * @return Status of handling + */ + static bool _handleControlKey(sf::Event::KeyEvent event, IKeyEvent::KeyCode &code); + + /** + * @brief Handle control key event if it's an arrow key + * @param event Event from SFML + * @param code Code of the key to set + * @return Status of handling + */ + static bool _handleArrowKey(sf::Event::KeyEvent event, IKeyEvent::KeyCode &code); + + /** + * @brief Handle control key event if it's a function key + * @param event Event from SFML + * @param code Code of the key to set + * @return Status of handling + */ + static bool _handleFunctionKey(sf::Event::KeyEvent event, IKeyEvent::KeyCode &code); + + /** + * @brief Handle control key event if it's a char key + * @param event Event from SFML + * @param code Code of the key to set + * @return Status of handling + */ + static bool _handleCharKey(sf::Event::KeyEvent event, IKeyEvent::KeyCode &code); + + /** + * @brief Handle key press event + * @param event Event from SFML + * @param window Window object + * @return Pointer to created event or null if not handled + */ + static EventPtr _handleKeyPressEvent(sf::Event &event, Window &window); + + /** + * @brief Handle key release event + * @param event Event from SFML + * @param window Window object + * @return Pointer to created event or null if not handled + */ + static EventPtr _handleKeyReleaseEvent(sf::Event &event, Window &window); + + /** + * @brief Handle mouse button press event + * @param event Event from SFML + * @param window Window object + * @return Pointer to created event or null if not handled + */ + static EventPtr _handleMouseButtonPressEvent(sf::Event &event, Window &window); + + /** + * @brief Handle mouse button release event + * @param event Event from SFML + * @param window Window object + * @return Pointer to created event or null if not handled + */ + static EventPtr _handleMouseBtnReleaseEvent(sf::Event &event, Window &window); + + /** + * @brief Handle mouse move event + * @param event Event from SFML + * @param window Window object + * @return Pointer to created event or null if not handled + */ + static EventPtr _handleMouseMoveEvent(sf::Event &event, Window &window); + + /** + * @brief Handle window close event + * @param event Event from SFML + * @param window Window object + * @return Pointer to created event or null if not handled + */ + static EventPtr _handleWindowCloseEvent(sf::Event &event, Window &window); + + /** + * @brief Handle window resize event + * @param event Event from SFML + * @param window Window object + * @return Pointer to created event or null if not handled + */ + static EventPtr _handleWindowResizeEvent(sf::Event &event, Window &window); + + /** + * @brief Resolve position of the event to convert it in tiles unit + * @param position Position to resolve + * @param window Window object of which relate the position + * @return Resolved position + */ + static Vector2i _resolvePosition(Vector2i position, Window &window); + + window::Window &_window; +}; diff --git a/graphics/sfml/src/window/Renderer.cpp b/graphics/sfml/src/window/Renderer.cpp new file mode 100644 index 0000000..3ba9489 --- /dev/null +++ b/graphics/sfml/src/window/Renderer.cpp @@ -0,0 +1,135 @@ +/* +** EPITECH PROJECT, 2024 +** arcade +** File description: +** Renderer.cpp +*/ + +#include "Window.hpp" +#include "Renderer.hpp" +#include "font/Font.hpp" +#include "texture/Texture.hpp" +#include "common/exceptions/WindowException.hpp" + +using namespace arcade::graphics::sfml::window; +using namespace arcade::graphics::common::exceptions; + +Renderer::Renderer(Window &window) : _window(window), _layer(_window.getInnerWindow()) { + _text.setFont(sf::Font()); + _sprite.setTexture(sf::Texture()); +} + +void Renderer::render(const shared::graphics::TextProps &props) { + auto font = _castOrThrow(props.font); + auto entityPosition = _entityPixelsPosition(props.position); + auto entitySize = _window.tilesToPixels(props.size); + + _reset(_text); + _text.setFont(font->getInnerFont()); + _text.setString(props.content); + _text.setCharacterSize(props.fontSize); + _text.setFillColor(sf::Color( + props.color.r, + props.color.g, + props.color.b, + props.color.a) + ); + _text.setPosition(entityPosition.x, entityPosition.y); + _textAlign(props.align, entitySize); + _textVerticalAlign(props.verticalAlign, entitySize); + _textAdjustPosition(); + _layer.draw(_text); +} + +void +Renderer::_textVerticalAlign(const shared::graphics::TextVerticalAlign &align, const shared::types::Vector2i &entitySize +) { + auto bounds = _text.getGlobalBounds(); + auto position = _text.getPosition(); + + if (align == shared::graphics::MIDDLE) { + position.y += (static_cast(entitySize.y) - bounds.height) / 2; + } else if (align == shared::graphics::BOTTOM) { + position.y += static_cast(entitySize.y) - bounds.height; + } + _text.setPosition(position); +} + +void Renderer::_textAlign(const shared::graphics::TextAlign &align, const shared::types::Vector2i &entitySize) { + auto bounds = _text.getGlobalBounds(); + auto position = _text.getPosition(); + + if (align == shared::graphics::CENTER) { + position.x += (static_cast(entitySize.x) - bounds.width) / 2; + } else if (align == shared::graphics::RIGHT) { + position.x += static_cast(entitySize.x) - bounds.width; + } + _text.setPosition(position); +} + +void Renderer::_textAdjustPosition() { + auto actual = _text.getPosition(); + sf::FloatRect bounds; + + _text.setPosition(0, 0); + bounds = _text.getGlobalBounds(); + _text.setPosition(actual.x - bounds.left, actual.y - bounds.top); +} + +void Renderer::render(const shared::graphics::TextureProps &props) { + auto texture = _castOrThrow(props.texture); + auto entityPosition = _entityPixelsPosition(props.position); + + _reset(_sprite); + _sprite.setTexture(texture->getInnerTexture()); + _sprite.setPosition(entityPosition.x, entityPosition.y); + _setTextureRectAndScale(props); + _layer.draw(_sprite); +} + +void Renderer::_setTextureRectAndScale(const shared::graphics::TextureProps &props) { + auto size = _window.tilesToPixels(props.size); + float width = static_cast(props.size.x) * props.binTileSize.x; + float height = static_cast(props.size.y) * props.binTileSize.y; + float left = static_cast(props.origin.x) * props.binTileSize.x; + float top = static_cast(props.origin.y) * props.binTileSize.y; + sf::IntRect rectangle = { + static_cast(left), + static_cast(top), + static_cast(width), + static_cast(height) + }; + + _sprite.setTextureRect(rectangle); + _sprite.setScale( + static_cast(size.x) / width, + static_cast(size.y) / height + ); +} + +void Renderer::_reset(sf::Text &text) { + text.setString(""); + text.setCharacterSize(0); + text.setFillColor(sf::Color::White); + text.setStyle(sf::Text::Regular); + text.setPosition(0, 0); + text.setScale(1, 1); + text.setOrigin(0, 0); +} + +void Renderer::_reset(sf::Sprite &sprite) { + sprite.setTextureRect(sf::IntRect(0, 0, 0, 0)); + sprite.setColor(sf::Color::White); + sprite.setScale(1, 1); + sprite.setPosition(0, 0); + sprite.setOrigin(0, 0); +} + +Vector2f Renderer::_entityPixelsPosition(const Vector2i &position) { + auto pixels = _window.tilesToPixels(position); + + return { + static_cast(pixels.x), + static_cast(pixels.y) + }; +} diff --git a/graphics/sfml/src/window/Renderer.hpp b/graphics/sfml/src/window/Renderer.hpp new file mode 100644 index 0000000..21c4998 --- /dev/null +++ b/graphics/sfml/src/window/Renderer.hpp @@ -0,0 +1,112 @@ +/* +** EPITECH PROJECT, 2024 +** arcade +** File description: +** Renderer.hpp +*/ + +#pragma once + +#include +#include "shared/graphics/ITexture.hpp" +#include "shared/graphics/types/TextureProps.hpp" +#include "shared/graphics/types/TextProps.hpp" +#include "common/exceptions/WindowException.hpp" + +namespace arcade::graphics::sfml::window { + class Renderer; + + class Window; +} + +class arcade::graphics::sfml::window::Renderer { +public: + explicit Renderer(Window &window); + + ~Renderer() = default; + + /** + * @brief Render a texture on the window + * @param props Texture properties + */ + void render(const shared::graphics::TextureProps &props); + + /** + * @brief Render a text on the window + * @param props Text properties + */ + void render(const shared::graphics::TextProps &props); + +private: + Window &_window; + sf::RenderWindow &_layer; + sf::Text _text; + sf::Sprite _sprite; + + /** + * @brief Reset the text properties + * @param text Text to reset + */ + static void _reset(sf::Text &text); + + /** + * @brief Reset the sprite properties + * @param sprite Sprite to reset + */ + static void _reset(sf::Sprite &sprite); + + /** + * @brief Convert a tile position to pixel position + * @param position Tile position + * @return Pixel position + */ + Vector2f _entityPixelsPosition(const Vector2i &position); + + /** + * @brief Align vertically the text + * @param align Text alignment + * @param entityPos Entity position + * @param entitySize Entity size + */ + void _textVerticalAlign( + const shared::graphics::TextVerticalAlign &align, + const shared::types::Vector2i &entitySize + ); + + /** + * @brief Align the text + * @param align Text alignment + * @param entitySize Entity size + */ + void _textAlign(const shared::graphics::TextAlign &align, const shared::types::Vector2i &entitySize); + + /** + * @brief Adjust the text position + */ + void _textAdjustPosition(); + + /** + * @brief Set texture rect depending on the texture properties + * @param props Texture properties + */ + void _setTextureRectAndScale(const shared::graphics::TextureProps &props); + + /** + * @brief Cast a shared pointer from a type to another + * @tparam From Type from which to cast + * @tparam To Type to which cast + * @param from Value to cast + * @return Casted value + */ + template + static std::shared_ptr _castOrThrow(std::shared_ptr from) { + std::shared_ptr to = std::dynamic_pointer_cast(from); + if (!to) { + throw common::exceptions::WindowException( + "Failed to cast shared pointer of:" + std::string(typeid(from).name()) + " to " + typeid(to).name(), + "SFML Library Renderer::_castOrThrow" + ); + } + return to; + }; +}; diff --git a/graphics/sfml/src/window/Window.cpp b/graphics/sfml/src/window/Window.cpp new file mode 100644 index 0000000..c63269e --- /dev/null +++ b/graphics/sfml/src/window/Window.cpp @@ -0,0 +1,171 @@ +/* +** EPITECH PROJECT, 2024 +** Window.cpp +** File description: +** Window class +*/ + +#include "Window.hpp" +#include "EventsHandler.hpp" +#include "common/events/mouse/mouse.hpp" +#include "common/exceptions/WindowException.hpp" + +using namespace arcade::graphics::sfml::window; +using namespace arcade::graphics::common::exceptions; + +const Vector2u Window::tileSize = { 12, 12 }; + +Window::Window(const IWindow::WindowInitProps &props): + _size(props.size), + _renderer(*this), + _eventsHandler(*this) +{ + auto size = _getPixelSizeFromTiles(props.size); + + _mode = props.mode; + _fps = props.fps; + _window.create( + sf::VideoMode(size.x, size.y), + props.title + ); + Window::setIcon(props.icon); +} + +Window::~Window() +{ + _window.close(); +} + +sf::RenderWindow &Window::getInnerWindow() noexcept { + return _window; +} + +void Window::setTitle(const std::string &title) { + _window.setTitle(title); +} + +void Window::setSize(shared::types::Vector2u size) { + auto real = _getPixelSizeFromTiles(size); + + _size = size; + _window.setSize(sf::Vector2u(real.x, real.y)); +} + +shared::types::Vector2u Window::getSize() const { + return _size; +} + +void Window::setFramerateLimit(unsigned int fps) { + _window.setFramerateLimit(fps); + _fps = fps; +} + +unsigned int Window::getFramerateLimit() const { + return _fps; +} + +void Window::setMode(IWindow::WindowMode mode) { + auto size = _window.getSize(); + + this->_mode = mode; + if (mode == FULLSCREEN) { + _window.create( + sf::VideoMode(size.x, size.y), + this->_title, + sf::Style::Fullscreen + ); + } else { + _window.create( + sf::VideoMode(size.x, size.y), + this->_title, + sf::Style::Default + ); + } +} + +Window::WindowMode Window::getMode() const { + return _mode; +} + +bool Window::isOpen() const { + return _window.isOpen(); +} + +void Window::setIcon(const std::string &path) { + if (path.empty()) + return; + if (!_icon.loadFromFile(path)) { + throw WindowException( + "Failed to load icon at: " + path, + "Window.setIcon in SFML library" + ); + } + _window.setIcon( + _icon.getSize().x, + _icon.getSize().y, + _icon.getPixelsPtr() + ); +} + +void Window::render(const shared::graphics::TextureProps &props) { + _renderer.render(props); +} + +void Window::render(const shared::graphics::TextProps &props) { + _renderer.render(props); +} + +void Window::clear() { + _window.clear(); +} + +void Window::display() { + _window.display(); +} + +void Window::close() { + _window.close(); +} + +std::vector Window::getEvents() { + return _eventsHandler.handleEvents(); +} + +Vector2u Window::_getPixelSizeFromTiles(const Vector2u &size) { + auto mode = sf::VideoMode::getDesktopMode(); + Vector2u real(mode.width, mode.height); + + if (size.x * static_cast(tileSize.x) < mode.width) + real.x = size.x * static_cast(tileSize.x); + if (size.y * static_cast(tileSize.y) < mode.height) + real.y = size.y * static_cast(tileSize.y); + return real; +} + +Vector2i Window::pixelsToTiles(const shared::types::Vector2i &position) const { + auto realSize = _window.getSize(); + + return { + static_cast(position.x * _size.x / realSize.x), + static_cast(position.y * _size.y / realSize.y) + }; +} + +Vector2i Window::tilesToPixels(const Vector2i &position) const { + auto realSize = _window.getSize(); + + return { + static_cast(position.x * realSize.x / _size.x), + static_cast(position.y * realSize.y / _size.y) + }; +} + +Vector2i Window::tilesToPixels(const Vector2u &position) const { + auto realSize = _window.getSize(); + + return { + static_cast(position.x * realSize.x / _size.x), + static_cast(position.y * realSize.y / _size.y) + }; +} + diff --git a/graphics/sfml/src/window/Window.hpp b/graphics/sfml/src/window/Window.hpp new file mode 100644 index 0000000..5ff6fdd --- /dev/null +++ b/graphics/sfml/src/window/Window.hpp @@ -0,0 +1,171 @@ +/* +** EPITECH PROJECT, 2024 +** Window.hpp +** File description: +** Window class +*/ + +#pragma once + +#include +#include "Renderer.hpp" +#include "shared/graphics/IWindow.hpp" +#include "EventsHandler.hpp" + +namespace arcade::graphics::sfml::window { + class Window; +} + +class arcade::graphics::sfml::window::Window: public shared::graphics::IWindow { +public: + explicit Window(const WindowInitProps &props); + ~Window() override; + + /** + * @brief Set the title of current window + * + * @param title Title of the window + */ + void setTitle(const std::string &title) override; + + /** + * @brief Set the size of the window + * + * @param size Size of the window + */ + void setSize(Vector2u size) override; + + /** + * @brief Get the size of the window + * + * @return Size of the window + */ + Vector2u getSize() const override; + + /** + * @brief Set the framerate Limit of the window + * + * @param fps Frame per seconds + */ + void setFramerateLimit(unsigned int fps) override; + + /** + * @brief Get the framerate Limit of the window + * + * @return Frame per seconds + */ + unsigned int getFramerateLimit() const override; + + /** + * @brief Set the mode of the window + * + * @param mode Mode to apply to the window + */ + void setMode(IWindow::WindowMode mode) override; + + /** + * @brief Get the mode of the window + * + * @return Mode of the window + */ + WindowMode getMode() const override; + + /** + * @brief Set the icon of the window + * + * @param icon Icon to use + */ + void setIcon(const std::string &icon) override; + + /** + * @brief Render the text with given properties + * + * @param props Properties of the entity to render + */ + void render(const shared::graphics::TextProps &props) override; + + /** + * @brief Render the entity with given properties + * + * @param props Properties of the entity to render + */ + void render(const shared::graphics::TextureProps &props) override; + + /** + * @brief Clear the content of the window + * + */ + void clear() override; + + /** + * @brief Display the content of the window + * + */ + void display() override; + + /** + * @brief Close the window + * + */ + void close() override; + + /** + * @brief Check if the window is open + * + * @return Open status of the window + */ + bool isOpen() const override; + + /** + * @brief Get the events object + * + * @return Last events occurred + * @warning Call successively this method will result in losing events + * @note Call `A` return `eventsA` containing 2 events, + * but make another call `B` (directly after call `A`) `eventsB` + * will result to an empty vector + */ + std::vector getEvents() override; + + /** + * @brief Get the window object + * @return Window object + */ + sf::RenderWindow &getInnerWindow() noexcept; + + /** + * @brief Convert a position in pixels to a position in tiles + * @return Converted position + */ + Vector2i pixelsToTiles(const Vector2i &position) const; + + /** + * @brief Convert a position in tiles to a position in pixels + * @return Converted position + */ + Vector2i tilesToPixels(const Vector2i &position) const; + + /** + * @brief Convert a position in tiles to a position in pixels + * @return Converted position + */ + Vector2i tilesToPixels(const Vector2u &position) const; + + /** + * @brief Get the size of a tile + * @return Size of a tile + */ + static const Vector2u tileSize; + +private: + static Vector2u _getPixelSizeFromTiles(const Vector2u &size); + + EventsHandler _eventsHandler; + Renderer _renderer; + sf::RenderWindow _window; + std::string _title; + unsigned int _fps; + WindowMode _mode; + sf::Image _icon; + Vector2u _size; +}; diff --git a/utils/compiler.hpp b/utils/compiler.hpp new file mode 100644 index 0000000..5a59f81 --- /dev/null +++ b/utils/compiler.hpp @@ -0,0 +1,10 @@ +/* +** EPITECH PROJECT, 2024 +** arcade +** File description: +** compiler.hpp +*/ + +#pragma once + +#define unused __attribute__((unused)) From 78c5eaef85aeeafddb61fb209f361b588a812118 Mon Sep 17 00:00:00 2001 From: Matheo Coquet Date: Tue, 2 Apr 2024 17:21:48 +0200 Subject: [PATCH 22/33] fix(snake): fix collidable interactions --- CMakeLists.txt | 2 +- core/src/Core.cpp | 2 +- games/common/components/CollidableComponent.cpp | 3 ++- games/snake/src/SnakeGame.cpp | 2 +- games/snake/src/entities/snake/HeadEntity.cpp | 2 +- 5 files changed, 6 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 99d4b74..b23028f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,4 +13,4 @@ set(CMAKE_SHARED_LIBRARY_PREFIX "arcade_") add_subdirectory(core) add_subdirectory(games) -#[[add_subdirectory(graphics)]] +add_subdirectory(graphics) diff --git a/core/src/Core.cpp b/core/src/Core.cpp index 48f4526..6cb8600 100644 --- a/core/src/Core.cpp +++ b/core/src/Core.cpp @@ -391,7 +391,7 @@ void Core::run() this->_initWindow(); while (this->_window->isOpen()) { auto currentTime = std::chrono::high_resolution_clock::now(); - auto deltaTime = std::chrono::duration_cast(previousTime - currentTime); + auto deltaTime = std::chrono::duration_cast(currentTime - previousTime); previousTime = currentTime; this->_game->compute(deltaTime); diff --git a/games/common/components/CollidableComponent.cpp b/games/common/components/CollidableComponent.cpp index be4687e..65c0d81 100644 --- a/games/common/components/CollidableComponent.cpp +++ b/games/common/components/CollidableComponent.cpp @@ -16,5 +16,6 @@ CollidableComponent::CollidableComponent(shared::games::entity::IEntity &entity, void CollidableComponent::onCollide(std::shared_ptr ctx, std::shared_ptr target) { - return this->_collideFunction(ctx, target); + if (this->_collideFunction) + this->_collideFunction(ctx, target); } diff --git a/games/snake/src/SnakeGame.cpp b/games/snake/src/SnakeGame.cpp index 1cc0da5..0122aea 100644 --- a/games/snake/src/SnakeGame.cpp +++ b/games/snake/src/SnakeGame.cpp @@ -55,7 +55,7 @@ void snake::SnakeGame::compute(shared::games::DeltaTime dt) { if (this->_looseGame) { return this->_loose(); } - if (this->_clock > std::chrono::milliseconds(300) + this->_snake->lastMove) { + if (this->_clock > std::chrono::milliseconds(100) + this->_snake->lastMove) { this->_snake->lastMove = this->_clock; this->_snake->head->forward(); diff --git a/games/snake/src/entities/snake/HeadEntity.cpp b/games/snake/src/entities/snake/HeadEntity.cpp index 373feac..1fe2d31 100644 --- a/games/snake/src/entities/snake/HeadEntity.cpp +++ b/games/snake/src/entities/snake/HeadEntity.cpp @@ -56,7 +56,7 @@ void arcade::games::snake::HeadEntity::forward() { textureCmp->getTextureProps().origin.x = 2; if (this->direction.x > 0) textureCmp->getTextureProps().origin.x += 1; - if (this->direction.y < 0) + if (this->direction.y > 0) textureCmp->getTextureProps().origin.x += 1; std::cout << textureCmp->getTextureProps().origin.x << std::endl; } From 3eabb216b8a208552c88891f426ff968db6d68f3 Mon Sep 17 00:00:00 2001 From: Yann Date: Tue, 2 Apr 2024 17:26:42 +0200 Subject: [PATCH 23/33] fix(dlloader): clear list on Loader --- core/src/loader/DLLoader.cpp | 0 core/src/loader/Loader.cpp | 5 ++++- 2 files changed, 4 insertions(+), 1 deletion(-) delete mode 100644 core/src/loader/DLLoader.cpp diff --git a/core/src/loader/DLLoader.cpp b/core/src/loader/DLLoader.cpp deleted file mode 100644 index e69de29..0000000 diff --git a/core/src/loader/Loader.cpp b/core/src/loader/Loader.cpp index 6ad23e5..09c0e4a 100644 --- a/core/src/loader/Loader.cpp +++ b/core/src/loader/Loader.cpp @@ -11,7 +11,10 @@ Loader::Loader() {} -Loader::~Loader() {} +Loader::~Loader() { + this->_gamesLibraries.clear(); + this->_graphicsLibraries.clear(); +} shared::types::LibraryType Loader::_getLibraryGetter(const std::string &filepath, std::shared_ptr dlLoader) { shared::types::LibraryTypeGetter getter = nullptr; From 38c7f7ca081d08041d6a9a84836753f8c0a9a403 Mon Sep 17 00:00:00 2001 From: Matheo Coquet Date: Tue, 2 Apr 2024 17:55:21 +0200 Subject: [PATCH 24/33] fix(snake): fix loose event --- games/snake/src/SnakeGame.cpp | 1 + games/snake/src/entities/snake/HeadEntity.cpp | 8 ++++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/games/snake/src/SnakeGame.cpp b/games/snake/src/SnakeGame.cpp index 0122aea..5b82634 100644 --- a/games/snake/src/SnakeGame.cpp +++ b/games/snake/src/SnakeGame.cpp @@ -83,6 +83,7 @@ void snake::SnakeGame::_loose() { for (auto &tail: this->_snake->getTails()) { this->_registerEntity(tail); } + this->_looseGame = false; } void snake::SnakeGame::setLooseGame(bool state) { diff --git a/games/snake/src/entities/snake/HeadEntity.cpp b/games/snake/src/entities/snake/HeadEntity.cpp index 1fe2d31..70b3930 100644 --- a/games/snake/src/entities/snake/HeadEntity.cpp +++ b/games/snake/src/entities/snake/HeadEntity.cpp @@ -66,11 +66,11 @@ void arcade::games::snake::HeadEntity::_onCollide(std::shared_ptr target) { auto game = std::dynamic_pointer_cast(ctx); - if ( - !dynamic_cast(&target->getEntity()) || - !dynamic_cast(&target->getEntity()) || - !game) + if (!dynamic_cast(&target->getEntity()) && !dynamic_cast(&target->getEntity())) return; + if (!game) + return; + std::cout << "Collide" << std::endl; game->setLooseGame(true); } From 2ef9f6aac4d228816111c4346b0dad2d1ea32fb1 Mon Sep 17 00:00:00 2001 From: Yann Date: Tue, 2 Apr 2024 23:30:17 +0200 Subject: [PATCH 25/33] fix(sfml): add sfml view in order to be 100% responsive --- graphics/sfml/src/GraphicsProvider.cpp | 5 ++++ graphics/sfml/src/window/EventsHandler.cpp | 1 + graphics/sfml/src/window/Renderer.cpp | 27 +++++++++++++++------- graphics/sfml/src/window/Renderer.hpp | 9 +++++++- graphics/sfml/src/window/Window.cpp | 24 ++++++++++++++++--- graphics/sfml/src/window/Window.hpp | 16 +++++++++++-- 6 files changed, 68 insertions(+), 14 deletions(-) diff --git a/graphics/sfml/src/GraphicsProvider.cpp b/graphics/sfml/src/GraphicsProvider.cpp index 20031d4..97e842e 100644 --- a/graphics/sfml/src/GraphicsProvider.cpp +++ b/graphics/sfml/src/GraphicsProvider.cpp @@ -30,6 +30,11 @@ const shared::graphics::GraphicsManifest GraphicsProvider::_manifest = { .name = "Flavien Chenu", .email = "flavien.chenu@epitech.eu", .website = "https://github.com/flavien-chenu" + }, + { + .name = "Yann Masson", + .email = "yann.masson@epitech.eu", + .website = "yannmasson.fr" } } }; diff --git a/graphics/sfml/src/window/EventsHandler.cpp b/graphics/sfml/src/window/EventsHandler.cpp index 877a4d8..3ecab0c 100644 --- a/graphics/sfml/src/window/EventsHandler.cpp +++ b/graphics/sfml/src/window/EventsHandler.cpp @@ -186,6 +186,7 @@ EventPtr EventsHandler::_handleWindowResizeEvent( unused sf::Event &event, Window &window ) { + window.viewResize(event); return std::make_shared(); } diff --git a/graphics/sfml/src/window/Renderer.cpp b/graphics/sfml/src/window/Renderer.cpp index 3ba9489..5b93ce3 100644 --- a/graphics/sfml/src/window/Renderer.cpp +++ b/graphics/sfml/src/window/Renderer.cpp @@ -21,8 +21,8 @@ Renderer::Renderer(Window &window) : _window(window), _layer(_window.getInnerWin void Renderer::render(const shared::graphics::TextProps &props) { auto font = _castOrThrow(props.font); - auto entityPosition = _entityPixelsPosition(props.position); - auto entitySize = _window.tilesToPixels(props.size); + auto entityPosition = _entityPixels(props.position); + auto entitySize = _entityPixels(props.size); _reset(_text); _text.setFont(font->getInnerFont()); @@ -78,7 +78,7 @@ void Renderer::_textAdjustPosition() { void Renderer::render(const shared::graphics::TextureProps &props) { auto texture = _castOrThrow(props.texture); - auto entityPosition = _entityPixelsPosition(props.position); + auto entityPosition = _entityPixels(props.position); _reset(_sprite); _sprite.setTexture(texture->getInnerTexture()); @@ -88,7 +88,7 @@ void Renderer::render(const shared::graphics::TextureProps &props) { } void Renderer::_setTextureRectAndScale(const shared::graphics::TextureProps &props) { - auto size = _window.tilesToPixels(props.size); + auto size = _entityPixels(props.size); float width = static_cast(props.size.x) * props.binTileSize.x; float height = static_cast(props.size.y) * props.binTileSize.y; float left = static_cast(props.origin.x) * props.binTileSize.x; @@ -125,11 +125,22 @@ void Renderer::_reset(sf::Sprite &sprite) { sprite.setOrigin(0, 0); } -Vector2f Renderer::_entityPixelsPosition(const Vector2i &position) { - auto pixels = _window.tilesToPixels(position); +Vector2f Renderer::_entityPixels(const Vector2i &position) { + auto realSize = this->_window.getSize(); + Vector2u originalPixels = this->_window.getPixelSizeFromTiles(realSize); return { - static_cast(pixels.x), - static_cast(pixels.y) + static_cast(position.x * originalPixels.x / realSize.x), + static_cast(position.y * originalPixels.y / realSize.y) + }; +} + +Vector2i Renderer::_entityPixels(const Vector2u &position) { + auto realSize = this->_window.getSize(); + Vector2u originalPixels = this->_window.getPixelSizeFromTiles(realSize); + + return { + static_cast(position.x * originalPixels.x / realSize.x), + static_cast(position.y * originalPixels.y / realSize.y) }; } diff --git a/graphics/sfml/src/window/Renderer.hpp b/graphics/sfml/src/window/Renderer.hpp index 21c4998..e7f989c 100644 --- a/graphics/sfml/src/window/Renderer.hpp +++ b/graphics/sfml/src/window/Renderer.hpp @@ -60,7 +60,14 @@ class arcade::graphics::sfml::window::Renderer { * @param position Tile position * @return Pixel position */ - Vector2f _entityPixelsPosition(const Vector2i &position); + Vector2f _entityPixels(const Vector2i &position); + + /** + * @brief Convert a pixel position to tile position + * @param position Pixel position + * @return Tile position + */ + Vector2i _entityPixels(const Vector2u &position); /** * @brief Align vertically the text diff --git a/graphics/sfml/src/window/Window.cpp b/graphics/sfml/src/window/Window.cpp index c63269e..1734c92 100644 --- a/graphics/sfml/src/window/Window.cpp +++ b/graphics/sfml/src/window/Window.cpp @@ -20,7 +20,7 @@ Window::Window(const IWindow::WindowInitProps &props): _renderer(*this), _eventsHandler(*this) { - auto size = _getPixelSizeFromTiles(props.size); + auto size = getPixelSizeFromTiles(props.size); _mode = props.mode; _fps = props.fps; @@ -29,6 +29,8 @@ Window::Window(const IWindow::WindowInitProps &props): props.title ); Window::setIcon(props.icon); + _view.setSize(size.x, size.y); + _view.setCenter(size.x / 2, size.y / 2); } Window::~Window() @@ -45,7 +47,7 @@ void Window::setTitle(const std::string &title) { } void Window::setSize(shared::types::Vector2u size) { - auto real = _getPixelSizeFromTiles(size); + auto real = getPixelSizeFromTiles(size); _size = size; _window.setSize(sf::Vector2u(real.x, real.y)); @@ -131,7 +133,7 @@ std::vector Window::getEvents() { return _eventsHandler.handleEvents(); } -Vector2u Window::_getPixelSizeFromTiles(const Vector2u &size) { +Vector2u Window::getPixelSizeFromTiles(const Vector2u &size) { auto mode = sf::VideoMode::getDesktopMode(); Vector2u real(mode.width, mode.height); @@ -169,3 +171,19 @@ Vector2i Window::tilesToPixels(const Vector2u &position) const { }; } +void Window::viewResize(const sf::Event &event) { + Vector2u orignalPixels = getPixelSizeFromTiles(_size); + float widht = event.size.width; + float height = event.size.height; + + _view.setSize(event.size.width, event.size.height); + _view.setCenter(orignalPixels.x / 2, orignalPixels.y / 2); + if (widht < height) { + auto zoom = static_cast(orignalPixels.x) / event.size.width; + _view.zoom(zoom); + } else { + auto zoom = static_cast(orignalPixels.y) / event.size.height; + _view.zoom(zoom); + } + _window.setView(_view); +} diff --git a/graphics/sfml/src/window/Window.hpp b/graphics/sfml/src/window/Window.hpp index 5ff6fdd..b1f97ab 100644 --- a/graphics/sfml/src/window/Window.hpp +++ b/graphics/sfml/src/window/Window.hpp @@ -157,9 +157,20 @@ class arcade::graphics::sfml::window::Window: public shared::graphics::IWindow { */ static const Vector2u tileSize; -private: - static Vector2u _getPixelSizeFromTiles(const Vector2u &size); + /** + * @brief Resize the view of the window + * @param event Event from SFML + */ + void viewResize(const sf::Event &event); + /** + * @brief Get the size of the window in pixels + * @param size Size of the window in tiles + * @return Size of the window in pixels + */ + static Vector2u getPixelSizeFromTiles(const Vector2u &size); + +private: EventsHandler _eventsHandler; Renderer _renderer; sf::RenderWindow _window; @@ -168,4 +179,5 @@ class arcade::graphics::sfml::window::Window: public shared::graphics::IWindow { WindowMode _mode; sf::Image _icon; Vector2u _size; + sf::View _view; }; From 348923676affc06c98017d670addc5fad88caf54 Mon Sep 17 00:00:00 2001 From: Yann Date: Wed, 3 Apr 2024 08:44:05 +0200 Subject: [PATCH 26/33] fix(sfml): fix oxygen description --- graphics/sfml/src/window/Renderer.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/graphics/sfml/src/window/Renderer.hpp b/graphics/sfml/src/window/Renderer.hpp index e7f989c..f7db849 100644 --- a/graphics/sfml/src/window/Renderer.hpp +++ b/graphics/sfml/src/window/Renderer.hpp @@ -63,9 +63,9 @@ class arcade::graphics::sfml::window::Renderer { Vector2f _entityPixels(const Vector2i &position); /** - * @brief Convert a pixel position to tile position - * @param position Pixel position - * @return Tile position + * @brief Convert a tile size to pixel size + * @param size Tile size + * @return Pixel size */ Vector2i _entityPixels(const Vector2u &position); From 57d9d33de9c6876257b32000060c8640781215db Mon Sep 17 00:00:00 2001 From: Matheo Coquet Date: Wed, 3 Apr 2024 12:40:31 +0200 Subject: [PATCH 27/33] feat(snake): add background --- games/snake/CMakeLists.txt | 2 + games/snake/src/SnakeGame.cpp | 2 + .../entities/background/BackgroundEntity.cpp | 43 +++++++++++++++++++ .../entities/background/BackgroundEntity.hpp | 35 +++++++++++++++ games/snake/src/entities/wall/WallEntity.cpp | 2 +- 5 files changed, 83 insertions(+), 1 deletion(-) create mode 100644 games/snake/src/entities/background/BackgroundEntity.cpp create mode 100644 games/snake/src/entities/background/BackgroundEntity.hpp diff --git a/games/snake/CMakeLists.txt b/games/snake/CMakeLists.txt index 7a828e8..3e27f8b 100644 --- a/games/snake/CMakeLists.txt +++ b/games/snake/CMakeLists.txt @@ -13,6 +13,8 @@ add_library(${PROJECT_NAME} SHARED src/entities/snake/components/HeadKeyboardComponent.hpp src/entities/wall/WallEntity.cpp src/entities/wall/WallEntity.hpp + src/entities/background/BackgroundEntity.cpp + src/entities/background/BackgroundEntity.hpp ) add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/../common PRIVATE) target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_LIST_DIR}/src) diff --git a/games/snake/src/SnakeGame.cpp b/games/snake/src/SnakeGame.cpp index 5b82634..ab3a262 100644 --- a/games/snake/src/SnakeGame.cpp +++ b/games/snake/src/SnakeGame.cpp @@ -8,6 +8,7 @@ #include #include "SnakeGame.hpp" #include "entities/wall/WallEntity.hpp" +#include "entities/background/BackgroundEntity.hpp" #include "common/components/TextureComponent.hpp" #include "entities/snake/components/HeadKeyboardComponent.hpp" @@ -40,6 +41,7 @@ snake::SnakeGame::SnakeGame() : common::AGame(Vector2u(20, 20), 60) { } this->_registerEntity(std::make_unique(Vector2u(20, 20))); + this->_registerEntity(std::make_unique(Vector2u(20, 20))); this->_clock = std::chrono::milliseconds(0); this->_looseGame = false; diff --git a/games/snake/src/entities/background/BackgroundEntity.cpp b/games/snake/src/entities/background/BackgroundEntity.cpp new file mode 100644 index 0000000..3a35c04 --- /dev/null +++ b/games/snake/src/entities/background/BackgroundEntity.cpp @@ -0,0 +1,43 @@ +/* +** EPITECH PROJECT, 2024 +** BackgroundEntity.cpp +** File description: +** BackgroundEntity class +*/ + +#include "BackgroundEntity.hpp" +#include "common/components/TextureComponent.hpp" + +using namespace arcade::games::snake; +using namespace arcade::games::common::components; + +arcade::games::snake::BackgroundEntity::BackgroundEntity(shared::types::Vector2u size) { + unsigned int textureOriginX = 1; + unsigned int textureOriginY = 1; + + for (std::size_t x = 1; x < size.x - 1; x++) { + for (std::size_t y = 1; y < size.y - 1; y++) { + this->_addColor(Vector2i(x, y), Vector2u(textureOriginY, 0)); + textureOriginY = textureOriginY == 1 ? 2 : 1; + } + textureOriginX = textureOriginX == 1 ? 2 : 1; + textureOriginY = textureOriginX; + } +} + +void arcade::games::snake::BackgroundEntity::_addColor(shared::types::Vector2i position, shared::types::Vector2u origin) { + shared::games::components::TextureProps textureProps = { + .sources = { + .ascii = "assets/snake/wall.ascii", + .bin = "assets/snake/wall.png", + .binTileSize = Vector2f(40, 40) + }, + .origin = origin + }; + std::shared_ptr texture = std::make_shared(*this, Vector2u(1, 1), 2, + textureProps); + + texture->getPosition().x = position.x; + texture->getPosition().y = position.y; + this->_components.push_back(texture); +} diff --git a/games/snake/src/entities/background/BackgroundEntity.hpp b/games/snake/src/entities/background/BackgroundEntity.hpp new file mode 100644 index 0000000..4c75ac3 --- /dev/null +++ b/games/snake/src/entities/background/BackgroundEntity.hpp @@ -0,0 +1,35 @@ +/* +** EPITECH PROJECT, 2024 +** WallEntity.hpp +** File description: +** WallEntity class +*/ + +#pragma once + +#include +#include "common/entity/AEntity.hpp" +#include "shared/types/Vector.hpp" + +namespace arcade::games::snake { + class BackgroundEntity; +} + +class arcade::games::snake::BackgroundEntity : public common::AEntity { +public: + ~BackgroundEntity() override = default; + + /** + * @brief Create a background to the game + * @param size Size of the game + */ + explicit BackgroundEntity(shared::types::Vector2u size); + +protected: + /** + * @brief Add a color to the background (create a texture composent) + * @param position Position of the wall + * @param origin Origin of the texture + */ + void _addColor(shared::types::Vector2i position, shared::types::Vector2u origin); +}; diff --git a/games/snake/src/entities/wall/WallEntity.cpp b/games/snake/src/entities/wall/WallEntity.cpp index 1822855..229e4e0 100644 --- a/games/snake/src/entities/wall/WallEntity.cpp +++ b/games/snake/src/entities/wall/WallEntity.cpp @@ -38,7 +38,7 @@ void WallEntity::_createWall(shared::types::Vector2i position) { .origin = Vector2u(0, 0) }; std::shared_ptr collision = std::make_shared(*this, nullptr); - std::shared_ptr texture = std::make_shared(*this, Vector2u(1, 1), 10, + std::shared_ptr texture = std::make_shared(*this, Vector2u(1, 1), 1, textureProps); collision->getPosition().x = position.x; From 918d08a4fdb0e37da8a84ca3a0c0e409861e3193 Mon Sep 17 00:00:00 2001 From: Matheo Coquet Date: Wed, 3 Apr 2024 13:06:32 +0200 Subject: [PATCH 28/33] feat(snake): add systeme of tail --- games/snake/src/SnakeGame.cpp | 16 ++++---------- games/snake/src/entities/snake/HeadEntity.cpp | 14 +++++++------ games/snake/src/entities/snake/HeadEntity.hpp | 7 ++++++- games/snake/src/entities/snake/Snake.cpp | 21 ++++++++++++++++--- games/snake/src/entities/snake/Snake.hpp | 7 +++++++ games/snake/src/entities/snake/TailEntity.cpp | 18 +++++++++++++++- games/snake/src/entities/snake/TailEntity.hpp | 13 ++++++++++++ 7 files changed, 73 insertions(+), 23 deletions(-) diff --git a/games/snake/src/SnakeGame.cpp b/games/snake/src/SnakeGame.cpp index ab3a262..0894cd4 100644 --- a/games/snake/src/SnakeGame.cpp +++ b/games/snake/src/SnakeGame.cpp @@ -40,8 +40,8 @@ snake::SnakeGame::SnakeGame() : common::AGame(Vector2u(20, 20), 60) { this->_registerEntity(tail); } - this->_registerEntity(std::make_unique(Vector2u(20, 20))); - this->_registerEntity(std::make_unique(Vector2u(20, 20))); + this->_registerEntity(std::make_unique(this->getSize())); + this->_registerEntity(std::make_unique(this->getSize())); this->_clock = std::chrono::milliseconds(0); this->_looseGame = false; @@ -59,12 +59,7 @@ void snake::SnakeGame::compute(shared::games::DeltaTime dt) { } if (this->_clock > std::chrono::milliseconds(100) + this->_snake->lastMove) { this->_snake->lastMove = this->_clock; - this->_snake->head->forward(); - - // DEBUG // - auto position = std::dynamic_pointer_cast(this->_snake->head->getComponents().at(1)); - std::cout << "Snake Position [" << position->getPosition().x << ", " << position->getPosition().y << "]" << std::endl; - // END DEBUG // + this->_snake->forward(); } } @@ -78,13 +73,10 @@ void snake::SnakeGame::_loose() { }), this->_entities.end()); this->_snake->reset(); - - for (size_t i = 0; i < 2; i++) { - this->_snake->addTail(); - } for (auto &tail: this->_snake->getTails()) { this->_registerEntity(tail); } + this->_looseGame = false; } diff --git a/games/snake/src/entities/snake/HeadEntity.cpp b/games/snake/src/entities/snake/HeadEntity.cpp index 70b3930..e4a790b 100644 --- a/games/snake/src/entities/snake/HeadEntity.cpp +++ b/games/snake/src/entities/snake/HeadEntity.cpp @@ -9,14 +9,14 @@ #include "HeadEntity.hpp" #include "../wall/WallEntity.hpp" #include "components/HeadKeyboardComponent.hpp" -#include using namespace arcade::games::common::components; using namespace shared::games::components; arcade::games::snake::HeadEntity::HeadEntity() : _textureProps( arcade::games::snake::HeadEntity::_defaultTextureProps()), - direction(1, 0) { + direction(1, 0), + position(8, 4) { std::shared_ptr collide = std::make_shared(*this, HeadEntity::_onCollide); std::shared_ptr texture = std::make_shared(*this, Vector2u(1, 1), 10, this->_textureProps); @@ -41,6 +41,9 @@ shared::games::components::TextureProps arcade::games::snake::HeadEntity::_defau } void arcade::games::snake::HeadEntity::forward() { + this->position.x += this->direction.x; + this->position.y += this->direction.y; + for (auto &component: this->_components) { auto posCmp = std::dynamic_pointer_cast(component); if (posCmp == nullptr) continue; @@ -58,7 +61,6 @@ void arcade::games::snake::HeadEntity::forward() { textureCmp->getTextureProps().origin.x += 1; if (this->direction.y > 0) textureCmp->getTextureProps().origin.x += 1; - std::cout << textureCmp->getTextureProps().origin.x << std::endl; } } @@ -70,17 +72,17 @@ void arcade::games::snake::HeadEntity::_onCollide(std::shared_ptrsetLooseGame(true); } void arcade::games::snake::HeadEntity::reset() { this->direction = Vector2i(1, 0); + this->position = Vector2i(8, 4); for (auto &component: this->_components) { std::shared_ptr posCmp = std::dynamic_pointer_cast(component); if (posCmp == nullptr) continue; - posCmp->getPosition().x = 8; - posCmp->getPosition().y = 4; + posCmp->getPosition().x = this->position.x; + posCmp->getPosition().y = this->position.y; } } diff --git a/games/snake/src/entities/snake/HeadEntity.hpp b/games/snake/src/entities/snake/HeadEntity.hpp index 5b410c2..758e5a4 100644 --- a/games/snake/src/entities/snake/HeadEntity.hpp +++ b/games/snake/src/entities/snake/HeadEntity.hpp @@ -32,10 +32,15 @@ class arcade::games::snake::HeadEntity : public common::AEntity { void forward(); /** - * @brief Direction of the snake + * @brief Direction of the snake head */ Vector2i direction; + /** + * @brief Position of the snake head + */ + Vector2i position; + /** * @brief Set the head at default position */ diff --git a/games/snake/src/entities/snake/Snake.cpp b/games/snake/src/entities/snake/Snake.cpp index d995be8..81a7dfb 100644 --- a/games/snake/src/entities/snake/Snake.cpp +++ b/games/snake/src/entities/snake/Snake.cpp @@ -15,10 +15,9 @@ using namespace arcade::games::snake; Snake::Snake(unsigned int tails) { this->lastMove = std::chrono::milliseconds(0); this->head = std::make_shared(); + this->_baseTails = tails; - for (size_t i = 0; i < tails; i++) { - this->addTail(); - } + this->reset(); } Snake::~Snake() = default; @@ -34,7 +33,23 @@ std::shared_ptr Snake::addTail() { return newTail; } +void Snake::forward() { + Vector2i oldPosition = this->head->position; + Vector2i tempOldPosition = oldPosition; + + this->head->forward(); + for (auto &tail: this->_tails) { + tempOldPosition = tail->getPosition(); + tail->setPosition(oldPosition); + oldPosition = tempOldPosition; + } +} + void Snake::reset() { this->head->reset(); this->_tails.clear(); + + for (size_t i = 0; i < this->_baseTails; i++) { + this->addTail(); + } } diff --git a/games/snake/src/entities/snake/Snake.hpp b/games/snake/src/entities/snake/Snake.hpp index b34ac6b..75f5ed7 100644 --- a/games/snake/src/entities/snake/Snake.hpp +++ b/games/snake/src/entities/snake/Snake.hpp @@ -50,6 +50,11 @@ class arcade::games::snake::Snake { */ void reset(); + /** + * @brief Update the position of the snake + */ + void forward(); + shared::games::DeltaTime lastMove; protected: /** @@ -57,4 +62,6 @@ class arcade::games::snake::Snake { * */ std::vector> _tails; + + unsigned int _baseTails; }; diff --git a/games/snake/src/entities/snake/TailEntity.cpp b/games/snake/src/entities/snake/TailEntity.cpp index ad9076d..da39e93 100644 --- a/games/snake/src/entities/snake/TailEntity.cpp +++ b/games/snake/src/entities/snake/TailEntity.cpp @@ -11,7 +11,7 @@ using namespace arcade::games::common::components; using namespace shared::games::components; arcade::games::snake::TailEntity::TailEntity() : _textureProps( - arcade::games::snake::TailEntity::_defaultTextureProps()) { + arcade::games::snake::TailEntity::_defaultTextureProps()), _position(0, 0) { std::shared_ptr collide = std::make_shared(*this, nullptr); std::shared_ptr texture = std::make_shared(*this, Vector2u(1, 1), 10, this->_textureProps); @@ -29,3 +29,19 @@ shared::games::components::TextureProps arcade::games::snake::TailEntity::_defau .origin = Vector2u(0, 0) }; } + +void arcade::games::snake::TailEntity::setPosition(Vector2i position) { + this->_position = position; + + for (auto &component: this->_components) { + auto posCmp = std::dynamic_pointer_cast(component); + if (posCmp == nullptr) continue; + + posCmp->getPosition().x = position.x; + posCmp->getPosition().y = position.y; + } +} + +Vector2i arcade::games::snake::TailEntity::getPosition() { + return this->_position; +} diff --git a/games/snake/src/entities/snake/TailEntity.hpp b/games/snake/src/entities/snake/TailEntity.hpp index 1123b3d..13da0e3 100644 --- a/games/snake/src/entities/snake/TailEntity.hpp +++ b/games/snake/src/entities/snake/TailEntity.hpp @@ -21,6 +21,18 @@ class arcade::games::snake::TailEntity : public common::AEntity { explicit TailEntity(); + /** + * @brief Set position of the tail + * @param position + */ + void setPosition(Vector2i position); + + /** + * @brief Get position of the tail + * @return Vector of the position + */ + Vector2i getPosition(); + protected: /** * @brief Get default texture props @@ -29,4 +41,5 @@ class arcade::games::snake::TailEntity : public common::AEntity { static shared::games::components::TextureProps _defaultTextureProps(); shared::games::components::TextureProps _textureProps; + Vector2i _position; }; From 34a55c1b0d4854ed5bac1f52a3e61b6c630e66c4 Mon Sep 17 00:00:00 2001 From: Matheo Coquet Date: Wed, 3 Apr 2024 13:49:04 +0200 Subject: [PATCH 29/33] feat(snake): add texture rotation fot tail --- games/snake/src/SnakeGame.cpp | 2 +- games/snake/src/entities/snake/Snake.cpp | 19 +++++++++++++++++++ games/snake/src/entities/snake/TailEntity.cpp | 9 +++++++++ games/snake/src/entities/snake/TailEntity.hpp | 6 ++++++ 4 files changed, 35 insertions(+), 1 deletion(-) diff --git a/games/snake/src/SnakeGame.cpp b/games/snake/src/SnakeGame.cpp index 0894cd4..e624244 100644 --- a/games/snake/src/SnakeGame.cpp +++ b/games/snake/src/SnakeGame.cpp @@ -33,7 +33,7 @@ const shared::games::GameManifest snake::SnakeGame::manifest = { }; snake::SnakeGame::SnakeGame() : common::AGame(Vector2u(20, 20), 60) { - this->_snake = std::make_unique(2); + this->_snake = std::make_unique(5); this->_registerEntity(this->_snake->head); for (auto &tail: this->_snake->getTails()) { diff --git a/games/snake/src/entities/snake/Snake.cpp b/games/snake/src/entities/snake/Snake.cpp index 81a7dfb..acd8fa9 100644 --- a/games/snake/src/entities/snake/Snake.cpp +++ b/games/snake/src/entities/snake/Snake.cpp @@ -36,12 +36,31 @@ std::shared_ptr Snake::addTail() { void Snake::forward() { Vector2i oldPosition = this->head->position; Vector2i tempOldPosition = oldPosition; + int at = -1; this->head->forward(); for (auto &tail: this->_tails) { + at += 1; tempOldPosition = tail->getPosition(); tail->setPosition(oldPosition); oldPosition = tempOldPosition; + + Vector2i old = at > 0 ? this->_tails.at(at - 1)->getPosition() : this->head->position; + if (tail == this->_tails.back()) { + if (tail->getPosition().y < old.y) + tail->setTextureOrigin(Vector2u(0, 1)); + if (tail->getPosition().y > old.y) + tail->setTextureOrigin(Vector2u(1, 1)); + if (tail->getPosition().x < old.x) + tail->setTextureOrigin(Vector2u(2, 1)); + if (tail->getPosition().x > old.x) + tail->setTextureOrigin(Vector2u(3, 1)); + continue; + } + if (tail->getPosition().y == old.y) + tail->setTextureOrigin(Vector2u(1, 0)); + else + tail->setTextureOrigin(Vector2u(0, 0)); } } diff --git a/games/snake/src/entities/snake/TailEntity.cpp b/games/snake/src/entities/snake/TailEntity.cpp index da39e93..55f2ee3 100644 --- a/games/snake/src/entities/snake/TailEntity.cpp +++ b/games/snake/src/entities/snake/TailEntity.cpp @@ -42,6 +42,15 @@ void arcade::games::snake::TailEntity::setPosition(Vector2i position) { } } +void arcade::games::snake::TailEntity::setTextureOrigin(shared::types::Vector2u origin) { + for (auto &component: this->_components) { + auto txCmp = std::dynamic_pointer_cast(component); + if (txCmp == nullptr) continue; + + txCmp->getTextureProps().origin = origin; + } +} + Vector2i arcade::games::snake::TailEntity::getPosition() { return this->_position; } diff --git a/games/snake/src/entities/snake/TailEntity.hpp b/games/snake/src/entities/snake/TailEntity.hpp index 13da0e3..2134205 100644 --- a/games/snake/src/entities/snake/TailEntity.hpp +++ b/games/snake/src/entities/snake/TailEntity.hpp @@ -27,6 +27,12 @@ class arcade::games::snake::TailEntity : public common::AEntity { */ void setPosition(Vector2i position); + /** + * @brief Set texture origin for direction of the tail + * @param origin + */ + void setTextureOrigin(Vector2u origin); + /** * @brief Get position of the tail * @return Vector of the position From b46a1baf75877fe3d4a7e809b81c705847ff479b Mon Sep 17 00:00:00 2001 From: Flavien Chenu Date: Wed, 3 Apr 2024 14:27:39 +0200 Subject: [PATCH 30/33] refactor(graphics:sfml): update mouse events with view handling --- graphics/sfml/src/window/EventsHandler.cpp | 74 +++++++++++++--------- graphics/sfml/src/window/Window.cpp | 67 ++++++++++---------- graphics/sfml/src/window/Window.hpp | 18 +----- 3 files changed, 80 insertions(+), 79 deletions(-) diff --git a/graphics/sfml/src/window/EventsHandler.cpp b/graphics/sfml/src/window/EventsHandler.cpp index 3ecab0c..d499aa3 100644 --- a/graphics/sfml/src/window/EventsHandler.cpp +++ b/graphics/sfml/src/window/EventsHandler.cpp @@ -28,7 +28,7 @@ EventsHandler::EventHandler EventsHandler::_getHandler(sf::Event::EventType type return handler != handlers.end() ? handler->second : nullptr; } -EventsHandler::EventsHandler(Window &window): _window(window) {} +EventsHandler::EventsHandler(Window &window) : _window(window) {} std::vector EventsHandler::handleEvents() { std::vector events; @@ -46,7 +46,7 @@ std::vector EventsHandler::handleEvents() { bool EventsHandler::_handleControlKey( sf::Event::KeyEvent event, - IKeyEvent::KeyCode &code + unused IKeyEvent::KeyCode &code ) { switch (event.code) { case sf::Keyboard::LControl: @@ -87,8 +87,7 @@ bool EventsHandler::_handleArrowKey( bool EventsHandler::_handleFunctionKey( sf::Event::KeyEvent event, IKeyEvent::KeyCode &code -) -{ +) { if (event.code >= sf::Keyboard::F1 && event.code <= sf::Keyboard::F12) { code.func = event.code - sf::Keyboard::F1 + 1; return true; @@ -102,26 +101,26 @@ bool EventsHandler::_handleCharKey( IKeyEvent::KeyCode &code ) { static const std::map specials = { - {sf::Keyboard::Space, ' '}, - {sf::Keyboard::LBracket, '['}, - {sf::Keyboard::RBracket, ']'}, + {sf::Keyboard::Space, ' '}, + {sf::Keyboard::LBracket, '['}, + {sf::Keyboard::RBracket, ']'}, {sf::Keyboard::Semicolon, ';'}, - {sf::Keyboard::Comma, ','}, - {sf::Keyboard::Period, '.'}, - {sf::Keyboard::Quote, '\''}, - {sf::Keyboard::Slash, '/'}, + {sf::Keyboard::Comma, ','}, + {sf::Keyboard::Period, '.'}, + {sf::Keyboard::Quote, '\''}, + {sf::Keyboard::Slash, '/'}, {sf::Keyboard::Backslash, '\\'}, - {sf::Keyboard::Tilde, '~'}, - {sf::Keyboard::Equal, '='}, - {sf::Keyboard::Hyphen, '-'}, - {sf::Keyboard::Enter, '\n'}, + {sf::Keyboard::Tilde, '~'}, + {sf::Keyboard::Equal, '='}, + {sf::Keyboard::Hyphen, '-'}, + {sf::Keyboard::Enter, '\n'}, {sf::Keyboard::Backspace, '\b'}, - {sf::Keyboard::Tab, '\t'}, - {sf::Keyboard::Escape, 0x1B}, - {sf::Keyboard::Add, '+'}, - {sf::Keyboard::Subtract, '-'}, - {sf::Keyboard::Multiply, '*'}, - {sf::Keyboard::Divide, '/'} + {sf::Keyboard::Tab, '\t'}, + {sf::Keyboard::Escape, 0x1B}, + {sf::Keyboard::Add, '+'}, + {sf::Keyboard::Subtract, '-'}, + {sf::Keyboard::Multiply, '*'}, + {sf::Keyboard::Divide, '/'} }; if (event.code >= sf::Keyboard::A && event.code <= sf::Keyboard::Z) { @@ -186,7 +185,7 @@ EventPtr EventsHandler::_handleWindowResizeEvent( unused sf::Event &event, Window &window ) { - window.viewResize(event); + window.onResize(); return std::make_shared(); } @@ -194,35 +193,48 @@ EventPtr EventsHandler::_handleMouseMoveEvent( sf::Event &event, Window &window ) { - return std::make_shared( - window.pixelsToTiles(Vector2i(event.mouseMove.x, event.mouseMove.y)) - ); + auto pos = window.mapPositionToTile({ + event.mouseMove.x, + event.mouseMove.y + }); + + return pos.x >= 0 && pos.y >= 0 + ? std::make_shared(pos) + : nullptr; } EventPtr EventsHandler::_handleMouseButtonPressEvent( sf::Event &event, Window &window ) { - Vector2i pos = window.pixelsToTiles(Vector2i(event.mouseButton.x, event.mouseButton.y)); + Vector2i pos = window.mapPositionToTile({ + event.mouseMove.x, + event.mouseMove.y + }); + if (pos.x < 0 || pos.y < 0) + return nullptr; if (event.mouseButton.button == sf::Mouse::Button::Left) return std::make_shared(pos, IMouseButtonEvent::MouseButton::LEFT); else if (event.mouseButton.button == sf::Mouse::Button::Right) return std::make_shared(pos, IMouseButtonEvent::MouseButton::RIGHT); - else - return nullptr; + return nullptr; } EventPtr EventsHandler::_handleMouseBtnReleaseEvent( sf::Event &event, unused Window &window ) { - Vector2i pos = window.pixelsToTiles(Vector2i(event.mouseButton.x, event.mouseButton.y)); + auto pos = window.mapPositionToTile({ + event.mouseMove.x, + event.mouseMove.y + }); + if (pos.x < 0 || pos.y < 0) + return nullptr; if (event.mouseButton.button == sf::Mouse::Button::Left) return std::make_shared(pos, IMouseButtonEvent::MouseButton::LEFT); else if (event.mouseButton.button == sf::Mouse::Button::Right) return std::make_shared(pos, IMouseButtonEvent::MouseButton::RIGHT); - else - return nullptr; + return nullptr; } diff --git a/graphics/sfml/src/window/Window.cpp b/graphics/sfml/src/window/Window.cpp index 1734c92..1eedc47 100644 --- a/graphics/sfml/src/window/Window.cpp +++ b/graphics/sfml/src/window/Window.cpp @@ -17,6 +17,7 @@ const Vector2u Window::tileSize = { 12, 12 }; Window::Window(const IWindow::WindowInitProps &props): _size(props.size), + _initialSize(0, 0), _renderer(*this), _eventsHandler(*this) { @@ -29,8 +30,12 @@ Window::Window(const IWindow::WindowInitProps &props): props.title ); Window::setIcon(props.icon); - _view.setSize(size.x, size.y); - _view.setCenter(size.x / 2, size.y / 2); + _view.setSize(static_cast(size.x), static_cast(size.y)); + _view.setCenter(static_cast(size.x) / 2, static_cast(size.y) / 2); + _initialSize = { + static_cast(_window.getSize().x), + static_cast(_window.getSize().y) + }; } Window::~Window() @@ -144,46 +149,42 @@ Vector2u Window::getPixelSizeFromTiles(const Vector2u &size) { return real; } -Vector2i Window::pixelsToTiles(const shared::types::Vector2i &position) const { - auto realSize = _window.getSize(); - - return { - static_cast(position.x * _size.x / realSize.x), - static_cast(position.y * _size.y / realSize.y) - }; -} - -Vector2i Window::tilesToPixels(const Vector2i &position) const { - auto realSize = _window.getSize(); +Vector2i Window::mapPositionToTile(const Vector2i &position) const { + auto pixelsPosition = _window.mapPixelToCoords({ + position.x, + position.y + }); + Vector2f size = { static_cast(_size.x), static_cast(_size.y) }; + Vector2f initialSize = { static_cast(_initialSize.x), static_cast(_initialSize.y) }; - return { - static_cast(position.x * realSize.x / _size.x), - static_cast(position.y * realSize.y / _size.y) + Vector2f tilesPosition = { + pixelsPosition.x * size.x / initialSize.x, + pixelsPosition.y * size.y / initialSize.y }; -} - -Vector2i Window::tilesToPixels(const Vector2u &position) const { - auto realSize = _window.getSize(); + if (tilesPosition.x >= size.x || tilesPosition.y >= size.y || pixelsPosition.x < 0) + return {-1, -1}; return { - static_cast(position.x * realSize.x / _size.x), - static_cast(position.y * realSize.y / _size.y) + static_cast(tilesPosition.x), + static_cast(tilesPosition.y) }; } -void Window::viewResize(const sf::Event &event) { - Vector2u orignalPixels = getPixelSizeFromTiles(_size); - float widht = event.size.width; - float height = event.size.height; +void Window::onResize() +{ + Vector2u originalPixels = getPixelSizeFromTiles(_size); + auto size = _window.getSize(); + auto width = static_cast(size.x); + auto height = static_cast(size.y); - _view.setSize(event.size.width, event.size.height); - _view.setCenter(orignalPixels.x / 2, orignalPixels.y / 2); - if (widht < height) { - auto zoom = static_cast(orignalPixels.x) / event.size.width; - _view.zoom(zoom); + _view.setSize(width, height); + _view.setCenter( static_cast(originalPixels.x) / 2, + static_cast(originalPixels.y) / 2 + ); + if (width < height) { + _view.zoom(static_cast(originalPixels.x) / width); } else { - auto zoom = static_cast(orignalPixels.y) / event.size.height; - _view.zoom(zoom); + _view.zoom(static_cast(originalPixels.y) / height); } _window.setView(_view); } diff --git a/graphics/sfml/src/window/Window.hpp b/graphics/sfml/src/window/Window.hpp index b1f97ab..6ac8d02 100644 --- a/graphics/sfml/src/window/Window.hpp +++ b/graphics/sfml/src/window/Window.hpp @@ -137,19 +137,7 @@ class arcade::graphics::sfml::window::Window: public shared::graphics::IWindow { * @brief Convert a position in pixels to a position in tiles * @return Converted position */ - Vector2i pixelsToTiles(const Vector2i &position) const; - - /** - * @brief Convert a position in tiles to a position in pixels - * @return Converted position - */ - Vector2i tilesToPixels(const Vector2i &position) const; - - /** - * @brief Convert a position in tiles to a position in pixels - * @return Converted position - */ - Vector2i tilesToPixels(const Vector2u &position) const; + Vector2i mapPositionToTile(const Vector2i &pixelsPosition) const; /** * @brief Get the size of a tile @@ -159,9 +147,8 @@ class arcade::graphics::sfml::window::Window: public shared::graphics::IWindow { /** * @brief Resize the view of the window - * @param event Event from SFML */ - void viewResize(const sf::Event &event); + void onResize(); /** * @brief Get the size of the window in pixels @@ -179,5 +166,6 @@ class arcade::graphics::sfml::window::Window: public shared::graphics::IWindow { WindowMode _mode; sf::Image _icon; Vector2u _size; + Vector2u _initialSize; sf::View _view; }; From 245f17ec36a7d28775a4b7812a30a22ca014b946 Mon Sep 17 00:00:00 2001 From: Matheo Coquet Date: Wed, 3 Apr 2024 14:38:29 +0200 Subject: [PATCH 31/33] feat(snake): add apple with reward system --- assets/snake/apple.ascii | 1 + assets/snake/apple.png | Bin 0 -> 718 bytes games/snake/CMakeLists.txt | 2 + games/snake/src/SnakeGame.cpp | 13 ++++- games/snake/src/SnakeGame.hpp | 7 +++ .../snake/src/entities/apple/AppleEntity.cpp | 51 ++++++++++++++++++ .../snake/src/entities/apple/AppleEntity.hpp | 41 ++++++++++++++ games/snake/src/entities/snake/HeadEntity.cpp | 10 ++-- .../components/HeadKeyboardComponent.cpp | 8 +-- games/snake/src/entities/wall/WallEntity.cpp | 6 +-- games/snake/src/entities/wall/WallEntity.hpp | 5 +- 11 files changed, 130 insertions(+), 14 deletions(-) create mode 100644 assets/snake/apple.ascii create mode 100644 assets/snake/apple.png create mode 100644 games/snake/src/entities/apple/AppleEntity.cpp create mode 100644 games/snake/src/entities/apple/AppleEntity.hpp diff --git a/assets/snake/apple.ascii b/assets/snake/apple.ascii new file mode 100644 index 0000000..60a89ed --- /dev/null +++ b/assets/snake/apple.ascii @@ -0,0 +1 @@ +O \ No newline at end of file diff --git a/assets/snake/apple.png b/assets/snake/apple.png new file mode 100644 index 0000000000000000000000000000000000000000..1bb1a638577716032def9fd93d851cff035e3994 GIT binary patch literal 718 zcmV;<0x|uGP)JN z6G0Tm-`iLfL9-|x#nn>9lNG&q%6c%QC+lBe`X2=JSRsEx1@AUDFVfx&y%?`vG$4q- z=t6rb?P0forGiH zfF)*YuFr=TF^ccA)vMF}ad*j^bia76F3$z9g@}1_gg#MqLBdBwpMW@uT6e7pba-+~ zPowv*Z$SCY^?-`)uE$qcMD=cz+V0N4_6=^Imb8Z0&f)HQc z{~Rvr#u*7r*Bt!-#cdseDCSzpYcfy`GAc9a15v0rNjb}_MC)MY-ZEH%UA&`mQR|?r zb6}AYiiT!>HCYk12cfSDo2t-zR^Ik1Q>zgA$n4N(iMK&?WWg&3SBB+X`_L|I-XMgrwka{pF` zLcxa4J&AFdNt;WYfkH6vsB_i9G-)Do*xMcD5huxAsAcjv`O6~jgF`L(y*%P1xqsF5 zk~FijpG#Y&qq>r=taGxIn5?%GLACLZ7;zTa1LF(Kax@MzC;$Ke07*qoM6N<$g0C_< AjsO4v literal 0 HcmV?d00001 diff --git a/games/snake/CMakeLists.txt b/games/snake/CMakeLists.txt index 3e27f8b..1c99fa6 100644 --- a/games/snake/CMakeLists.txt +++ b/games/snake/CMakeLists.txt @@ -15,6 +15,8 @@ add_library(${PROJECT_NAME} SHARED src/entities/wall/WallEntity.hpp src/entities/background/BackgroundEntity.cpp src/entities/background/BackgroundEntity.hpp + src/entities/apple/AppleEntity.cpp + src/entities/apple/AppleEntity.hpp ) add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/../common PRIVATE) target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_LIST_DIR}/src) diff --git a/games/snake/src/SnakeGame.cpp b/games/snake/src/SnakeGame.cpp index e624244..875c308 100644 --- a/games/snake/src/SnakeGame.cpp +++ b/games/snake/src/SnakeGame.cpp @@ -9,6 +9,7 @@ #include "SnakeGame.hpp" #include "entities/wall/WallEntity.hpp" #include "entities/background/BackgroundEntity.hpp" +#include "entities/apple/AppleEntity.hpp" #include "common/components/TextureComponent.hpp" #include "entities/snake/components/HeadKeyboardComponent.hpp" @@ -33,7 +34,7 @@ const shared::games::GameManifest snake::SnakeGame::manifest = { }; snake::SnakeGame::SnakeGame() : common::AGame(Vector2u(20, 20), 60) { - this->_snake = std::make_unique(5); + this->_snake = std::make_unique(2); this->_registerEntity(this->_snake->head); for (auto &tail: this->_snake->getTails()) { @@ -43,6 +44,9 @@ snake::SnakeGame::SnakeGame() : common::AGame(Vector2u(20, 20), 60) { this->_registerEntity(std::make_unique(this->getSize())); this->_registerEntity(std::make_unique(this->getSize())); + this->_apple = std::make_unique(this->getSize()); + this->_registerEntity(this->_apple); + this->_clock = std::chrono::milliseconds(0); this->_looseGame = false; } @@ -83,3 +87,10 @@ void snake::SnakeGame::_loose() { void snake::SnakeGame::setLooseGame(bool state) { this->_looseGame = state; } + +void snake::SnakeGame::addNewPoint() { + std::shared_ptr newTail = this->_snake->addTail(); + + this->_registerEntity(newTail); + this->_apple->generateApple(); +} diff --git a/games/snake/src/SnakeGame.hpp b/games/snake/src/SnakeGame.hpp index fde5a78..c7d8645 100644 --- a/games/snake/src/SnakeGame.hpp +++ b/games/snake/src/SnakeGame.hpp @@ -9,6 +9,7 @@ #include "common/game/AGame.hpp" #include "games/snake/src/entities/snake/Snake.hpp" +#include "entities/apple/AppleEntity.hpp" namespace arcade::games::snake { class SnakeGame; @@ -47,6 +48,11 @@ class arcade::games::snake::SnakeGame : public arcade::games::common::AGame { */ void setLooseGame(bool state); + /** + * @brief Add new point to player and re-generate an apple + */ + void addNewPoint(); + protected: /** * @brief Execute the process of the end of the game when the player _loose @@ -54,6 +60,7 @@ class arcade::games::snake::SnakeGame : public arcade::games::common::AGame { void _loose(); std::unique_ptr _snake; + std::shared_ptr _apple; shared::games::DeltaTime _clock; bool _looseGame; }; diff --git a/games/snake/src/entities/apple/AppleEntity.cpp b/games/snake/src/entities/apple/AppleEntity.cpp new file mode 100644 index 0000000..82c7ba5 --- /dev/null +++ b/games/snake/src/entities/apple/AppleEntity.cpp @@ -0,0 +1,51 @@ +/* +** EPITECH PROJECT, 2024 +** AppleEntity.cpp +** File description: +** AppleEntity class +*/ + +#include +#include "AppleEntity.hpp" +#include "common/components/CollidableComponent.hpp" +#include "common/components/TextureComponent.hpp" + +using namespace arcade::games::snake; +using namespace arcade::games::common::components; + +arcade::games::snake::AppleEntity::AppleEntity(shared::types::Vector2u size): _mapSize(size) { + this->_create(); + this->generateApple(); +} + +void AppleEntity::generateApple() { + std::random_device rd; + std::mt19937 gen(rd()); + std::uniform_int_distribution dis(1, this->_mapSize.x - 2); + Vector2i randomPosition = Vector2i(dis(gen), dis(gen)); + + for (auto &component: this->_components) { + auto posCmp = std::dynamic_pointer_cast(component); + if (posCmp == nullptr) continue; + + posCmp->getPosition().x = randomPosition.x; + posCmp->getPosition().y = randomPosition.y; + } +} + +void AppleEntity::_create() { + shared::games::components::TextureProps textureProps = { + .sources = { + .ascii = "assets/snake/apple.ascii", + .bin = "assets/snake/apple.png", + .binTileSize = Vector2f(40, 40) + }, + .origin = Vector2u(0, 0) + }; + std::shared_ptr collision = std::make_shared(*this, nullptr); + std::shared_ptr texture = std::make_shared(*this, Vector2u(1, 1), 9, + textureProps); + + this->_components.push_back(collision); + this->_components.push_back(texture); +} diff --git a/games/snake/src/entities/apple/AppleEntity.hpp b/games/snake/src/entities/apple/AppleEntity.hpp new file mode 100644 index 0000000..b36d5f8 --- /dev/null +++ b/games/snake/src/entities/apple/AppleEntity.hpp @@ -0,0 +1,41 @@ +/* +** EPITECH PROJECT, 2024 +** AppleEntity.hpp +** File description: +** AppleEntity class +*/ + +#pragma once + +#include "common/entity/AEntity.hpp" +#include "shared/types/Vector.hpp" + +namespace arcade::games::snake { + class AppleEntity; +} + +class arcade::games::snake::AppleEntity : public common::AEntity { +public: + ~AppleEntity() override = default; + + /** + * @brief Create the apple entity + * @param size Size of the map + */ + explicit AppleEntity(shared::types::Vector2u + size); + + /** + * @brief Update the position of the apple on the map + * (As a new apple reward for the player) + */ + void generateApple(); + +protected: + /** + * @brief Create the apple components + */ + void _create(); + + shared::types::Vector2u _mapSize; +}; diff --git a/games/snake/src/entities/snake/HeadEntity.cpp b/games/snake/src/entities/snake/HeadEntity.cpp index e4a790b..c3c794e 100644 --- a/games/snake/src/entities/snake/HeadEntity.cpp +++ b/games/snake/src/entities/snake/HeadEntity.cpp @@ -7,6 +7,7 @@ #include "SnakeGame.hpp" #include "HeadEntity.hpp" +#include "../apple/AppleEntity.hpp" #include "../wall/WallEntity.hpp" #include "components/HeadKeyboardComponent.hpp" @@ -68,11 +69,14 @@ void arcade::games::snake::HeadEntity::_onCollide(std::shared_ptr target) { auto game = std::dynamic_pointer_cast(ctx); - if (!dynamic_cast(&target->getEntity()) && !dynamic_cast(&target->getEntity())) - return; if (!game) return; - game->setLooseGame(true); + if (dynamic_cast(&target->getEntity()) || dynamic_cast(&target->getEntity())) { + game->setLooseGame(true); + } + if (dynamic_cast(&target->getEntity())) { + game->addNewPoint(); + } } void arcade::games::snake::HeadEntity::reset() { diff --git a/games/snake/src/entities/snake/components/HeadKeyboardComponent.cpp b/games/snake/src/entities/snake/components/HeadKeyboardComponent.cpp index d9893b5..213308e 100644 --- a/games/snake/src/entities/snake/components/HeadKeyboardComponent.cpp +++ b/games/snake/src/entities/snake/components/HeadKeyboardComponent.cpp @@ -15,16 +15,16 @@ HeadKeyboardComponent::HeadKeyboardComponent(HeadEntity &entity) : AComponent(KE void HeadKeyboardComponent::onKeyPress(std::shared_ptr ctx, shared::games::components::IKeyboardComponent::KeyData keyData) { if (keyData.type == ARROW) { - if (keyData.code.arrow == UP) { + if (keyData.code.arrow == UP && this->_parent.direction.y != 1) { this->_parent.direction = Vector2i(0, -1); } - if (keyData.code.arrow == DOWN) { + if (keyData.code.arrow == DOWN && this->_parent.direction.y != -1) { this->_parent.direction = Vector2i(0, 1); } - if (keyData.code.arrow == LEFT) { + if (keyData.code.arrow == LEFT && this->_parent.direction.x != 1) { this->_parent.direction = Vector2i(-1, 0); } - if (keyData.code.arrow == RIGHT) { + if (keyData.code.arrow == RIGHT && this->_parent.direction.x != -1) { this->_parent.direction = Vector2i(1, 0); } } diff --git a/games/snake/src/entities/wall/WallEntity.cpp b/games/snake/src/entities/wall/WallEntity.cpp index 229e4e0..d641e64 100644 --- a/games/snake/src/entities/wall/WallEntity.cpp +++ b/games/snake/src/entities/wall/WallEntity.cpp @@ -14,7 +14,7 @@ using namespace arcade::games::common::components; WallEntity::WallEntity(shared::types::Vector2u size) { if (size.x < 3 || size.y < 3) - throw WallExeption("Invalid size of map"); + throw WallException("Invalid size of map"); for (std::size_t y = 0; y < size.y; y++) { this->_createWall(Vector2i(0, y)); @@ -49,8 +49,8 @@ void WallEntity::_createWall(shared::types::Vector2i position) { this->_components.push_back(texture); } -WallEntity::WallExeption::WallExeption(const std::string &message) : _message(message) {} +WallEntity::WallException::WallException(const std::string &message) : _message(message) {} -const char *WallEntity::WallExeption::what() const noexcept { +const char *WallEntity::WallException::what() const noexcept { return this->_message.c_str(); } diff --git a/games/snake/src/entities/wall/WallEntity.hpp b/games/snake/src/entities/wall/WallEntity.hpp index 49744b7..7c3dc5c 100644 --- a/games/snake/src/entities/wall/WallEntity.hpp +++ b/games/snake/src/entities/wall/WallEntity.hpp @@ -15,16 +15,15 @@ namespace arcade::games::snake { class WallEntity; } - class arcade::games::snake::WallEntity : public common::AEntity { public: ~WallEntity() override = default; explicit WallEntity(shared::types::Vector2u size); - class WallExeption : public std::exception { + class WallException : public std::exception { public: - WallExeption(const std::string &message); + WallException(const std::string &message); const char *what() const noexcept override; From 01804bcd1ba8c58e8353f5dc866e4232eec9c5e7 Mon Sep 17 00:00:00 2001 From: Matheo Coquet Date: Wed, 3 Apr 2024 15:24:00 +0200 Subject: [PATCH 32/33] fix(snake): update apple collision handler --- games/snake/src/entities/apple/AppleEntity.cpp | 16 +++++++++++++++- games/snake/src/entities/apple/AppleEntity.hpp | 11 +++++++++++ games/snake/src/entities/snake/HeadEntity.cpp | 3 --- .../snake/components/HeadKeyboardComponent.cpp | 8 ++++---- games/snake/src/entities/wall/WallEntity.cpp | 2 +- 5 files changed, 31 insertions(+), 9 deletions(-) diff --git a/games/snake/src/entities/apple/AppleEntity.cpp b/games/snake/src/entities/apple/AppleEntity.cpp index 82c7ba5..651e611 100644 --- a/games/snake/src/entities/apple/AppleEntity.cpp +++ b/games/snake/src/entities/apple/AppleEntity.cpp @@ -9,6 +9,9 @@ #include "AppleEntity.hpp" #include "common/components/CollidableComponent.hpp" #include "common/components/TextureComponent.hpp" +#include "../snake/HeadEntity.hpp" +#include "../snake/TailEntity.hpp" +#include "../../SnakeGame.hpp" using namespace arcade::games::snake; using namespace arcade::games::common::components; @@ -42,10 +45,21 @@ void AppleEntity::_create() { }, .origin = Vector2u(0, 0) }; - std::shared_ptr collision = std::make_shared(*this, nullptr); + std::shared_ptr collision = std::make_shared(*this, this->_onCollide); std::shared_ptr texture = std::make_shared(*this, Vector2u(1, 1), 9, textureProps); this->_components.push_back(collision); this->_components.push_back(texture); } + +void arcade::games::snake::AppleEntity::_onCollide(std::shared_ptr ctx, + std::shared_ptr target) { + auto game = std::dynamic_pointer_cast(ctx); + + if (!game) + return; + if (dynamic_cast(&target->getEntity()) || dynamic_cast(&target->getEntity())) { + game->addNewPoint(); + } +} diff --git a/games/snake/src/entities/apple/AppleEntity.hpp b/games/snake/src/entities/apple/AppleEntity.hpp index b36d5f8..f0a125f 100644 --- a/games/snake/src/entities/apple/AppleEntity.hpp +++ b/games/snake/src/entities/apple/AppleEntity.hpp @@ -9,6 +9,7 @@ #include "common/entity/AEntity.hpp" #include "shared/types/Vector.hpp" +#include "shared/games/components/ICollidableComponent.hpp" namespace arcade::games::snake { class AppleEntity; @@ -37,5 +38,15 @@ class arcade::games::snake::AppleEntity : public common::AEntity { */ void _create(); + /** + * @brief Represent the function that will be executed + * when the apple will collide with an other collidable component + * @param ctx Context of the game + * @param target Target component + */ + static void _onCollide(std::shared_ptr ctx, + std::shared_ptr target); + + shared::types::Vector2u _mapSize; }; diff --git a/games/snake/src/entities/snake/HeadEntity.cpp b/games/snake/src/entities/snake/HeadEntity.cpp index c3c794e..722fb77 100644 --- a/games/snake/src/entities/snake/HeadEntity.cpp +++ b/games/snake/src/entities/snake/HeadEntity.cpp @@ -74,9 +74,6 @@ void arcade::games::snake::HeadEntity::_onCollide(std::shared_ptr(&target->getEntity()) || dynamic_cast(&target->getEntity())) { game->setLooseGame(true); } - if (dynamic_cast(&target->getEntity())) { - game->addNewPoint(); - } } void arcade::games::snake::HeadEntity::reset() { diff --git a/games/snake/src/entities/snake/components/HeadKeyboardComponent.cpp b/games/snake/src/entities/snake/components/HeadKeyboardComponent.cpp index 213308e..9a645de 100644 --- a/games/snake/src/entities/snake/components/HeadKeyboardComponent.cpp +++ b/games/snake/src/entities/snake/components/HeadKeyboardComponent.cpp @@ -29,16 +29,16 @@ void HeadKeyboardComponent::onKeyPress(std::shared_ptr ctx } } if (keyData.type == CHAR) { - if (keyData.code.character == 'z') { + if (keyData.code.character == 'z' && this->_parent.direction.y != 1) { this->_parent.direction = Vector2i(0, -1); } - if (keyData.code.character == 's') { + if (keyData.code.character == 's' && this->_parent.direction.y != -1) { this->_parent.direction = Vector2i(0, 1); } - if (keyData.code.character == 'q') { + if (keyData.code.character == 'q' && this->_parent.direction.x != 1) { this->_parent.direction = Vector2i(-1, 0); } - if (keyData.code.character == 'd') { + if (keyData.code.character == 'd' && this->_parent.direction.x != -1) { this->_parent.direction = Vector2i(1, 0); } } diff --git a/games/snake/src/entities/wall/WallEntity.cpp b/games/snake/src/entities/wall/WallEntity.cpp index d641e64..e554340 100644 --- a/games/snake/src/entities/wall/WallEntity.cpp +++ b/games/snake/src/entities/wall/WallEntity.cpp @@ -38,7 +38,7 @@ void WallEntity::_createWall(shared::types::Vector2i position) { .origin = Vector2u(0, 0) }; std::shared_ptr collision = std::make_shared(*this, nullptr); - std::shared_ptr texture = std::make_shared(*this, Vector2u(1, 1), 1, + std::shared_ptr texture = std::make_shared(*this, Vector2u(1, 1), 11, textureProps); collision->getPosition().x = position.x; From 9b1e1f4d4eaf024adff4a9689df4a955df0fb341 Mon Sep 17 00:00:00 2001 From: Matheo Coquet Date: Wed, 3 Apr 2024 18:59:00 +0200 Subject: [PATCH 33/33] feat(snake): add bonus --- games/snake/src/SnakeGame.cpp | 12 ++++++++++-- games/snake/src/SnakeGame.hpp | 4 ++++ games/snake/src/entities/snake/HeadEntity.cpp | 4 ++-- games/snake/src/entities/snake/Snake.cpp | 3 ++- .../snake/components/HeadKeyboardComponent.cpp | 6 ++++++ 5 files changed, 24 insertions(+), 5 deletions(-) diff --git a/games/snake/src/SnakeGame.cpp b/games/snake/src/SnakeGame.cpp index 875c308..0bd6501 100644 --- a/games/snake/src/SnakeGame.cpp +++ b/games/snake/src/SnakeGame.cpp @@ -34,7 +34,7 @@ const shared::games::GameManifest snake::SnakeGame::manifest = { }; snake::SnakeGame::SnakeGame() : common::AGame(Vector2u(20, 20), 60) { - this->_snake = std::make_unique(2); + this->_snake = std::make_unique(4); this->_registerEntity(this->_snake->head); for (auto &tail: this->_snake->getTails()) { @@ -49,6 +49,8 @@ snake::SnakeGame::SnakeGame() : common::AGame(Vector2u(20, 20), 60) { this->_clock = std::chrono::milliseconds(0); this->_looseGame = false; + this->speedTime = 100; + this->speedBoost = 0; } const shared::games::GameManifest &snake::SnakeGame::getManifest() const noexcept { @@ -56,12 +58,17 @@ const shared::games::GameManifest &snake::SnakeGame::getManifest() const noexcep } void snake::SnakeGame::compute(shared::games::DeltaTime dt) { + unsigned int speed = this->speedTime; this->_clock += dt; if (this->_looseGame) { return this->_loose(); } - if (this->_clock > std::chrono::milliseconds(100) + this->_snake->lastMove) { + if (this->speedBoost > 0) { + speed = 0; + this->speedBoost -= 1; + } + if (this->_clock > std::chrono::milliseconds(speed) + this->_snake->lastMove) { this->_snake->lastMove = this->_clock; this->_snake->forward(); } @@ -93,4 +100,5 @@ void snake::SnakeGame::addNewPoint() { this->_registerEntity(newTail); this->_apple->generateApple(); + this->speedTime -= 2; } diff --git a/games/snake/src/SnakeGame.hpp b/games/snake/src/SnakeGame.hpp index c7d8645..24d6e3c 100644 --- a/games/snake/src/SnakeGame.hpp +++ b/games/snake/src/SnakeGame.hpp @@ -53,6 +53,10 @@ class arcade::games::snake::SnakeGame : public arcade::games::common::AGame { */ void addNewPoint(); + unsigned int speedTime; + + unsigned int speedBoost; + protected: /** * @brief Execute the process of the end of the game when the player _loose diff --git a/games/snake/src/entities/snake/HeadEntity.cpp b/games/snake/src/entities/snake/HeadEntity.cpp index 722fb77..e744697 100644 --- a/games/snake/src/entities/snake/HeadEntity.cpp +++ b/games/snake/src/entities/snake/HeadEntity.cpp @@ -17,7 +17,7 @@ using namespace shared::games::components; arcade::games::snake::HeadEntity::HeadEntity() : _textureProps( arcade::games::snake::HeadEntity::_defaultTextureProps()), direction(1, 0), - position(8, 4) { + position(6, 10) { std::shared_ptr collide = std::make_shared(*this, HeadEntity::_onCollide); std::shared_ptr texture = std::make_shared(*this, Vector2u(1, 1), 10, this->_textureProps); @@ -78,7 +78,7 @@ void arcade::games::snake::HeadEntity::_onCollide(std::shared_ptrdirection = Vector2i(1, 0); - this->position = Vector2i(8, 4); + this->position = Vector2i(6, 10); for (auto &component: this->_components) { std::shared_ptr posCmp = std::dynamic_pointer_cast(component); if (posCmp == nullptr) continue; diff --git a/games/snake/src/entities/snake/Snake.cpp b/games/snake/src/entities/snake/Snake.cpp index acd8fa9..3c3547e 100644 --- a/games/snake/src/entities/snake/Snake.cpp +++ b/games/snake/src/entities/snake/Snake.cpp @@ -13,7 +13,7 @@ using namespace shared::games::entity; using namespace arcade::games::snake; Snake::Snake(unsigned int tails) { - this->lastMove = std::chrono::milliseconds(0); + this->lastMove = std::chrono::milliseconds(900); this->head = std::make_shared(); this->_baseTails = tails; @@ -70,5 +70,6 @@ void Snake::reset() { for (size_t i = 0; i < this->_baseTails; i++) { this->addTail(); + this->forward(); } } diff --git a/games/snake/src/entities/snake/components/HeadKeyboardComponent.cpp b/games/snake/src/entities/snake/components/HeadKeyboardComponent.cpp index 9a645de..f0f0efd 100644 --- a/games/snake/src/entities/snake/components/HeadKeyboardComponent.cpp +++ b/games/snake/src/entities/snake/components/HeadKeyboardComponent.cpp @@ -6,6 +6,7 @@ */ #include "HeadKeyboardComponent.hpp" +#include "../../../SnakeGame.hpp" using namespace arcade::games::snake::components; using namespace shared::games::components; @@ -42,6 +43,11 @@ void HeadKeyboardComponent::onKeyPress(std::shared_ptr ctx this->_parent.direction = Vector2i(1, 0); } } + if (keyData.type == CHAR && keyData.code.character == ' ') { + auto game = std::dynamic_pointer_cast(ctx); + + game->speedBoost = 3; + } } void HeadKeyboardComponent::onKeyRelease(std::shared_ptr ctx,