diff --git a/.gitignore b/.gitignore index 4a7e5eb..1571a4d 100644 --- a/.gitignore +++ b/.gitignore @@ -19,4 +19,4 @@ lib *.gcno *.gcda *.o -*.txt +scores.txt diff --git a/assets/nibbler/apple.ascii b/assets/nibbler/apple.ascii new file mode 100644 index 0000000..60a89ed --- /dev/null +++ b/assets/nibbler/apple.ascii @@ -0,0 +1 @@ +O \ No newline at end of file diff --git a/assets/nibbler/apple.png b/assets/nibbler/apple.png new file mode 100644 index 0000000..1bb1a63 Binary files /dev/null and b/assets/nibbler/apple.png differ diff --git a/assets/nibbler/death.wav b/assets/nibbler/death.wav new file mode 100644 index 0000000..bba6b2a Binary files /dev/null and b/assets/nibbler/death.wav differ diff --git a/assets/nibbler/down.wav b/assets/nibbler/down.wav new file mode 100644 index 0000000..76ee628 Binary files /dev/null and b/assets/nibbler/down.wav differ diff --git a/assets/nibbler/eat.wav b/assets/nibbler/eat.wav new file mode 100644 index 0000000..7801d73 Binary files /dev/null and b/assets/nibbler/eat.wav differ diff --git a/assets/nibbler/effects.wav b/assets/nibbler/effects.wav new file mode 100644 index 0000000..0ad2d8d Binary files /dev/null and b/assets/nibbler/effects.wav differ diff --git a/assets/nibbler/head.ascii b/assets/nibbler/head.ascii new file mode 100644 index 0000000..71c4a23 --- /dev/null +++ b/assets/nibbler/head.ascii @@ -0,0 +1 @@ +@@@@ \ No newline at end of file diff --git a/assets/nibbler/head.png b/assets/nibbler/head.png new file mode 100644 index 0000000..f369b2a Binary files /dev/null and b/assets/nibbler/head.png differ diff --git a/assets/nibbler/left.wav b/assets/nibbler/left.wav new file mode 100644 index 0000000..24e462f Binary files /dev/null and b/assets/nibbler/left.wav differ diff --git a/assets/nibbler/levels/1.ascii b/assets/nibbler/levels/1.ascii new file mode 100644 index 0000000..fd379a7 --- /dev/null +++ b/assets/nibbler/levels/1.ascii @@ -0,0 +1,19 @@ +################### +# * * * * # +# ### # ### # ### # +#*# #*# #*# #*# +# ### # # # # ### # +# #*# #*# # +# ##### # # ##### # +#*# * * #*# +# # #####*##### # # +# * * # +# ##### ### ##### # +# * ### * # +# ### # ### # ### # +# # # # * # # # # +#*###*#*###*#*###*# +# # ### # # +#*##### ### #####*# +# # +################### diff --git a/assets/nibbler/levels/2.ascii b/assets/nibbler/levels/2.ascii new file mode 100644 index 0000000..0bab670 --- /dev/null +++ b/assets/nibbler/levels/2.ascii @@ -0,0 +1,19 @@ +################### +#* #* # # * # +# # # # # # # # # # +# *# * # * # # +# #### # # ## ## # +# # * # # ## ## ## +#* # # * # # +# #### * #### * # # +# ### ## #### # +# # * * # * # +# ## # ## ## ## ### +#**# # # * # * # +## # # # ## ### # +# *## ## * # +# ##### ## ## # ### +# * * # * # *# +# ##### # # ## ## # +# * * # +################### diff --git a/assets/nibbler/right.wav b/assets/nibbler/right.wav new file mode 100644 index 0000000..a214ccf Binary files /dev/null and b/assets/nibbler/right.wav differ diff --git a/assets/nibbler/tail.ascii b/assets/nibbler/tail.ascii new file mode 100644 index 0000000..2afd973 --- /dev/null +++ b/assets/nibbler/tail.ascii @@ -0,0 +1,3 @@ +║═ +~~~~ +╝╚╗╔ \ No newline at end of file diff --git a/assets/nibbler/tail.png b/assets/nibbler/tail.png new file mode 100644 index 0000000..3910682 Binary files /dev/null and b/assets/nibbler/tail.png differ diff --git a/assets/nibbler/up.wav b/assets/nibbler/up.wav new file mode 100644 index 0000000..22d6c27 Binary files /dev/null and b/assets/nibbler/up.wav differ diff --git a/assets/nibbler/wall.ascii b/assets/nibbler/wall.ascii new file mode 100644 index 0000000..4287ca8 --- /dev/null +++ b/assets/nibbler/wall.ascii @@ -0,0 +1 @@ +# \ No newline at end of file diff --git a/assets/nibbler/wall.png b/assets/nibbler/wall.png new file mode 100644 index 0000000..e0f8498 Binary files /dev/null and b/assets/nibbler/wall.png differ diff --git a/core/src/Core.cpp b/core/src/Core.cpp index facb377..c12b444 100644 --- a/core/src/Core.cpp +++ b/core/src/Core.cpp @@ -55,16 +55,43 @@ void Core::_initGame() if (this->_gameProviders.empty()) throw ArcadeError("No game provider available"); this->_gameProvider = this->_getGameProvider(0); - std::cout << "No game provider selected, using default provider" << std::endl; + std::cerr << "No game provider selected, using default provider" << std::endl; } - this->_game = this->_gameProvider->createInstance(); - this->_sceneStage = RESUME; + try { + this->_game = this->_gameProvider->createInstance(); + this->_sceneStage = RESUME; + } catch (std::exception &e) { + std::cerr << e.what() << std::endl; + this->_sceneStage = MENU; + } +} + +void Core::_initSecureWindow() +{ + IWindow::WindowInitProps windowInitProps { + Vector2u(20, 20), + IWindow::WINDOWED, + 60, + "Secured Window", + "" + }; + + this->_handleWindowClose(); + if (!this->_graphicsProvider) { + if (this->_graphicsProviders.empty()) + throw ArcadeError("No graphic provider available"); + this->_graphicsProvider = this->_getGraphicsProvider(0); + std::cerr << "No graphic provider selected, using default provider" << std::endl; + } + this->_window = this->_graphicsProvider->createWindow(windowInitProps); } void Core::_initWindow() { if (!this->_game) this->_initGame(); + if (!this->_game) + return this->_initSecureWindow(); auto gameManifest = this->_game->getManifest(); IWindow::WindowInitProps windowInitProps { this->_game->getSize(), @@ -79,7 +106,7 @@ void Core::_initWindow() if (this->_graphicsProviders.empty()) throw ArcadeError("No graphic provider available"); this->_graphicsProvider = this->_getGraphicsProvider(0); - std::cout << "No graphic provider selected, using default provider" << std::endl; + std::cerr << "No graphic provider selected, using default provider" << std::endl; } this->_window = this->_graphicsProvider->createWindow(windowInitProps); this->_sceneStage = PLAY; @@ -285,7 +312,7 @@ void Core::_preventWindowEvents(std::vector events) void Core::_changeGraphicProvider(const unsigned char &index) { if (index > this->_graphicsProviders.size() - 1) { - std::cout << "Invalid graphic provider index" << std::endl; + std::cerr << "Invalid graphic provider index" << std::endl; return; } auto newProvider = this->_getGraphicsProvider(index); @@ -298,7 +325,7 @@ void Core::_changeGraphicProvider(const unsigned char &index) void Core::_changeGameProvider(const unsigned char &index) { if (index > this->_gameProviders.size() - 1) { - std::cout << "Invalid game provider index" << std::endl; + std::cerr << "Invalid game provider index" << std::endl; return; } auto newProvider = this->_getGameProvider(index); @@ -393,6 +420,7 @@ void Core::_handleWindowClose() this->_stopAllGraphicsSounds(); this->_window->close(); this->_menu.updateScore(this->_game); + this->_sceneStage = MENU; } } @@ -549,7 +577,7 @@ void Core::run() return; this->_initGame(); this->_initWindow(); - while (this->_window->isOpen()) { + while (this->_sceneStage != EXIT) { auto currentTime = std::chrono::high_resolution_clock::now(); auto deltaTime = std::chrono::duration_cast(currentTime - previousTime); previousTime = currentTime; @@ -559,15 +587,15 @@ void Core::run() this->_menu.run(); previousTime = std::chrono::high_resolution_clock::now(); } - if (this->_sceneStage == EXIT) - return; if (this->_sceneStage == NEWGAME) this->_initGame(); if (this->_sceneStage == RESUME) this->_initWindow(); - this->_game->compute(deltaTime); - this->_gameEntities = this->_game->getEntities(); - this->_handleEvents(); - this->_renderEntities(); + if (this->_sceneStage == PLAY) { + 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 index 461ba3d..315907b 100644 --- a/core/src/Core.hpp +++ b/core/src/Core.hpp @@ -64,6 +64,12 @@ class Core { */ void _initWindow(); + /** + * @brief Initialize the secure window + * + */ + void _initSecureWindow(); + /** * @brief Initialize the game * diff --git a/core/src/menu/Menu.cpp b/core/src/menu/Menu.cpp index c701fca..3bc9252 100644 --- a/core/src/menu/Menu.cpp +++ b/core/src/menu/Menu.cpp @@ -692,10 +692,11 @@ void Menu::_writeScore() void Menu::updateScore(std::shared_ptr game) { + if (!game) + return; this->_score.game = game->getManifest().name; this->_score.score = game->getScore(); - std::cout << "Player Score: " << this->_score.score << std::endl; for (auto &score : this->_scores) { auto playerName = this->_score.player.empty() ? "Guest" : this->_score.player; auto scoreName = score.player.empty() ? "Guest" : score.player; diff --git a/games/CMakeLists.txt b/games/CMakeLists.txt index 4c39731..aecae1b 100644 --- a/games/CMakeLists.txt +++ b/games/CMakeLists.txt @@ -1 +1,2 @@ add_subdirectory(snake) +add_subdirectory(nibbler) diff --git a/games/nibbler/CMakeLists.txt b/games/nibbler/CMakeLists.txt new file mode 100644 index 0000000..1d8b076 --- /dev/null +++ b/games/nibbler/CMakeLists.txt @@ -0,0 +1,24 @@ +project(nibbler) +add_library(${PROJECT_NAME} SHARED + export.cpp + src/NibblerGameProvider.cpp + src/NibblerGame.cpp + src/entities/nibbler/Nibbler.cpp + src/entities/nibbler/Nibbler.hpp + src/entities/nibbler/TailEntity.cpp + src/entities/nibbler/TailEntity.hpp + src/entities/nibbler/HeadEntity.cpp + src/entities/nibbler/HeadEntity.hpp + src/entities/nibbler/components/HeadKeyboardComponent.cpp + src/entities/nibbler/components/HeadKeyboardComponent.hpp + src/entities/wall/WallEntity.cpp + 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) +target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_LIST_DIR}/../..) +target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_LIST_DIR}/..) diff --git a/games/nibbler/export.cpp b/games/nibbler/export.cpp new file mode 100644 index 0000000..4ecdc95 --- /dev/null +++ b/games/nibbler/export.cpp @@ -0,0 +1,22 @@ +/* +** EPITECH PROJECT, 2024 +** arcade-shared +** File description: +** export +*/ + +#include "NibblerGameProvider.hpp" +#include "shared/types/Libraries.hpp" + +using namespace shared::games; +using namespace shared::types; + +extern "C" { +LibraryType SHARED_LIBRARY_TYPE_GETTER_NAME(void) { + return LibraryType::GAME; +} + +IGameProvider *SHARED_GAME_PROVIDER_GETTER_NAME(void) { + return new arcade::games::nibbler::NibblerGameProvider(); +} +} diff --git a/games/nibbler/src/NibblerGame.cpp b/games/nibbler/src/NibblerGame.cpp new file mode 100644 index 0000000..055313d --- /dev/null +++ b/games/nibbler/src/NibblerGame.cpp @@ -0,0 +1,257 @@ +/* +** EPITECH PROJECT, 2024 +** arcade +** File description: +** NibblerGame.cpp +*/ + +#include +#include +#include "NibblerGame.hpp" +#include "entities/wall/WallEntity.hpp" +#include "entities/background/BackgroundEntity.hpp" +#include "entities/apple/AppleEntity.hpp" +#include "common/components/TextureComponent.hpp" +#include "entities/nibbler/HeadEntity.hpp" + +using namespace arcade::games; + +const shared::games::GameManifest nibbler::NibblerGame::manifest = { + .name = "nibbler", + .description = "The nibbler 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" + }, + { + .name = "Yann Masson", + .email = "yannmasson@epitech.eu", + .website = "yannmasson.fr" + } + } +}; + +nibbler::NibblerGame::NibblerGame() : common::AGame(Vector2u(19, 19), 60) { + + this->_nibbler = std::make_unique(4); + this->_registerEntity(this->_nibbler->head); + this->changeToLevel(1); + + this->_clock = std::chrono::milliseconds(0); + this->_looseGame = false; + this->speedTime = 100; + this->speedBoost = 0; + this->moved = false; + this->canMakeChoice = true; +} + +const shared::games::GameManifest &nibbler::NibblerGame::getManifest() const noexcept { + return NibblerGame::manifest; +} + +void nibbler::NibblerGame::compute(shared::games::DeltaTime dt) { + unsigned int speed = this->speedTime; + this->_clock += dt; + + if (this->_looseGame) { + return this->_loose(); + } + if (this->speedBoost > 0) { + speed = 0; + this->speedBoost -= 1; + } + if (this->_clock > std::chrono::milliseconds(speed) + this->_nibbler->lastMove) { + this->_preventWallCollision(); + this->moved = false; + if (!this->canMakeChoice) + return; + this->_nibbler->lastMove = this->_clock; + this->_nibbler->forward(); + } +} + +void nibbler::NibblerGame::_loose() { + this->_clock = std::chrono::milliseconds(0); + this->_nibbler->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); + return !(tail == nullptr); + }), this->_entities.end()); + + this->_nibbler->reset(); + for (auto &tail: this->_nibbler->getTails()) { + this->_registerEntity(tail); + } + + this->_looseGame = false; + if (this->_score < this->_currentScore) + this->_score = this->_currentScore; + this->speedTime = 100; + this->changeToLevel(1); +} + +void nibbler::NibblerGame::setLooseGame(bool state) { + this->_looseGame = state; +} + +void nibbler::NibblerGame::addNewPoint() { + std::shared_ptr newTail = this->_nibbler->addTail(); + + this->changeStateSound("eat", shared::games::components::SoundState::PLAY); + this->_registerEntity(newTail); + + auto headPostion = this->_nibbler->head->position; + + int count = 0; + for (auto &entity: this->_entities) { + auto apple = std::dynamic_pointer_cast(entity); + if (apple == nullptr) + continue; + count += 1; + auto applePostion = apple->postion; + if (headPostion.x == applePostion.x && headPostion.y == applePostion.y) { + this->_entities.erase(std::remove(this->_entities.begin(), this->_entities.end(), entity), this->_entities.end()); + count -= 1; + } + } + this->_currentScore += 10; + if (count == 0) { + this->changeToLevel(2); + this->speedTime -= 20; + } +} + +void nibbler::NibblerGame::changeStateSound(const std::string &soundName, shared::games::components::SoundState state) { + for (auto &entity: this->_entities) { + auto head = std::dynamic_pointer_cast(entity); + if (head == nullptr) + continue; + head->sounds[soundName]->setState(state); + } +} + +bool nibbler::NibblerGame::isValidDirection(Vector2i direction) { + auto headPosition = this->_nibbler->head->position; + + if (direction.x == 0 && direction.y == -1) { + if (this->_map[headPosition.x][headPosition.y - 1] == WALL) + return false; + } else if (direction.x == 0 && direction.y == 1) { + if (this->_map[headPosition.x][headPosition.y + 1] == WALL) + return false; + } else if (direction.x == -1 && direction.y == 0) { + if (this->_map[headPosition.x - 1][headPosition.y] == WALL) + return false; + } else if (direction.x == 1 && direction.y == 0) { + if (this->_map[headPosition.x + 1][headPosition.y] == WALL) + return false; + } + return true; +} + +void nibbler::NibblerGame::_preventWallCollision() { + auto headDirection = this->_nibbler->head->direction; + auto headPosition = this->_nibbler->head->position; + + if (headDirection.x == 0 && headDirection.y == -1) { + if (this->_map[headPosition.x][headPosition.y - 1] == WALL) { + if (this->_map[headPosition.x - 1][headPosition.y] == SPACE && this->_map[headPosition.x + 1][headPosition.y] == SPACE) { + this->canMakeChoice = false; + } else if (this->_map[headPosition.x - 1][headPosition.y] == WALL && this->_map[headPosition.x + 1][headPosition.y] == SPACE) { + this->_nibbler->head->setDirection(Vector2i(1, 0)); + this->canMakeChoice = true; + this->moved = true; + } else if (this->_map[headPosition.x + 1][headPosition.y] == WALL && this->_map[headPosition.x - 1][headPosition.y] == SPACE) { + this->_nibbler->head->setDirection(Vector2i(-1, 0)); + this->canMakeChoice = true; + this->moved = true; + } + } + } else if (headDirection.x == 0 && headDirection.y == 1) { + if (this->_map[headPosition.x][headPosition.y + 1] == WALL) { + if (this->_map[headPosition.x - 1][headPosition.y] == SPACE && this->_map[headPosition.x + 1][headPosition.y] == SPACE) { + this->canMakeChoice = false; + } else if (this->_map[headPosition.x - 1][headPosition.y] == WALL && this->_map[headPosition.x + 1][headPosition.y] == SPACE) { + this->_nibbler->head->setDirection(Vector2i(1, 0)); + this->canMakeChoice = true; + this->moved = true; + } else if (this->_map[headPosition.x + 1][headPosition.y] == WALL && this->_map[headPosition.x - 1][headPosition.y] == SPACE) { + this->_nibbler->head->setDirection(Vector2i(-1, 0)); + this->canMakeChoice = true; + this->moved = true; + } + } + } else if (headDirection.x == -1 && headDirection.y == 0) { + if (this->_map[headPosition.x - 1][headPosition.y] == WALL) { + if (this->_map[headPosition.x][headPosition.y - 1] == SPACE && this->_map[headPosition.x][headPosition.y + 1] == SPACE) { + this->canMakeChoice = false; + } else if (this->_map[headPosition.x][headPosition.y - 1] == WALL && this->_map[headPosition.x][headPosition.y + 1] == SPACE) { + this->_nibbler->head->setDirection(Vector2i(0, 1)); + this->canMakeChoice = true; + this->moved = true; + } else if (this->_map[headPosition.x][headPosition.y + 1] == WALL && this->_map[headPosition.x][headPosition.y - 1] == SPACE) { + this->_nibbler->head->setDirection(Vector2i(0, -1)); + this->canMakeChoice = true; + this->moved = true; + } + } + } else if (headDirection.x == 1 && headDirection.y == 0) { + if (this->_map[headPosition.x + 1][headPosition.y] == WALL) { + if (this->_map[headPosition.x][headPosition.y - 1] == SPACE && this->_map[headPosition.x][headPosition.y + 1] == SPACE) { + this->canMakeChoice = false; + } else if (this->_map[headPosition.x][headPosition.y - 1] == WALL && this->_map[headPosition.x][headPosition.y + 1] == SPACE) { + this->_nibbler->head->setDirection(Vector2i(0, 1)); + this->canMakeChoice = true; + this->moved = true; + } else if (this->_map[headPosition.x][headPosition.y + 1] == WALL && this->_map[headPosition.x][headPosition.y - 1] == SPACE) { + this->_nibbler->head->setDirection(Vector2i(0, -1)); + this->canMakeChoice = true; + this->moved = true; + } + } + } +} + +void nibbler::NibblerGame::changeToLevel(int level) { + std::string line; + std::ifstream file("assets/nibbler/levels/" + std::to_string(level) + ".ascii"); + + if (!file.is_open()) { + std::cerr << "Error: cannot open file" << std::endl; + return; + } + std::size_t x = 0; + std::size_t y = 0; + + this->_entities.clear(); + this->_nibbler->reset(); + this->_registerEntity(this->_nibbler->head); + for (auto &tail: this->_nibbler->getTails()) { + this->_registerEntity(tail); + } + + while (std::getline(file, line)) { + for (auto &c: line) { + if (c == '#') + this->_registerEntity(std::make_unique(Vector2u(x, y))); + if (c == '*') + this->_registerEntity(std::make_unique(Vector2u(x, y))); + if (c == ' ' || c == '*') + this->_registerEntity(std::make_unique(Vector2u(x, y))); + this->_map[x][y] = c == '#' ? WALL : SPACE; + x += 1; + } + x = 0; + y += 1; + } + file.close(); +} diff --git a/games/nibbler/src/NibblerGame.hpp b/games/nibbler/src/NibblerGame.hpp new file mode 100644 index 0000000..3a389da --- /dev/null +++ b/games/nibbler/src/NibblerGame.hpp @@ -0,0 +1,109 @@ +/* +** EPITECH PROJECT, 2024 +** arcade +** File description: +** NibblerGame.hpp +*/ + +#pragma once + +#include "common/game/AGame.hpp" +#include "games/nibbler/src/entities/nibbler/Nibbler.hpp" +#include "entities/apple/AppleEntity.hpp" +#include "common/components/SoundComponent.hpp" + +namespace arcade::games::nibbler { + class NibblerGame; +} + +class arcade::games::nibbler::NibblerGame : public arcade::games::common::AGame { +public: + NibblerGame(); + + ~NibblerGame() override = default; + + /** + * @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; + + /** + * @brief Set loose game state + * + * @param state If the game is loose or not + */ + void setLooseGame(bool state); + + /** + * @brief Add new point to player and re-generate an apple + */ + void addNewPoint(); + + /** + * @brief Change the state of a sound + * + * @param soundName Name of the sound + * @param state State of the sound + */ + void changeStateSound(const std::string &soundName, shared::games::components::SoundState state); + + /** + * @brief Change to a specific level + */ + void changeToLevel(int level); + + /** + * @brief Check if the direction is valid + * + * @param direction + * @return true + * @return false + */ + bool isValidDirection(Vector2i direction); + + unsigned int speedTime; + + unsigned int speedBoost; + + bool moved; + + bool canMakeChoice; + +protected: + /** + * @brief Execute the process of the end of the game when the player _loose + */ + void _loose(); + + /** + * @brief Prevent wall collision + */ + void _preventWallCollision(); + + typedef enum { + WALL, + SPACE, + } CellType; + + std::unique_ptr _nibbler; + std::shared_ptr _apple; + shared::games::DeltaTime _clock; + std::map> _map; + bool _looseGame; + int _currentScore; +}; diff --git a/games/nibbler/src/NibblerGameProvider.cpp b/games/nibbler/src/NibblerGameProvider.cpp new file mode 100644 index 0000000..50973f5 --- /dev/null +++ b/games/nibbler/src/NibblerGameProvider.cpp @@ -0,0 +1,19 @@ +/* +** EPITECH PROJECT, 2024 +** arcade +** File description: +** NibblerGameProvider.cpp +*/ + +#include "NibblerGame.hpp" +#include "NibblerGameProvider.hpp" + +using namespace arcade::games; + +const shared::games::GameManifest &nibbler::NibblerGameProvider::getManifest() const noexcept { + return NibblerGame::manifest; +} + +std::shared_ptr nibbler::NibblerGameProvider::createInstance() { + return std::make_shared(); +} diff --git a/games/nibbler/src/NibblerGameProvider.hpp b/games/nibbler/src/NibblerGameProvider.hpp new file mode 100644 index 0000000..fbd14b5 --- /dev/null +++ b/games/nibbler/src/NibblerGameProvider.hpp @@ -0,0 +1,35 @@ +/* +** EPITECH PROJECT, 2024 +** arcade +** File description: +** NibblerGameProvider.hpp +*/ + +#pragma once + +#include "shared/games/IGameProvider.hpp" + +namespace arcade::games::nibbler { + class NibblerGameProvider; +} + +class arcade::games::nibbler::NibblerGameProvider : public shared::games::IGameProvider { +public: + NibblerGameProvider() = default; + + ~NibblerGameProvider() 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/games/nibbler/src/entities/apple/AppleEntity.cpp b/games/nibbler/src/entities/apple/AppleEntity.cpp new file mode 100644 index 0000000..abe789c --- /dev/null +++ b/games/nibbler/src/entities/apple/AppleEntity.cpp @@ -0,0 +1,53 @@ +/* +** EPITECH PROJECT, 2024 +** AppleEntity.cpp +** File description: +** AppleEntity class +*/ + +#include +#include "AppleEntity.hpp" +#include "common/components/CollidableComponent.hpp" +#include "common/components/TextureComponent.hpp" +#include "../nibbler/HeadEntity.hpp" +#include "../nibbler/TailEntity.hpp" +#include "../../NibblerGame.hpp" + +using namespace arcade::games::nibbler; +using namespace arcade::games::common::components; + +arcade::games::nibbler::AppleEntity::AppleEntity(shared::types::Vector2u size): postion(size) { + this->_create(Vector2i(size.x, size.y)); +} + +void AppleEntity::_create(Vector2i position) { + shared::games::components::TextureProps textureProps = { + .sources = { + .ascii = "assets/nibbler/apple.ascii", + .bin = "assets/nibbler/apple.png", + .binTileSize = Vector2f(40, 40) + }, + .origin = Vector2u(0, 0) + }; + std::shared_ptr collision = std::make_shared(*this, this->_onCollide); + std::shared_ptr texture = std::make_shared(*this, Vector2u(1, 1), 9, + 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); +} + +void arcade::games::nibbler::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/nibbler/src/entities/apple/AppleEntity.hpp b/games/nibbler/src/entities/apple/AppleEntity.hpp new file mode 100644 index 0000000..36516f5 --- /dev/null +++ b/games/nibbler/src/entities/apple/AppleEntity.hpp @@ -0,0 +1,47 @@ +/* +** EPITECH PROJECT, 2024 +** AppleEntity.hpp +** File description: +** AppleEntity class +*/ + +#pragma once + +#include "common/entity/AEntity.hpp" +#include "shared/types/Vector.hpp" +#include "shared/games/components/ICollidableComponent.hpp" + +namespace arcade::games::nibbler { + class AppleEntity; +} + +class arcade::games::nibbler::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); + + shared::types::Vector2u postion; + +protected: + /** + * @brief Create the apple components + */ + void _create(Vector2i position); + + /** + * @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); + + +}; diff --git a/games/nibbler/src/entities/background/BackgroundEntity.cpp b/games/nibbler/src/entities/background/BackgroundEntity.cpp new file mode 100644 index 0000000..5ecc8e8 --- /dev/null +++ b/games/nibbler/src/entities/background/BackgroundEntity.cpp @@ -0,0 +1,38 @@ +/* +** EPITECH PROJECT, 2024 +** BackgroundEntity.cpp +** File description: +** BackgroundEntity class +*/ + +#include +#include +#include "BackgroundEntity.hpp" +#include "common/components/TextureComponent.hpp" + +using namespace arcade::games::nibbler; +using namespace arcade::games::common::components; + +arcade::games::nibbler::BackgroundEntity::BackgroundEntity(shared::types::Vector2u size) { + if (static_cast(size.x + size.y) % 2 == 0) + this->_addColor(Vector2i(size.x, size.y), Vector2u(1, 0)); + else + this->_addColor(Vector2i(size.x, size.y), Vector2u(2, 0)); +} + +void arcade::games::nibbler::BackgroundEntity::_addColor(shared::types::Vector2i position, shared::types::Vector2u origin) { + shared::games::components::TextureProps textureProps = { + .sources = { + .ascii = "assets/nibbler/wall.ascii", + .bin = "assets/nibbler/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/nibbler/src/entities/background/BackgroundEntity.hpp b/games/nibbler/src/entities/background/BackgroundEntity.hpp new file mode 100644 index 0000000..9922ed2 --- /dev/null +++ b/games/nibbler/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::nibbler { + class BackgroundEntity; +} + +class arcade::games::nibbler::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/nibbler/src/entities/nibbler/HeadEntity.cpp b/games/nibbler/src/entities/nibbler/HeadEntity.cpp new file mode 100644 index 0000000..3f51a59 --- /dev/null +++ b/games/nibbler/src/entities/nibbler/HeadEntity.cpp @@ -0,0 +1,180 @@ +/* +** EPITECH PROJECT, 2024 +** HeadEntity.cpp +** File description: +** HeadEntity class +*/ + +#include "NibblerGame.hpp" +#include "HeadEntity.hpp" +#include "../apple/AppleEntity.hpp" +#include "../wall/WallEntity.hpp" +#include "components/HeadKeyboardComponent.hpp" + +using namespace arcade::games::common::components; +using namespace shared::games::components; + +arcade::games::nibbler::HeadEntity::HeadEntity() : _textureProps( + arcade::games::nibbler::HeadEntity::_defaultTextureProps()), + direction(1, 0), + position(6, 10), + _previousDirection(1, 0) { + 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( + *this); + + this->sounds["up"] = std::make_shared(*this, "assets/snake/up.wav", SoundState::STOP, 100, false, arcade::games::nibbler::HeadEntity::_onSoundStateChangeUp); + this->sounds["down"] = std::make_shared(*this, "assets/snake/down.wav", SoundState::STOP, 100, false, arcade::games::nibbler::HeadEntity::_onSoundStateChangeDown); + this->sounds["left"] = std::make_shared(*this, "assets/snake/left.wav", SoundState::STOP, 100, false, arcade::games::nibbler::HeadEntity::_onSoundStateChangeLeft); + this->sounds["right"] = std::make_shared(*this, "assets/snake/right.wav", SoundState::STOP, 100, false, arcade::games::nibbler::HeadEntity::_onSoundStateChangeRight); + this->sounds["eat"] = std::make_shared(*this, "assets/snake/eat.wav", SoundState::STOP, 100, false, arcade::games::nibbler::HeadEntity::_onSoundStateChangeEat); + this->sounds["death"] = std::make_shared(*this, "assets/snake/death.wav", SoundState::STOP, 100, false, arcade::games::nibbler::HeadEntity::_onSoundStateChangeDeath); + for (auto &sound : this->sounds) { + this->_components.push_back(sound.second); + } + this->_components.push_back(collide); + this->_components.push_back(texture); + this->_components.push_back(keyboard); + this->reset(); +} + +shared::games::components::TextureProps arcade::games::nibbler::HeadEntity::_defaultTextureProps() { + return { + .sources = { + .ascii = "assets/nibbler/head.ascii", + .bin = "assets/nibbler/head.png", + .binTileSize = Vector2f(40, 40) + }, + .origin = Vector2u(3, 0) + }; +} + +void arcade::games::nibbler::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; + + 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; + } +} + +void arcade::games::nibbler::HeadEntity::setDirection(Vector2i dir) { + if (dir.x > 1 || dir.x < -1 || dir.y > 1 || dir.y < -1) + return; + this->_previousDirection = this->direction; + if (this->_previousDirection.x == dir.x && this->_previousDirection.y == dir.y) + return; + if (dir.x == 0 && dir.y == -1) { + this->sounds["up"]->setState(shared::games::components::SoundState::PLAY); + } else if (dir.x == 0 && dir.y == 1) { + this->sounds["down"]->setState(shared::games::components::SoundState::PLAY); + } else if (dir.x == -1 && dir.y == 0) { + this->sounds["left"]->setState(shared::games::components::SoundState::PLAY); + } else if (dir.x == 1 && dir.y == 0) { + this->sounds["right"]->setState(shared::games::components::SoundState::PLAY); + } + this->direction = dir; +} + +void arcade::games::nibbler::HeadEntity::_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->changeStateSound("death", SoundState::PLAY); + game->setLooseGame(true); + } +} + +void arcade::games::nibbler::HeadEntity::reset() { + this->direction = Vector2i(1, 0); + this->position = Vector2i(6, 17); + for (auto &component: this->_components) { + std::shared_ptr posCmp = std::dynamic_pointer_cast(component); + if (posCmp == nullptr) continue; + + posCmp->getPosition().x = this->position.x; + posCmp->getPosition().y = this->position.y; + } +} + +void arcade::games::nibbler::HeadEntity::_onSoundStateChangeUp(std::shared_ptr ctx, shared::games::components::SoundState state) +{ + auto game = std::dynamic_pointer_cast(ctx); + + if (!game) + return; + if (state == shared::games::components::SoundState::STOP) { + game->changeStateSound("up", shared::games::components::SoundState::STOP); + } +} + +void arcade::games::nibbler::HeadEntity::_onSoundStateChangeDown(std::shared_ptr ctx, shared::games::components::SoundState state) +{ + auto game = std::dynamic_pointer_cast(ctx); + + if (!game) + return; + if (state == shared::games::components::SoundState::STOP) + game->changeStateSound("down", shared::games::components::SoundState::STOP); +} + +void arcade::games::nibbler::HeadEntity::_onSoundStateChangeLeft(std::shared_ptr ctx, shared::games::components::SoundState state) +{ + auto game = std::dynamic_pointer_cast(ctx); + + if (!game) + return; + if (state == shared::games::components::SoundState::STOP) + game->changeStateSound("left", shared::games::components::SoundState::STOP); +} + +void arcade::games::nibbler::HeadEntity::_onSoundStateChangeRight(std::shared_ptr ctx, shared::games::components::SoundState state) +{ + auto game = std::dynamic_pointer_cast(ctx); + + if (!game) + return; + if (state == shared::games::components::SoundState::STOP) + game->changeStateSound("right", shared::games::components::SoundState::STOP); +} + +void arcade::games::nibbler::HeadEntity::_onSoundStateChangeEat(std::shared_ptr ctx, shared::games::components::SoundState state) +{ + auto game = std::dynamic_pointer_cast(ctx); + + if (!game) + return; + if (state == shared::games::components::SoundState::STOP) + game->changeStateSound("eat", shared::games::components::SoundState::STOP); +} + +void arcade::games::nibbler::HeadEntity::_onSoundStateChangeDeath(std::shared_ptr ctx, shared::games::components::SoundState state) +{ + auto game = std::dynamic_pointer_cast(ctx); + + if (!game) + return; + if (state == shared::games::components::SoundState::STOP) + game->changeStateSound("death", shared::games::components::SoundState::STOP); +} + diff --git a/games/nibbler/src/entities/nibbler/HeadEntity.hpp b/games/nibbler/src/entities/nibbler/HeadEntity.hpp new file mode 100644 index 0000000..7a66b61 --- /dev/null +++ b/games/nibbler/src/entities/nibbler/HeadEntity.hpp @@ -0,0 +1,126 @@ +/* +** EPITECH PROJECT, 2024 +** HeadEntity.hpp +** File description: +** HeadEntity class +*/ + +#pragma once + +#include +#include "common/entity/AEntity.hpp" +#include "common/components/CollidableComponent.hpp" +#include "common/components/TextureComponent.hpp" +#include "common/components/SoundComponent.hpp" + +namespace arcade::games::nibbler { + class NibblerGame; + + class HeadEntity; +} + +class arcade::games::nibbler::HeadEntity : public common::AEntity { +public: + ~HeadEntity() override = default; + + /** + * @brief Create the head of a nibbler + */ + explicit HeadEntity(); + + /** + * @brief Update the position of the head of the nibbler + */ + void forward(); + + /** + * @brief Direction of the nibbler head + */ + Vector2i direction; + + /** + * @brief Set the direction of the nibbler head + * @param dir Direction + */ + void setDirection(Vector2i dir); + + /** + * @brief Position of the nibbler head + */ + Vector2i position; + + /** + * @brief Set the head at default position + */ + void reset(); + + /// @brief Map of sounds + std::map> sounds; + +protected: + /** + * @brief Get default texture props + * @return Texture props + */ + static shared::games::components::TextureProps _defaultTextureProps(); + + /** + * @brief Represent the function that will be executed + * when the nibbler 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); + + Vector2i _previousDirection; + shared::games::components::TextureProps _textureProps; + + /** + * @brief On sound state change event UP + * + * @param ctx Game context + * @param state new state of the sound + */ + static void _onSoundStateChangeUp(std::shared_ptr ctx, shared::games::components::SoundState state); + + /** + * @brief On sound state change event DOWN + * + * @param ctx Game context + * @param state new state of the sound + */ + static void _onSoundStateChangeDown(std::shared_ptr ctx, shared::games::components::SoundState state); + + /** + * @brief On sound state change event LEFT + * + * @param ctx Game context + * @param state new state of the sound + */ + static void _onSoundStateChangeLeft(std::shared_ptr ctx, shared::games::components::SoundState state); + + /** + * @brief On sound state change event RIGHT + * + * @param ctx Game context + * @param state new state of the sound + */ + static void _onSoundStateChangeRight(std::shared_ptr ctx, shared::games::components::SoundState state); + + /** + * @brief On sound state change event EAT + * + * @param ctx Game context + * @param state new state of the sound + */ + static void _onSoundStateChangeEat(std::shared_ptr ctx, shared::games::components::SoundState state); + + /** + * @brief On sound state change event DEATH + * + * @param ctx Game context + * @param state new state of the sound + */ + static void _onSoundStateChangeDeath(std::shared_ptr ctx, shared::games::components::SoundState state); +}; diff --git a/games/nibbler/src/entities/nibbler/Nibbler.cpp b/games/nibbler/src/entities/nibbler/Nibbler.cpp new file mode 100644 index 0000000..89ff86b --- /dev/null +++ b/games/nibbler/src/entities/nibbler/Nibbler.cpp @@ -0,0 +1,75 @@ +/* +** EPITECH PROJECT, 2024 +** arcade +** File description: +** nibbler.cpp +*/ + +#include "Nibbler.hpp" +#include "TailEntity.hpp" +#include "HeadEntity.hpp" + +using namespace shared::games::entity; +using namespace arcade::games::nibbler; + +Nibbler::Nibbler(unsigned int tails) { + this->lastMove = std::chrono::milliseconds(900); + this->head = std::make_shared(); + this->_baseTails = tails; + + this->reset(); +} + +Nibbler::~Nibbler() = default; + +std::vector> &Nibbler::getTails() { + return this->_tails; +} + +std::shared_ptr Nibbler::addTail() { + std::shared_ptr newTail = std::make_shared(); + + this->_tails.push_back(newTail); + return newTail; +} + +void Nibbler::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)); + } +} + +void Nibbler::reset() { + this->head->reset(); + this->_tails.clear(); + + for (size_t i = 0; i < this->_baseTails; i++) { + this->addTail(); + this->forward(); + } +} diff --git a/games/nibbler/src/entities/nibbler/Nibbler.hpp b/games/nibbler/src/entities/nibbler/Nibbler.hpp new file mode 100644 index 0000000..3d8a26b --- /dev/null +++ b/games/nibbler/src/entities/nibbler/Nibbler.hpp @@ -0,0 +1,67 @@ +/* +** EPITECH PROJECT, 2024 +** arcade +** File description: +** nibbler.hpp +*/ + +#pragma once + +#include +#include +#include + +#include "common/game/AGame.hpp" +#include "shared/games/IEntity.hpp" +#include "HeadEntity.hpp" +#include "TailEntity.hpp" + +namespace arcade::games::nibbler { + class Nibbler; +} + +class arcade::games::nibbler::Nibbler { +public: + explicit Nibbler(unsigned int tails); + ~Nibbler(); + + /** + * @brief Head of the nibbler + * + */ + std::shared_ptr head; + + /** + * @brief Add a tail to the nibbler body + * + * @return The entity to the new tail + */ + std::shared_ptr addTail(); + + /** + * Get tails of the nibbler + * + * @return Vector of tails + */ + std::vector> &getTails(); + + /** + * @brief Reset the nibbler + */ + void reset(); + + /** + * @brief Update the position of the nibbler + */ + void forward(); + + shared::games::DeltaTime lastMove; +protected: + /** + * @brief Entities that compose the nibbler + * + */ + std::vector> _tails; + + unsigned int _baseTails; +}; diff --git a/games/nibbler/src/entities/nibbler/TailEntity.cpp b/games/nibbler/src/entities/nibbler/TailEntity.cpp new file mode 100644 index 0000000..0e94263 --- /dev/null +++ b/games/nibbler/src/entities/nibbler/TailEntity.cpp @@ -0,0 +1,56 @@ +/* +** EPITECH PROJECT, 2024 +** TailEntity.cpp +** File description: +** TailEntity class +*/ + +#include "TailEntity.hpp" + +using namespace arcade::games::common::components; +using namespace shared::games::components; + +arcade::games::nibbler::TailEntity::TailEntity() : _textureProps( + arcade::games::nibbler::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); + this->_components.push_back(collide); + this->_components.push_back(texture); +} + +shared::games::components::TextureProps arcade::games::nibbler::TailEntity::_defaultTextureProps() { + return { + .sources = { + .ascii = "assets/nibbler/tail.ascii", + .bin = "assets/nibbler/tail.png", + .binTileSize = Vector2f(40, 40) + }, + .origin = Vector2u(0, 0) + }; +} + +void arcade::games::nibbler::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; + } +} + +void arcade::games::nibbler::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::nibbler::TailEntity::getPosition() { + return this->_position; +} diff --git a/games/nibbler/src/entities/nibbler/TailEntity.hpp b/games/nibbler/src/entities/nibbler/TailEntity.hpp new file mode 100644 index 0000000..b37eed8 --- /dev/null +++ b/games/nibbler/src/entities/nibbler/TailEntity.hpp @@ -0,0 +1,51 @@ +/* +** EPITECH PROJECT, 2024 +** TailEntity.hpp +** File description: +** TailEntity class +*/ + +#pragma once + +#include "common/entity/AEntity.hpp" +#include "common/components/CollidableComponent.hpp" +#include "common/components/TextureComponent.hpp" + +namespace arcade::games::nibbler { + class TailEntity; +} + +class arcade::games::nibbler::TailEntity : public common::AEntity { +public: + ~TailEntity() override = default; + + explicit TailEntity(); + + /** + * @brief Set position of the tail + * @param position + */ + 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 + */ + Vector2i getPosition(); + +protected: + /** + * @brief Get default texture props + * @return Texture props + */ + static shared::games::components::TextureProps _defaultTextureProps(); + + shared::games::components::TextureProps _textureProps; + Vector2i _position; +}; diff --git a/games/nibbler/src/entities/nibbler/components/HeadKeyboardComponent.cpp b/games/nibbler/src/entities/nibbler/components/HeadKeyboardComponent.cpp new file mode 100644 index 0000000..3029a2e --- /dev/null +++ b/games/nibbler/src/entities/nibbler/components/HeadKeyboardComponent.cpp @@ -0,0 +1,83 @@ +/* +** EPITECH PROJECT, 2024 +** KeyboardComponent.cpp +** File description: +** HeadKeyboardComponent class +*/ + +#include "HeadKeyboardComponent.hpp" +#include "../../../NibblerGame.hpp" + +using namespace arcade::games::common::components; +using namespace arcade::games::nibbler::components; +using namespace shared::games::components; + +HeadKeyboardComponent::HeadKeyboardComponent(HeadEntity &entity) : AComponent(KEYBOARD, entity), _parent(entity), _previousDirection(1, 0) {} + +void HeadKeyboardComponent::onKeyPress(std::shared_ptr ctx, + shared::games::components::IKeyboardComponent::KeyData keyData) +{ + auto game = std::dynamic_pointer_cast(ctx); + + if (!game) + return; + if (!game->moved && keyData.type == ARROW) { + if (keyData.code.arrow == UP && this->_parent.direction.y != 1) { + auto dir = Vector2i(0, -1); + if (game->isValidDirection(dir)) { + this->_parent.setDirection(dir); + } + } + if (keyData.code.arrow == DOWN && this->_parent.direction.y != -1) { + auto dir = Vector2i(0, 1); + if (game->isValidDirection(dir)) { + this->_parent.setDirection(dir); + } + } + if (keyData.code.arrow == LEFT && this->_parent.direction.x != 1) { + auto dir = Vector2i(-1, 0); + if (game->isValidDirection(dir)) { + this->_parent.setDirection(dir); + } + } + if (keyData.code.arrow == RIGHT && this->_parent.direction.x != -1) { + auto dir = Vector2i(1, 0); + if (game->isValidDirection(dir)) { + this->_parent.setDirection(dir); + } + } + game->moved = true; + game->canMakeChoice = true; + } + if (!game->moved && keyData.type == CHAR) { + if (keyData.code.character == 'z' && this->_parent.direction.y != 1) { + auto dir = Vector2i(0, -1); + if (game->isValidDirection(dir)) + this->_parent.setDirection(dir); + } + if (keyData.code.character == 's' && this->_parent.direction.y != -1) { + auto dir = Vector2i(0, 1); + if (game->isValidDirection(dir)) + this->_parent.setDirection(dir); + } + if (keyData.code.character == 'q' && this->_parent.direction.x != 1) { + auto dir = Vector2i(-1, 0); + if (game->isValidDirection(dir)) + this->_parent.setDirection(dir); + } + if (keyData.code.character == 'd' && this->_parent.direction.x != -1) { + auto dir = Vector2i(1, 0); + if (game->isValidDirection(dir)) + this->_parent.setDirection(dir); + } + game->moved = true; + game->canMakeChoice = true; + } + if (keyData.type == CHAR && keyData.code.character == ' ') { + game->speedBoost = 3; + } +} + +void HeadKeyboardComponent::onKeyRelease(std::shared_ptr ctx, + shared::games::components::IKeyboardComponent::KeyData keyData) {} + diff --git a/games/nibbler/src/entities/nibbler/components/HeadKeyboardComponent.hpp b/games/nibbler/src/entities/nibbler/components/HeadKeyboardComponent.hpp new file mode 100644 index 0000000..fd356af --- /dev/null +++ b/games/nibbler/src/entities/nibbler/components/HeadKeyboardComponent.hpp @@ -0,0 +1,50 @@ +/* +** EPITECH PROJECT, 2024 +** HeadKeyboardComponent.hpp +** File description: +** HeadKeyboardComponent class +*/ + +#pragma once + +#include +#include "shared/games/components/IKeyboardComponent.hpp" +#include "common/components/AComponent.hpp" +#include "../HeadEntity.hpp" + +#include "common/components/SoundComponent.hpp" + +namespace arcade::games::nibbler::components { + class HeadKeyboardComponent; +} + +class arcade::games::nibbler::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::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; + +protected: + HeadEntity &_parent; + Vector2i _previousDirection; + +}; diff --git a/games/nibbler/src/entities/wall/WallEntity.cpp b/games/nibbler/src/entities/wall/WallEntity.cpp new file mode 100644 index 0000000..6ae9d3b --- /dev/null +++ b/games/nibbler/src/entities/wall/WallEntity.cpp @@ -0,0 +1,46 @@ +/* +** EPITECH PROJECT, 2024 +** WallEntity.cpp +** File description: +** WallEntity class +*/ + +#include +#include +#include "WallEntity.hpp" +#include "common/components/CollidableComponent.hpp" +#include "common/components/TextureComponent.hpp" + +using namespace arcade::games::nibbler; +using namespace arcade::games::common::components; + +WallEntity::WallEntity(shared::types::Vector2u size) { + this->_createWall(Vector2i(size.x, size.y)); +} + +void WallEntity::_createWall(shared::types::Vector2i position) { + shared::games::components::TextureProps textureProps = { + .sources = { + .ascii = "assets/nibbler/wall.ascii", + .bin = "assets/nibbler/wall.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), 11, + 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::WallException::WallException(const std::string &message) : _message(message) {} + +const char *WallEntity::WallException::what() const noexcept { + return this->_message.c_str(); +} diff --git a/games/nibbler/src/entities/wall/WallEntity.hpp b/games/nibbler/src/entities/wall/WallEntity.hpp new file mode 100644 index 0000000..0e826b7 --- /dev/null +++ b/games/nibbler/src/entities/wall/WallEntity.hpp @@ -0,0 +1,40 @@ +/* +** 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::nibbler { + class WallEntity; +} + +class arcade::games::nibbler::WallEntity : public common::AEntity { +public: + ~WallEntity() override = default; + + explicit WallEntity(shared::types::Vector2u size); + + class WallException : public std::exception { + public: + WallException(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); +}; diff --git a/shared/Doxyfile b/shared/Doxyfile new file mode 100644 index 0000000..803fea5 --- /dev/null +++ b/shared/Doxyfile @@ -0,0 +1,5 @@ +INPUT = . +RECURSIVE = YES +GENERATE_LATEX = NO +PROJECT_NAME = "Arcade Shared" +USE_MDFILE_AS_MAINPAGE = "README.md" diff --git a/shared/README.md b/shared/README.md index bf34730..6d6163d 100644 --- a/shared/README.md +++ b/shared/README.md @@ -9,3 +9,30 @@ This library contains shared code for the Arcade project in order to unify inter - **[Carapace Retro](https://github.com/G-Epitech)** : [Baptiste Moreau](https://github.com/BxptisteM), [Axel Fradet](https://github.com/AxelF44) & [Suceveanu Dragos](https://github.com/sdragos1) +## How ? + +Our arcade simulator relies on a modular development model, utilizing dynamic libraries to separate game logic from graphical display. This system revolves around two types of libraries: game libraries and graphical libraries. These two libraries operate entirely independently, focusing solely on the principle of getters and setters for data manipulation. + +1. Game Libraries: + +Game libraries are responsible for managing the internal game logic, including gameplay mechanics, collisions, levels, and more. They provide functionalities through getter and setter methods, allowing developers to access and modify game data as needed. + +2. Graphical Libraries: + +On the other hand, graphical libraries handle the visual display of the game. They include features such as sprite rendering, animation management, and special effects. These libraries also interact with the simulator solely through getter and setter methods, enabling the modification of visual properties of game elements. + +3. Core: + +To ensure consistency and communication between game libraries and graphical libraries, a "core" is necessary. This core acts as a central liaison, coordinating game data with graphical display. It retrieves information about the game state from game libraries and passes it to graphical libraries for display. Similarly, it monitors user interactions and updates game data accordingly, ensuring a smooth gaming experience. + +In summary, our arcade simulator relies on a modular development model where game libraries, graphical libraries, and the core interact independently, providing maximum flexibility and enabling developers to create unique and dynamic gaming experiences. + +## Documentation + +If you want the code documentation you can run this command : + +```bash +doxygen Doxyfile +``` + +This command allow you to generate Doxygen documentation. diff --git a/shared/games/IEntity.hpp b/shared/games/IEntity.hpp index 9741616..d0df623 100644 --- a/shared/games/IEntity.hpp +++ b/shared/games/IEntity.hpp @@ -10,35 +10,38 @@ #include #include -namespace shared::games -{ - class IGame; +namespace shared::games { + class IGame; - namespace entity - { - class IEntity; + namespace entity { + class IEntity; - typedef std::shared_ptr EntityPtr; - typedef std::vector EntitiesMap; - } + /// @brief Entity pointer + typedef std::shared_ptr EntityPtr; + /// @brief Entities map pointers + typedef std::vector EntitiesMap; + } - namespace components - { - class IComponent; + namespace components { + class IComponent; - typedef std::vector> ComponentsMap; - } + /// @brief Components map pointers + typedef std::vector> ComponentsMap; + } } -class shared::games::entity::IEntity -{ +/** + * @brief Interface of an entity + * + */ +class shared::games::entity::IEntity { public: - virtual ~IEntity() = default; - - /** - * @brief Get the components of the entity - * - * @return Components of the entity - */ - virtual const components::ComponentsMap &getComponents(void) const noexcept = 0; + virtual ~IEntity() = default; + + /** + * @brief Get the components of the entity + * + * @return Components of the entity + */ + virtual const components::ComponentsMap &getComponents(void) const noexcept = 0; }; diff --git a/shared/games/IGame.hpp b/shared/games/IGame.hpp index 956baab..c03b9ef 100644 --- a/shared/games/IGame.hpp +++ b/shared/games/IGame.hpp @@ -15,58 +15,61 @@ using namespace shared::types; -namespace shared::games -{ - class IGame; +namespace shared::games { + class IGame; - typedef std::chrono::duration DeltaTime; + /// @brief Delta time in milliseconds + typedef std::chrono::duration DeltaTime; } -class shared::games::IGame -{ +/** + * @brief Interface of a game + * + */ +class shared::games::IGame { public: - virtual ~IGame() = default; + virtual ~IGame() = default; - /** - * @brief Compute the game each tick of the program - * - * @param dt Time since last tick (Time in `milliseconds`) - */ - virtual void compute(DeltaTime dt) = 0; + /** + * @brief Compute the game each tick of the program + * + * @param dt Time since last tick (Time in `milliseconds`) + */ + virtual void compute(DeltaTime dt) = 0; - /** - * @brief Manifest with informations of the game - * - * @return Manifest of the game - */ - virtual const GameManifest &getManifest() const noexcept = 0; + /** + * @brief Manifest with informations of the game + * + * @return Manifest of the game + */ + 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() 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() const noexcept = 0; - /** - * @brief Get fps of the game - * - * @return The number of frame per seconds of the game - */ - virtual const unsigned int getFps() const noexcept = 0; + /** + * @brief Get fps of the game + * + * @return The number of frame per seconds of the game + */ + virtual const unsigned int getFps() const noexcept = 0; - /** - * @brief Get map of entities - * - * @return Entities map of the game - */ - virtual const entity::EntitiesMap &getEntities(void) const = 0; + /** + * @brief Get map of entities + * + * @return Entities map of the game + */ + virtual const entity::EntitiesMap &getEntities(void) const = 0; - /** - * @brief Get the score of the game - * - * @return The score of the game - */ - virtual const int getScore() const noexcept = 0; + /** + * @brief Get the score of the game + * + * @return The score of the game + */ + virtual const int getScore() const noexcept = 0; }; diff --git a/shared/games/IGameProvider.hpp b/shared/games/IGameProvider.hpp index ddb2bcd..2db5dd3 100644 --- a/shared/games/IGameProvider.hpp +++ b/shared/games/IGameProvider.hpp @@ -15,22 +15,25 @@ namespace shared::games { class IGameProvider; } -class shared::games::IGameProvider -{ +/** + * @brief Interface of a game provider + * + */ +class shared::games::IGameProvider { public: - virtual ~IGameProvider() = default; + virtual ~IGameProvider() = default; - /** - * @brief Provides the game manifest - * - * @return Manifest of current game - */ - virtual const GameManifest &getManifest() const noexcept = 0; + /** + * @brief Provides the game manifest + * + * @return Manifest of current game + */ + virtual const GameManifest &getManifest() const noexcept = 0; - /** - * @brief Provides a new instance of the game - * - * @return Created game instance - */ - virtual std::shared_ptr createInstance(void) = 0; + /** + * @brief Provides a new instance of the game + * + * @return Created game instance + */ + virtual std::shared_ptr createInstance(void) = 0; }; diff --git a/shared/games/components/ICollidableComponent.hpp b/shared/games/components/ICollidableComponent.hpp index feec546..0363665 100644 --- a/shared/games/components/ICollidableComponent.hpp +++ b/shared/games/components/ICollidableComponent.hpp @@ -12,18 +12,21 @@ #include "../../types/Vector.hpp" namespace shared::games::components { - class ICollidableComponent; + class ICollidableComponent; } -class shared::games::components::ICollidableComponent: public virtual IPositionableComponent -{ +/** + * @brief Interface of a collidable component + * + */ +class shared::games::components::ICollidableComponent: public virtual IPositionableComponent { public: - virtual ~ICollidableComponent() = default; + virtual ~ICollidableComponent() = default; - /** - * @brief On collide event handler for the component - * @param ctx Context of the game - * @param target Target entity - */ - virtual void onCollide(std::shared_ptr ctx, std::shared_ptr target) = 0; + /** + * @brief On collide event handler for the component + * @param ctx Context of the game + * @param target Target entity + */ + virtual void onCollide(std::shared_ptr ctx, std::shared_ptr target) = 0; }; diff --git a/shared/games/components/IComponent.hpp b/shared/games/components/IComponent.hpp index db6c260..d2299fa 100644 --- a/shared/games/components/IComponent.hpp +++ b/shared/games/components/IComponent.hpp @@ -10,19 +10,32 @@ #include "../IEntity.hpp" namespace shared::games::components { + + /// @brief Enum of component types typedef enum { - TEXTURE, - TEXT, - DISPLAYABLE, - SOUND, - COLLIDABLE, - POSITIONABLE, - KEYBOARD + /// @brief Component type for a texture + TEXTURE, + /// @brief Component type for a text + TEXT, + /// @brief Component type for a displayable + DISPLAYABLE, + /// @brief Component type for a sound + SOUND, + /// @brief Component type for a collidable + COLLIDABLE, + /// @brief Component type for a positionable + POSITIONABLE, + /// @brief Component type for a keyboard + KEYBOARD } ComponentType; class IComponent; } +/** + * @brief Interface of a component + * + */ class shared::games::components::IComponent { public: virtual ~IComponent() = default; diff --git a/shared/games/components/IDisplayableComponent.hpp b/shared/games/components/IDisplayableComponent.hpp index df1f6b1..d16d4ae 100644 --- a/shared/games/components/IDisplayableComponent.hpp +++ b/shared/games/components/IDisplayableComponent.hpp @@ -15,6 +15,10 @@ namespace shared::games::components { class IDisplayableComponent; } +/** + * @brief Interface of a displayable component + * + */ class shared::games::components::IDisplayableComponent : public virtual IPositionableComponent { public: virtual ~IDisplayableComponent() = default; @@ -22,6 +26,7 @@ class shared::games::components::IDisplayableComponent : public virtual IPositio /** * @brief Get Z index that is usefull for display prioroty * + * @return Z index of the entity */ virtual unsigned int &getZIndex() noexcept = 0; diff --git a/shared/games/components/IKeyboardComponent.hpp b/shared/games/components/IKeyboardComponent.hpp index a6bb8f8..0606528 100644 --- a/shared/games/components/IKeyboardComponent.hpp +++ b/shared/games/components/IKeyboardComponent.hpp @@ -11,63 +11,85 @@ #include "IComponent.hpp" namespace shared::games::components { - class IKeyboardComponent; + class IKeyboardComponent; } -class shared::games::components::IKeyboardComponent: public virtual IComponent -{ +/** + * @brief Interface of a keyboard component + * + */ +class shared::games::components::IKeyboardComponent: public virtual IComponent { public: - 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; + /// @brief Type of the key + typedef enum { + /// @brief Control key (`Ctrl`, `Shift`, `Alt`) + CONTROL, + /// @brief Arrow key (`Up`, `Down`, `Left`, `Right`) + ARROW, + /// @brief Function key (`F1`, `F2`, `F3`, etc.) + FUNC, + /// @brief Character key (`a`, `1`, `&`, etc.) + CHAR, + /// @brief Unknown key + UNKNOWN + } KeyType; - typedef enum - { - UP, // `Up` arrow key - DOWN, // `Down` arrow key - LEFT, // `Left` arrow key - RIGHT // `Right` arrow key - } ArrowCode; + /// @brief Control key code + typedef enum { + /// @brief `Ctrl` key + CTRL, + /// @brief `Shift` key + SHIFT, + /// @brief `Alt` key + ALT + } ControlCode; - typedef union - { - ControlCode control; // Control key - ArrowCode arrow; // Arrow key - char character; // ASCII character value - unsigned char func; // Function key number - } KeyCode; + /// @brief Arrow key code + typedef enum { + /// @brief `Up` arrow key + UP, + /// @brief `Down` arrow key + DOWN, + /// @brief `Left` arrow key + LEFT, + /// @brief `Right` arrow key + RIGHT + } ArrowCode; - typedef struct - { - KeyCode code; // Key code. Interpretation depends on the type - KeyType type; // Type of the key - } KeyData; + /// @brief Function key code union + typedef union { + /// @brief Function key number + ControlCode control; + /// @brief Control key code + ArrowCode arrow; + /// @brief Arrow key code + char character; + /// @brief Character key code + unsigned char func; + } KeyCode; - virtual ~IKeyboardComponent() = default; + /// @brief Key data + typedef struct { + /// @brief Key code. Interpretation depends on the type + KeyCode code; + /// @brief Type of the key + KeyType type; + } KeyData; - /** - * @brief On key pressed event handler for the entity - * @param ctx Context of the game - * @param keyData Key data of key pressed - */ - virtual void onKeyPress(std::shared_ptr ctx, KeyData keyData) = 0; + virtual ~IKeyboardComponent() = default; - /** - * @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; + /** + * @brief On key pressed event handler for the entity + * @param ctx Context of the game + * @param keyData Key data of key pressed + */ + 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; }; diff --git a/shared/games/components/IPositionableComponent.hpp b/shared/games/components/IPositionableComponent.hpp index 8cf9edb..4f1f743 100644 --- a/shared/games/components/IPositionableComponent.hpp +++ b/shared/games/components/IPositionableComponent.hpp @@ -11,12 +11,15 @@ #include "../../types/Vector.hpp" namespace shared::games::components { - class IPositionableComponent; + class IPositionableComponent; } -class shared::games::components::IPositionableComponent: public virtual IComponent -{ - public: +/** + * @brief Interface of a positionable component + * + */ +class shared::games::components::IPositionableComponent: public virtual IComponent { +public: virtual ~IPositionableComponent() = default; /** diff --git a/shared/games/components/ISoundComponent.hpp b/shared/games/components/ISoundComponent.hpp index 43d6f02..a18704e 100644 --- a/shared/games/components/ISoundComponent.hpp +++ b/shared/games/components/ISoundComponent.hpp @@ -12,56 +12,63 @@ #include "../../types/Vector.hpp" namespace shared::games::components { - class ISoundComponent; + class ISoundComponent; - typedef enum - { - PLAY, - PAUSE, - STOP - } SoundState; + /// @brief State of the sound + typedef enum { + /// @brief Sound is playing + PLAY, + /// @brief Sound is paused + PAUSE, + /// @brief Sound is stopped + STOP + } SoundState; - typedef unsigned char SoundVolume; + /// @brief Volume of the sound + typedef unsigned char SoundVolume; } -class shared::games::components::ISoundComponent: public virtual IComponent -{ +/** + * @brief Interface of a sound component + * + */ +class shared::games::components::ISoundComponent: public virtual IComponent { public: - virtual ~ISoundComponent() = default; + virtual ~ISoundComponent() = default; - /** - * @brief Get path of the sound - * - * @return Sound path - */ - virtual const std::string &getPath() const noexcept = 0; + /** + * @brief Get path of the sound + * + * @return Sound path + */ + virtual const std::string &getPath() const noexcept = 0; - /** - * @brief Get state of the sound - * - * @return Sound state - */ - virtual SoundState &getState() noexcept = 0; + /** + * @brief Get state of the sound + * + * @return Sound state + */ + virtual SoundState &getState() noexcept = 0; - /** - * @brief Get volume of the sound - * - * @return Sound volume - */ - virtual SoundVolume &getVolume() noexcept = 0; + /** + * @brief Get volume of the sound + * + * @return Sound volume + */ + virtual SoundVolume &getVolume() noexcept = 0; - /** - * @brief Get loop of the sound - * - * @return Sound loop - */ - virtual bool &getLoop() noexcept = 0; + /** + * @brief Get loop of the sound + * + * @return Sound loop + */ + virtual bool &getLoop() noexcept = 0; - /** - * @brief On state change event handler for the component - * - * @param ctx Context of the game - * @param state New state of the sound - */ - virtual void onStateChange(std::shared_ptr ctx, SoundState state) = 0; + /** + * @brief On state change event handler for the component + * + * @param ctx Context of the game + * @param state New state of the sound + */ + virtual void onStateChange(std::shared_ptr ctx, SoundState state) = 0; }; diff --git a/shared/games/components/ITextComponent.hpp b/shared/games/components/ITextComponent.hpp index 64dd5cf..7015b7c 100644 --- a/shared/games/components/ITextComponent.hpp +++ b/shared/games/components/ITextComponent.hpp @@ -15,31 +15,53 @@ namespace shared::games::components { class ITextComponent; } +/** + * @brief Interface of a text component + * + */ class shared::games::components::ITextComponent : public virtual IDisplayableComponent { public: + + /// @brief Horizontal text alignment typedef enum { + /// @brief Align text to the left LEFT, + /// @brief Align text to the center CENTER, + /// @brief Align text to the right RIGHT } TextAlign; + /// @brief Vertical text alignment typedef enum { + /// @brief Align text to the bottom BOTTOM, + /// @brief Align text to the middle MIDDLE, + /// @brief Align text to the top TOP } TextVerticalAlign; + /// @brief Font properties typedef struct { - std::string path; // Path of the font - unsigned int size; // Font size + /// @brief Path of the font + std::string path; + /// @brief Size of the font + unsigned int size; } TextFontProps; + /// @brief Text properties 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 + /// @brief Content of the text + std::string content; + /// @brief Horizontal alignment of the text + TextAlign align; + /// @brief Vertical alignment of the text + TextVerticalAlign verticalAlign; + /// @brief Font of the text + TextFontProps font; + /// @brief Color of the text + types::Color color; } TextProps; virtual ~ITextComponent() = default; diff --git a/shared/games/components/ITextureComponent.hpp b/shared/games/components/ITextureComponent.hpp index 930215c..35d2755 100644 --- a/shared/games/components/ITextureComponent.hpp +++ b/shared/games/components/ITextureComponent.hpp @@ -14,18 +14,29 @@ namespace shared::games::components { class ITextureComponent; + /// @brief Texture sources typedef struct { - const std::string ascii; // ASCII image representation path - const std::string bin; // Binary image path - Vector2f binTileSize; // Size of the binary tile + /// @brief ASCII image representation path + const std::string ascii; + /// @brief Binary image path + const std::string bin; + /// @brief Size of the binary tile + Vector2f binTileSize; } TextureSources; + /// @brief Texture properties typedef struct { - TextureSources sources; // Sources of textures - Vector2u origin; // Origin of the texture + /// @brief Sources of textures + TextureSources sources; + /// @brief Size of the texture + Vector2u origin; } TextureProps; } +/** + * @brief Interface of a texture component + * + */ class shared::games::components::ITextureComponent : public virtual IDisplayableComponent { public: virtual ~ITextureComponent() = default; @@ -33,6 +44,7 @@ class shared::games::components::ITextureComponent : public virtual IDisplayable /** * @brief Get texture properties * + * @return TextureProps &Texture properties */ virtual TextureProps &getTextureProps() noexcept = 0; }; diff --git a/shared/games/types/GameManifest.hpp b/shared/games/types/GameManifest.hpp index 25da00a..3040ac2 100644 --- a/shared/games/types/GameManifest.hpp +++ b/shared/games/types/GameManifest.hpp @@ -11,17 +11,28 @@ #include namespace shared::games { + + /// @brief Author of the game 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.) + /// @brief Name of the author + std::string name; + /// @brief Public contact email + std::string email; + /// @brief Website of the author (`github`, `gitlab`, etc.) + std::string website; } Author; + /// @brief Game manifest 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 + /// @brief Name of the game + const std::string name; + /// @brief Description of the game + const std::string description; + /// @brief Version of the game + const std::string version; + /// @brief List of authors of the game + const std::vector authors; + /// @brief Path of the icon game + const std::string iconPath; } GameManifest; } diff --git a/shared/graphics/IFont.hpp b/shared/graphics/IFont.hpp index 63b7829..eaae7ad 100644 --- a/shared/graphics/IFont.hpp +++ b/shared/graphics/IFont.hpp @@ -11,7 +11,11 @@ namespace shared::graphics { class IFont; } +/** + * @brief Interface of a font + * + */ class shared::graphics::IFont { - public: - virtual ~IFont() = default; + public: + virtual ~IFont() = default; }; diff --git a/shared/graphics/IGraphicsProvider.hpp b/shared/graphics/IGraphicsProvider.hpp index 4200a5c..10a6ea4 100644 --- a/shared/graphics/IGraphicsProvider.hpp +++ b/shared/graphics/IGraphicsProvider.hpp @@ -15,11 +15,15 @@ #include "types/GraphicsManifest.hpp" namespace shared::graphics { - class IGraphicsProvider; + class IGraphicsProvider; } +/** + * @brief Interface for the graphics provider + * + */ class shared::graphics::IGraphicsProvider { - public: +public: virtual ~IGraphicsProvider() = default; /** diff --git a/shared/graphics/ISound.hpp b/shared/graphics/ISound.hpp index 00da6af..52d903e 100644 --- a/shared/graphics/ISound.hpp +++ b/shared/graphics/ISound.hpp @@ -7,21 +7,28 @@ #pragma once -namespace shared::graphics -{ - class ISound; +namespace shared::graphics { + class ISound; } +/** + * @brief Interface for the sound object + * + */ class shared::graphics::ISound { - public: +public: virtual ~ISound() = default; + /// @brief Sound volume typedef unsigned char SoundVolume; - typedef enum - { + /// @brief Sound state + typedef enum { + /// @brief Sound is playing PLAY, + /// @brief Sound is paused PAUSE, + /// @brief Sound is stopped STOP } SoundState; @@ -29,7 +36,6 @@ class shared::graphics::ISound { * @brief Get the state of the sound * * @param state State of sound playing - * @return SoundState */ virtual void setState(SoundState state) = 0; diff --git a/shared/graphics/ITexture.hpp b/shared/graphics/ITexture.hpp index f82f3e8..b6ac3ff 100644 --- a/shared/graphics/ITexture.hpp +++ b/shared/graphics/ITexture.hpp @@ -11,7 +11,11 @@ namespace shared::graphics { class ITexture; } +/** + * @brief Interface for the texture object + * + */ class shared::graphics::ITexture { - public: +public: virtual ~ITexture() = default; }; diff --git a/shared/graphics/IWindow.hpp b/shared/graphics/IWindow.hpp index ac1746a..0a2ebe7 100644 --- a/shared/graphics/IWindow.hpp +++ b/shared/graphics/IWindow.hpp @@ -18,25 +18,43 @@ using namespace shared::types; namespace shared::graphics { - class IWindow; + class IWindow; } +/** + * @brief Interface for the window object + * + */ class shared::graphics::IWindow { public: virtual ~IWindow() = default; - typedef enum - { - WINDOWED, - FULLSCREEN + /** + * @brief Window mode + * + */ + typedef enum { + /// @brief Windowed mode + WINDOWED, + /// @brief Fullscreen mode + FULLSCREEN } WindowMode; + /** + * @brief Window initial properties + * + */ 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 + /// @brief Initial size of the window + Vector2u size; + /// @brief Initial mode of the window + WindowMode mode; + /// @brief Initial framerate of the window + unsigned int fps; + /// @brief Initial title of the window + const std::string title; + /// @brief Initial icon of the window + const std::string icon; } WindowInitProps; /** diff --git a/shared/graphics/events/IEvent.hpp b/shared/graphics/events/IEvent.hpp index 84c9492..cf48dbf 100644 --- a/shared/graphics/events/IEvent.hpp +++ b/shared/graphics/events/IEvent.hpp @@ -9,27 +9,37 @@ #include -namespace shared::graphics::events -{ - class IEvent; +namespace shared::graphics::events { + class IEvent; - typedef enum - { - KEY_PRESS, // Key pressed - KEY_RELEASE, // Key released - MOUSE_BTN_PRESS, // Mouse button pressed - MOUSE_BTN_RELEASE, // Mouse button released - MOUSE_MOVE, // Mouse moved - WINDOW_CLOSE, // Window closed - WINDOW_RESIZE, // Window resized - } EventType; + /// @brief Event type + typedef enum { + /// @brief Key pressed + KEY_PRESS, + /// @brief Key released + KEY_RELEASE, + /// @brief Mouse button pressed + MOUSE_BTN_PRESS, + /// @brief Mouse button released + MOUSE_BTN_RELEASE, + /// @brief Mouse moved + MOUSE_MOVE, + /// @brief Window closed + WINDOW_CLOSE, + /// @brief Window resized + WINDOW_RESIZE, + } EventType; - typedef std::shared_ptr EventPtr; + /// @brief Event pointer + typedef std::shared_ptr EventPtr; } -class shared::graphics::events::IEvent -{ - public: +/** + * @brief Interface for the event object + * + */ +class shared::graphics::events::IEvent { +public: virtual ~IEvent() = default; /** diff --git a/shared/graphics/events/IKeyEvent.hpp b/shared/graphics/events/IKeyEvent.hpp index 81fe453..786bce1 100644 --- a/shared/graphics/events/IKeyEvent.hpp +++ b/shared/graphics/events/IKeyEvent.hpp @@ -13,36 +13,60 @@ namespace shared::graphics::events { class IKeyEvent; } +/** + * @brief Interface for the key event object + * + */ class shared::graphics::events::IKeyEvent : public virtual IEvent { public: virtual ~IKeyEvent() = default; + /// @brief Key type 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 + /// @brief Control key (`Ctrl`, `Shift`, `Alt`) + CONTROL, + /// @brief Arrow key (`Up`, `Down`, `Left`, `Right`) + ARROW, + /// @brief Function key (`F1`, `F2`, `F3`, etc.) + FUNC, + /// @brief ASCII character key + CHAR, + /// @brief Unknown key + UNKNOWN } KeyType; + /// @brief Control key code typedef enum { - CTRL, // `Ctrl` key - SHIFT, // `Shift` key - ALT // `Alt` key + /// @brief CTRL key + CTRL, + /// @brief SHIFT key + SHIFT, + /// @brief ALT key + ALT } ControlCode; + /// @brief Arrow key code typedef enum { - UP, // `Up` arrow key - DOWN, // `Down` arrow key - LEFT, // `Left` arrow key - RIGHT // `Right` arrow key + /// @brief UP arrow key + UP, + /// @brief DOWN arrow key + DOWN, + /// @brief LEFT arrow key + LEFT, + /// @brief RIGHT arrow key + RIGHT } ArrowCode; + /// @brief Key code typedef union { - ControlCode control; // Control key - ArrowCode arrow; // Arrow key - char character; // ASCII character value - unsigned char func; // Function key number + /// @brief Control key + ControlCode control; + /// @brief Arrow key + ArrowCode arrow; + /// @brief ASCII character value + char character; + /// @brief Function key number + unsigned char func; } KeyCode; /** diff --git a/shared/graphics/events/IMouseButtonEvent.hpp b/shared/graphics/events/IMouseButtonEvent.hpp index bac5eba..b6bbd4d 100644 --- a/shared/graphics/events/IMouseButtonEvent.hpp +++ b/shared/graphics/events/IMouseButtonEvent.hpp @@ -13,10 +13,15 @@ namespace shared::graphics::events{ class IMouseButtonEvent; } +/** + * @brief Interface for the mouse button event object + * + */ class shared::graphics::events::IMouseButtonEvent : public virtual IMouseEvent { public: virtual ~IMouseButtonEvent() = default; + /// @brief Mouse button typedef enum { LEFT, RIGHT diff --git a/shared/graphics/events/IMouseEvent.hpp b/shared/graphics/events/IMouseEvent.hpp index c8d6b03..193955d 100644 --- a/shared/graphics/events/IMouseEvent.hpp +++ b/shared/graphics/events/IMouseEvent.hpp @@ -14,6 +14,10 @@ namespace shared::graphics::events { class IMouseEvent; } +/** + * @brief Interface for the mouse event object + * + */ 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 index 7b875e6..c07f64c 100644 --- a/shared/graphics/exceptions/IFontException.hpp +++ b/shared/graphics/exceptions/IFontException.hpp @@ -13,6 +13,10 @@ namespace shared::graphics::exceptions { class IFontException; } +/** + * @brief Interface for the font exception object + * + */ 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 index a899775..3002ab2 100644 --- a/shared/graphics/exceptions/IGraphicsException.hpp +++ b/shared/graphics/exceptions/IGraphicsException.hpp @@ -13,6 +13,10 @@ namespace shared::graphics::exceptions { class IGraphicsException; } +/** + * @brief Interface for the graphics exception object + * + */ class shared::graphics::exceptions::IGraphicsException: public std::exception { public: /** diff --git a/shared/graphics/exceptions/ISoundException.hpp b/shared/graphics/exceptions/ISoundException.hpp index 2a2e534..572c681 100644 --- a/shared/graphics/exceptions/ISoundException.hpp +++ b/shared/graphics/exceptions/ISoundException.hpp @@ -13,6 +13,10 @@ namespace shared::graphics::exceptions { class ISoundException; } +/** + * @brief Interface for the sound exception object + * + */ 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 index e894b71..fd7754f 100644 --- a/shared/graphics/exceptions/ITextureException.hpp +++ b/shared/graphics/exceptions/ITextureException.hpp @@ -13,6 +13,10 @@ namespace shared::graphics::exceptions { class ITextureException; } +/** + * @brief Interface for the texture exception object + * + */ 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 index ae030f3..a42abac 100644 --- a/shared/graphics/exceptions/IWindowException.hpp +++ b/shared/graphics/exceptions/IWindowException.hpp @@ -13,6 +13,10 @@ namespace shared::graphics::exceptions { class IWindowException; } +/** + * @brief Interface for the window exception object + * + */ class shared::graphics::exceptions::IWindowException : public virtual IGraphicsException { public: virtual ~IWindowException() = default; diff --git a/shared/graphics/types/GraphicsManifest.hpp b/shared/graphics/types/GraphicsManifest.hpp index fc45e15..57354e8 100644 --- a/shared/graphics/types/GraphicsManifest.hpp +++ b/shared/graphics/types/GraphicsManifest.hpp @@ -11,18 +11,25 @@ namespace shared::graphics { - 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; + /// @brief Author of the graphics library + typedef struct { + /// @brief Name of the author + std::string name; + /// @brief Public contact email + std::string email; + /// @brief Website of the author (`github`, `gitlab`, etc.) + std::string website; + } Author; - typedef struct - { - const std::string name; // Name of the graphics library - const std::string description; // Description of the library - const std::string version; // Version of the library - const std::vector authors; // Authors - } GraphicsManifest; + /// @brief Graphics library manifest + typedef struct { + /// @brief Name of the graphics library + const std::string name; + /// @brief Description of the graphics library + const std::string description; + /// @brief Version of the graphics library + const std::string version; + /// @brief List of authors of the graphics library + const std::vector authors; + } GraphicsManifest; } diff --git a/shared/graphics/types/TextProps.hpp b/shared/graphics/types/TextProps.hpp index d405473..3c3828e 100644 --- a/shared/graphics/types/TextProps.hpp +++ b/shared/graphics/types/TextProps.hpp @@ -17,26 +17,44 @@ using namespace shared::types; namespace shared::graphics { + + /// @brief Horizontal alignment of the text typedef enum { + /// @brief Left alignment LEFT, + /// @brief Center alignment CENTER, + /// @brief Right alignment RIGHT } TextAlign; + /// @brief Vertical alignment of the text typedef enum { + /// @brief Bottom alignment BOTTOM, + /// @brief Middle alignment MIDDLE, + /// @brief Top alignment TOP } TextVerticalAlign; + /// @brief Text properties typedef struct { - 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 - types::Color color; // Color of the text - Vector2u size; // Size of the entity - Vector2f position; // Position of the entity + /// @brief Font of the text + std::shared_ptr font; + /// @brief Font size + unsigned int fontSize; + /// @brief Content of the text + std::string content; + /// @brief Horizontal alignment of the text + TextAlign align; + /// @brief Vertical alignment of the text + TextVerticalAlign verticalAlign; + /// @brief Color of the text + types::Color color; + /// @brief Size of the entity + Vector2u size; + /// @brief Position of the entity + Vector2f position; } TextProps; } diff --git a/shared/graphics/types/TextureProps.hpp b/shared/graphics/types/TextureProps.hpp index 5d72157..4b05664 100644 --- a/shared/graphics/types/TextureProps.hpp +++ b/shared/graphics/types/TextureProps.hpp @@ -15,11 +15,18 @@ using namespace shared::types; namespace shared::graphics { + + /// @brief Texture properties 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 - Vector2f position; // Position of the entity + /// @brief Texture of the entity + std::shared_ptr texture; + /// @brief Size of a binary tile + Vector2f binTileSize; + /// @brief Origin of the texture + Vector2u origin; + /// @brief Size of the entity + Vector2u size; + /// @brief Position of the entity + Vector2f position; } TextureProps; } diff --git a/shared/types/Color.hpp b/shared/types/Color.hpp index b6fe6e2..1d9d49f 100644 --- a/shared/types/Color.hpp +++ b/shared/types/Color.hpp @@ -9,7 +9,16 @@ namespace shared::types { + /// @brief Color type typedef struct ColorType { + /** + * @brief Construct a new Color Type object + * + * @param r Red color value + * @param g Green color value + * @param b Blue color value + * @param a Alpha color value + */ ColorType( unsigned char r, unsigned char g, @@ -17,9 +26,28 @@ namespace shared::types unsigned char a ) : r(r), g(g), b(b), a(a) {} + /** + * @brief Red color value + * + */ unsigned char r; + + /** + * @brief Green color value + * + */ unsigned char g; + + /** + * @brief Blue color value + * + */ unsigned char b; + + /** + * @brief Alpha color value + * + */ unsigned char a; } Color; } diff --git a/shared/types/Vector.hpp b/shared/types/Vector.hpp index 5905a04..177cd23 100644 --- a/shared/types/Vector.hpp +++ b/shared/types/Vector.hpp @@ -7,21 +7,40 @@ #pragma once -namespace shared::types -{ - template - struct Vector; +namespace shared::types { + template + struct Vector; - typedef struct Vector Vector2i; - typedef struct Vector Vector2f; - typedef struct Vector Vector2u; + typedef struct Vector Vector2i; + typedef struct Vector Vector2f; + typedef struct Vector Vector2u; } +/// @brief Vector type +/// @tparam T Type of the vector template -struct shared::types::Vector -{ - Vector(T x, T y) : x(x), y(y){}; +struct shared::types::Vector { + /** + * @brief Construct a new Vector object + * + * @param x X value + * @param y Y value + */ + Vector(T x, T y) : x(x), y(y){}; - T x; - T y; + /** + * @brief X value + * In this Graphical Project, it can be refer as : + * - Width + * - Longitude + */ + T x; + + /** + * @brief Y value + * In this Graphical Project, it can be refer as : + * - Height + * - Latitude + */ + T y; };