diff --git a/Data/Game/Player.hpp b/Data/Game/Player.hpp index eed14ca..38c96bd 100644 --- a/Data/Game/Player.hpp +++ b/Data/Game/Player.hpp @@ -40,7 +40,6 @@ namespace zappy { Orientation orientation = Orientation::NORTH, size_t level = 1 ); - ~Player() = default; /** diff --git a/GUI/src/Game/GameState.hpp b/GUI/src/Game/GameState.hpp index 5cdfb31..8981157 100644 --- a/GUI/src/Game/GameState.hpp +++ b/GUI/src/Game/GameState.hpp @@ -17,85 +17,246 @@ namespace zappy { using EggList = std::vector>; using PlayerList = std::vector>; - class GameState - { + class GameState { public: + /** + * @brief Constructeur par défaut. Initialise la fréquence à 100. + */ GameState() : _frequency(100) {} + + /** + * @brief Destructeur par défaut. + */ ~GameState() = default; + /** + * @brief Définit la fréquence du serveur. + * @param frequency Nouvelle fréquence. + */ void setFrequency(const size_t &frequency) { this->_frequency = frequency; } + /** + * @brief Initialise la carte du jeu avec les dimensions données. + * @param width Largeur de la carte. + * @param height Hauteur de la carte. + */ void initMap(const size_t &width, const size_t &height) { this->_map = std::make_shared(width, height); } + /** + * @brief Récupère la fréquence du serveur. + * @return Fréquence actuelle. + */ size_t getFrequency() const { return this->_frequency; } + /** + * @brief Récupère la carte actuelle. + * @return Carte partagée (modifiable). + */ std::shared_ptr getMap() { return this->_map; } + /** + * @brief Récupère la carte actuelle (version constante). + * @return Carte partagée (const). + */ const std::shared_ptr &getMap() const { return this->_map; } + /** + * @brief Récupère une case spécifique de la carte. + * @param x Coordonnée x. + * @param y Coordonnée y. + * @return Référence constante à la case demandée. + */ const Tile &getTile(const size_t &x, const size_t &y) const { return this->_map->getTile(x, y); } + /** + * @brief Récupère la liste des équipes connues. + * @return Référence vers le vecteur des noms d'équipes. + */ const std::vector &getTeams() const { return this->_teams; } + /** + * @brief Récupère la liste des œufs. + * @return Référence vers le vecteur des œufs. + */ const std::vector &getEggs() const { return this->_eggs; } + /** + * @brief Récupère la liste des joueurs. + * @return Référence vers le vecteur des joueurs. + */ const std::vector &getPlayers() const { return this->_players; } + /** + * @brief Met à jour une case de la carte. + * @param x Coordonnée x. + * @param y Coordonnée y. + * @param tile Nouvelle case. + */ void updateTile(const size_t &x, const size_t &y, Tile &tile) { this->_map->setTile(x, y, tile); } + /** + * @brief Ajoute une équipe au jeu. + * @param teamName Nom de l'équipe. + */ void addTeam(const std::string &teamName) { this->_teams.push_back(teamName); } - void addEgg( - const int &eggId, - const int &fatherId, - const int &x, - const int &y - ) { this->_eggs.push_back(Egg(eggId, fatherId, x, y)); } + /** + * @brief Ajoute un œuf au jeu. + * @param eggId Identifiant de l'œuf. + * @param fatherId Identifiant du joueur père. + * @param x Position x. + * @param y Position y. + */ + void addEgg(const int &eggId, const int &fatherId, const int &x, const int &y) + { this->_eggs.push_back(Egg(eggId, fatherId, x, y)); } + + /** + * @brief Ajoute un joueur au jeu. + * @param player Joueur à ajouter. + */ void addPlayer(const Player &player) { this->_players.push_back(player); } - void updatePlayerPosition( - const int &id, - const int &x, - const int &y, - const Orientation &orientation - ); + /** + * @brief Met à jour la position et l’orientation d’un joueur. + * @param id Identifiant du joueur. + * @param x Nouvelle position x. + * @param y Nouvelle position y. + * @param orientation Nouvelle orientation. + */ + void updatePlayerPosition(const int &id, const int &x, const int &y, const Orientation &orientation); + + /** + * @brief Met à jour le niveau d’un joueur. + * @param id Identifiant du joueur. + * @param level Nouveau niveau. + */ void updatePlayerLevel(const int &id, const size_t &level); + + /** + * @brief Met à jour l’inventaire d’un joueur. + * @param id Identifiant du joueur. + * @param inventory Nouvel inventaire. + */ void updatePlayerInventory(const int &id, const Inventory &inventory); + /** + * @brief Gère l’expulsion d’un joueur. + * @param id Identifiant du joueur. + */ void playerExpulsion(const int &id); + /** + * @brief Gère un message de broadcast émis par un joueur. + * @param id Identifiant du joueur. + * @param message Message émis. + */ void playerBroadcast(const int &id, const std::string &message); - void startIncantation( - const int &x, const int &y, - const int &level, - const std::vector &playerIds - ); + /** + * @brief Démarre une incantation. + * @param x Coordonnée x. + * @param y Coordonnée y. + * @param level Niveau d'incantation. + * @param playerIds Liste des joueurs participants. + */ + void startIncantation(const int &x, const int &y, const int &level, const std::vector &playerIds); + + /** + * @brief Termine une incantation. + * @param x Coordonnée x. + * @param y Coordonnée y. + * @param result Résultat de l'incantation (true = succès). + */ void endIncantation(const int &x, const int &y, const bool &result); + /** + * @brief Fait éclore un œuf. + * @param eggId Identifiant de l’œuf. + */ void hatchEgg(const int &eggId); + /** + * @brief Supprime un œuf. + * @param eggId Identifiant de l’œuf. + */ void removeEgg(const int &eggId); + + /** + * @brief Supprime un joueur. + * @param id Identifiant du joueur. + */ void removePlayer(const int &id); + /** + * @brief Récupère une référence à un œuf par son identifiant. + * @param eggId Identifiant de l’œuf. + * @return Référence vers l’œuf. + */ Egg &getEggById(const int &eggId); + + /** + * @brief Récupère une référence constante à un œuf par son identifiant. + * @param eggId Identifiant de l’œuf. + * @return Référence constante vers l’œuf. + */ const Egg &getEggById(const int &eggId) const; + /** + * @brief Récupère une référence à un joueur par son identifiant. + * @param id Identifiant du joueur. + * @return Référence vers le joueur. + */ Player &getPlayerById(const int &id); + + /** + * @brief Récupère une référence constante à un joueur par son identifiant. + * @param id Identifiant du joueur. + * @return Référence constante vers le joueur. + */ const Player &getPlayerById(const int &id) const; + /** + * @brief Récupère les œufs situés à une position donnée. + * @param x Coordonnée x. + * @param y Coordonnée y. + * @return Liste de références vers les œufs. + */ std::vector> getEggsByCoord(const int &x, const int &y); + + /** + * @brief Récupère les œufs situés à une position donnée (const). + * @param x Coordonnée x. + * @param y Coordonnée y. + * @return Liste de références constantes vers les œufs. + */ std::vector> getEggsByCoord(const int &x, const int &y) const; + /** + * @brief Récupère les joueurs situés à une position donnée. + * @param x Coordonnée x. + * @param y Coordonnée y. + * @return Liste de références vers les joueurs. + */ std::vector> getPlayersByCoord(const int &x, const int &y); + + /** + * @brief Récupère les joueurs situés à une position donnée (const). + * @param x Coordonnée x. + * @param y Coordonnée y. + * @return Liste de références constantes vers les joueurs. + */ std::vector> getPlayersByCoord(const int &x, const int &y) const; + /** + * @brief Termine la partie avec l’équipe gagnante. + * @param teamName Nom de l’équipe victorieuse. + */ void endGame(const std::string &teamName); private: + size_t _frequency; ///< Fréquence d’actualisation du serveur. - size_t _frequency; - - std::vector _eggs; - std::vector _players; - std::vector _teams; + std::vector _eggs; ///< Liste des œufs. + std::vector _players; ///< Liste des joueurs. + std::vector _teams; ///< Liste des noms d’équipes. - std::shared_ptr _map; + std::shared_ptr _map; ///< Carte du jeu. }; - } -} + + } // namespace game +} // namespace zappy diff --git a/GUI/src/Gui.cpp b/GUI/src/Gui.cpp index 1c684d8..c9efdbb 100644 --- a/GUI/src/Gui.cpp +++ b/GUI/src/Gui.cpp @@ -9,6 +9,14 @@ static constexpr const char *defaultIp = "127.0.0.1"; +/** + * @brief Construct a new zappy::gui::Gui::Gui object + * + * initialize the gui + * debug is set to true if the -d or --debug argument is given + * ip is set to the 127.0.0.1 if no ip is given + * port is set to 4242 if no port is given + */ zappy::gui::Gui::Gui() : _debug(false), _ip(defaultIp), @@ -18,6 +26,14 @@ zappy::gui::Gui::Gui() : _renderer(nullptr) {} +/** + * @brief Parse the arguments given to the program + * + * Parse the arguments given to the program + * + * @param argc number of arguments + * @param argv arguments + */ void zappy::gui::Gui::parseArgs(int argc, char const *argv[]) { if (argc < 3) @@ -66,6 +82,11 @@ void zappy::gui::Gui::parseArgs(int argc, char const *argv[]) } } +/** + * @brief initialize the game + * + * initialize the game state and the renderer + */ void zappy::gui::Gui::init() { this->_gameState = std::make_shared(); @@ -78,6 +99,12 @@ void zappy::gui::Gui::init() this->_protocol->update(); } +/** + * @brief initialize the network + * + * initialize the network and send the first request to the server + * initialize the renderer requests to the server + */ void zappy::gui::Gui::_initNetwork() { this->_protocol = std::make_unique(this->_renderer, this->_gameState, this->_debug); @@ -99,12 +126,20 @@ void zappy::gui::Gui::_initNetwork() this->_renderer->setProtocolRequests(protocolRequests); } +/** + * @brief Run the GUI + * + * initialize the network and the renderer + * then run the main loop + */ void zappy::gui::Gui::run() { init(); bool running = true; while (running) { + std::this_thread::sleep_for(std::chrono::milliseconds(1)); + this->_renderer->handleInput(); this->_protocol->update(); diff --git a/GUI/src/Gui.hpp b/GUI/src/Gui.hpp index 320397d..437a7ea 100644 --- a/GUI/src/Gui.hpp +++ b/GUI/src/Gui.hpp @@ -22,6 +22,7 @@ #include #include #include +#include namespace zappy { namespace gui { diff --git a/GUI/src/Network/NetworkManager.hpp b/GUI/src/Network/NetworkManager.hpp index ca12247..3915150 100644 --- a/GUI/src/Network/NetworkManager.hpp +++ b/GUI/src/Network/NetworkManager.hpp @@ -24,36 +24,91 @@ namespace zappy { namespace network { - struct ServerMessage { - std::string command; - std::string params; - std::string raw; - }; - - class NetworkManager { - public: - NetworkManager(); - ~NetworkManager(); - - bool connect(const std::string &host, int port); - void disconnect(); - bool isConnected() const; - - bool sendCommand(const std::string &command); - std::vector receiveMessages(); - void setMessageCallback(std::function callback); - - private: - int _socket; - bool _connected; - std::string _buffer; - std::queue _messageQueue; - std::function _messageCallback; - mutable std::mutex _mutex; - - ServerMessage parseMessage(const std::string &raw); - void processBuffer(); + /** + * @brief Représente un message reçu depuis le serveur. + */ + struct ServerMessage { + std::string command; ///< Commande extraite du message. + std::string params; ///< Paramètres associés à la commande. + std::string raw; ///< Message brut tel que reçu. }; + + class NetworkManager { + public: + /** + * @brief Constructeur par défaut. + */ + NetworkManager(); + + /** + * @brief Destructeur. Ferme la connexion si active. + */ + ~NetworkManager(); + + /** + * @brief Établit une connexion au serveur. + * + * @param host Adresse IP ou nom d’hôte du serveur. + * @param port Port de connexion. + * @return true si la connexion a réussi, false sinon. + */ + bool connect(const std::string &host, int port); + + /** + * @brief Ferme la connexion avec le serveur. + */ + void disconnect(); + + /** + * @brief Vérifie si une connexion est active. + * @return true si connecté, false sinon. + */ + bool isConnected() const; + + /** + * @brief Envoie une commande brute au serveur. + * + * @param command Chaîne représentant la commande à envoyer. + * @return true si l’envoi a réussi, false sinon. + */ + bool sendCommand(const std::string &command); + + /** + * @brief Récupère les messages en attente du serveur. + * + * @return Un vecteur de messages ServerMessage reçus. + */ + std::vector receiveMessages(); + + /** + * @brief Définit une fonction de rappel appelée à chaque réception de message. + * + * @param callback Fonction prenant un `ServerMessage` en paramètre. + */ + void setMessageCallback(std::function callback); + + private: + int _socket; ///< Descripteur de socket. + bool _connected; ///< Indique si une connexion est active. + std::string _buffer; ///< Tampon pour les données brutes reçues. + std::queue _messageQueue; ///< File des messages à traiter. + std::function _messageCallback; ///< Callback de message. + mutable std::mutex _mutex; ///< Mutex pour la synchronisation des accès concurrents. + + /** + * @brief Parse un message brut en structure ServerMessage. + * + * @param raw Message brut à analyser. + * @return Structure ServerMessage extraite. + */ + ServerMessage parseMessage(const std::string &raw); + + /** + * @brief Traite le tampon interne pour extraire les messages complets. + */ + void processBuffer(); + }; + } // namespace network } // namespace zappy diff --git a/GUI/src/Renderer/ARenderer.cpp b/GUI/src/Renderer/ARenderer.cpp index d8ebdad..c768597 100644 --- a/GUI/src/Renderer/ARenderer.cpp +++ b/GUI/src/Renderer/ARenderer.cpp @@ -12,27 +12,48 @@ zappy::gui::ARenderer::ARenderer() : _elapsedTime(0.0f) {} +/** + * @brief Initialise le temps interne du renderer. + */ void zappy::gui::ARenderer::init() { this->_lastTime = std::chrono::steady_clock::now(); } +/** + * @brief Définit l'état de jeu à utiliser par le renderer. + * + * @param gameState L'état de jeu partagé. + */ void zappy::gui::ARenderer::setGameState(std::shared_ptr &gameState) { this->_gameState = gameState; } +/** + * @brief Définit les requêtes du protocole à utiliser. + * + * @param protocolRequests Map de fonctions associées aux requêtes réseau. + */ void zappy::gui::ARenderer::setProtocolRequests(const ProtocolRequest &protocolRequests) { this->_protocolRequests = protocolRequests; } +/** + * @brief Définit la fréquence de mise à jour du jeu. + * + * @param frequency La fréquence en unités de temps. + */ void zappy::gui::ARenderer::setFrequency(const size_t &frequency) { _checkGameState(); this->_gameState->setFrequency(frequency); } +/** + * @brief Met à jour le renderer et déclenche des actions régulières comme les requêtes de contenu de carte. + */ void zappy::gui::ARenderer::update() { if (!_gameState) @@ -53,22 +74,39 @@ void zappy::gui::ARenderer::update() } } -void zappy::gui::ARenderer::addEgg( - const int &eggId, - const int &fatherId, - const int &x, - const int &y -) { +/** + * @brief Ajoute un œuf à l'état de jeu. + * + * @param eggId Identifiant de l'œuf. + * @param fatherId Identifiant du joueur père. + * @param x Coordonnée X de l'œuf. + * @param y Coordonnée Y de l'œuf. + */ +void zappy::gui::ARenderer::addEgg(const int &eggId, const int &fatherId, const int &x, const int &y) +{ _checkGameState(); this->_gameState->addEgg(eggId, fatherId, x, y); } +/** + * @brief Ajoute un joueur à l'état de jeu. + * + * @param player Référence au joueur à ajouter. + */ void zappy::gui::ARenderer::addPlayer(const game::Player &player) { _checkGameState(); this->_gameState->addPlayer(player); } +/** + * @brief Met à jour la position et l’orientation d’un joueur. + * + * @param id Identifiant du joueur. + * @param x Coordonnée X. + * @param y Coordonnée Y. + * @param orientation Orientation du joueur. + */ void zappy::gui::ARenderer::updatePlayerPosition( const int &id, const int &x, @@ -79,30 +117,61 @@ void zappy::gui::ARenderer::updatePlayerPosition( this->_gameState->updatePlayerPosition(id, x, y, orientation); } +/** + * @brief Met à jour le niveau d’un joueur. + * + * @param id Identifiant du joueur. + * @param level Nouveau niveau. + */ void zappy::gui::ARenderer::updatePlayerLevel(const int &id, const size_t &level) { _checkGameState(); this->_gameState->updatePlayerLevel(id, level); } +/** + * @brief Met à jour l’inventaire d’un joueur. + * + * @param id Identifiant du joueur. + * @param inventory Inventaire à appliquer. + */ void zappy::gui::ARenderer::updatePlayerInventory(const int &id, const game::Inventory &inventory) { _checkGameState(); this->_gameState->updatePlayerInventory(id, inventory); } +/** + * @brief Notifie l’expulsion d’un joueur. + * + * @param id Identifiant du joueur expulsé. + */ void zappy::gui::ARenderer::playerExpulsion(const int &id) { _checkGameState(); this->_gameState->playerExpulsion(id); } +/** + * @brief Notifie un message de broadcast émis par un joueur. + * + * @param id Identifiant du joueur. + * @param message Message diffusé. + */ void zappy::gui::ARenderer::playerBroadcast(const int &id, const std::string &message) { _checkGameState(); this->_gameState->playerBroadcast(id, message); } +/** + * @brief Démarre une incantation. + * + * @param x Coordonnée X. + * @param y Coordonnée Y. + * @param level Niveau de l’incantation. + * @param playerIds Liste des identifiants des joueurs impliqués. + */ void zappy::gui::ARenderer::startIncantation( const int &x, const int &y, const int &level, @@ -112,36 +181,68 @@ void zappy::gui::ARenderer::startIncantation( this->_gameState->startIncantation(x, y, level, playerIds); } +/** + * @brief Termine une incantation. + * + * @param x Coordonnée X. + * @param y Coordonnée Y. + * @param result Résultat de l’incantation (succès ou échec). + */ void zappy::gui::ARenderer::endIncantation(const int &x, const int &y, const bool &result) { _checkGameState(); this->_gameState->endIncantation(x, y, result); } +/** + * @brief Fait éclore un œuf. + * + * @param eggId Identifiant de l'œuf. + */ void zappy::gui::ARenderer::hatchEgg(const int &eggId) { _checkGameState(); this->_gameState->hatchEgg(eggId); } +/** + * @brief Supprime un œuf de l’état de jeu. + * + * @param eggId Identifiant de l'œuf. + */ void zappy::gui::ARenderer::removeEgg(const int &eggId) { _checkGameState(); this->_gameState->removeEgg(eggId); } +/** + * @brief Supprime un joueur de l’état de jeu. + * + * @param id Identifiant du joueur. + */ void zappy::gui::ARenderer::removePlayer(const int &id) { _checkGameState(); this->_gameState->removePlayer(id); } +/** + * @brief Termine la partie et affiche le nom de l’équipe gagnante. + * + * @param teamName Nom de l’équipe gagnante. + */ void zappy::gui::ARenderer::endGame(const std::string &teamName) { _checkGameState(); this->_gameState->endGame(teamName); } +/** + * @brief Vérifie que l'état de jeu est bien défini. + * + * @throw GuiError si l’état de jeu n’est pas défini. + */ void zappy::gui::ARenderer::_checkGameState() const { if (!this->_gameState) diff --git a/GUI/src/Renderer/DebugRenderer.cpp b/GUI/src/Renderer/DebugRenderer.cpp index cb554df..db152cc 100644 --- a/GUI/src/Renderer/DebugRenderer.cpp +++ b/GUI/src/Renderer/DebugRenderer.cpp @@ -7,6 +7,8 @@ #include "DebugRenderer.hpp" +/// @brief Constructeur du renderer Debug. +/// Initialise les pointeurs de menu et la scène par défaut. zappy::gui::DebugRenderer::DebugRenderer() : ARenderer::ARenderer(), _shouldClose(false) diff --git a/GUI/src/Renderer/IRenderer.hpp b/GUI/src/Renderer/IRenderer.hpp index 1544593..6744f16 100644 --- a/GUI/src/Renderer/IRenderer.hpp +++ b/GUI/src/Renderer/IRenderer.hpp @@ -24,54 +24,165 @@ namespace zappy { public: virtual ~IRenderer() = default; + /** + * @brief Initialize the renderer + */ virtual void init() = 0; + /** + * @brief Set the Game State object + * + * @param gameState shared pointer to the game state + */ virtual void setGameState(std::shared_ptr &gameState) = 0; + /** + * @brief Set the Protocol Requests object + * + * @param protocolRequests the protocol requests + */ virtual void setProtocolRequests(const ProtocolRequest &protocolRequests) = 0; + /** + * @brief Set the Frequency object + * + * @param frequency new frequency + */ virtual void setFrequency(const size_t &frequency) = 0; + /** + * @brief Update the renderer's inputs + */ virtual void handleInput() = 0; + /** + * @brief Update the renderer + */ virtual void update() = 0; + /** + * @brief Render the renderer + */ virtual void render() const = 0; + /** + * @brief Check if the renderer should close + * + * @return true or false + */ virtual bool shouldClose() const = 0; + /** + * @brief Add an egg to the renderer + * + * @param eggId id of the egg + * @param fatherId id of the father of the egg + * @param x x position of the egg + * @param y y position of the egg + */ virtual void addEgg( const int &eggId, const int &fatherId, const int &x, const int &y ) = 0; + /** + * @brief Add a player to the renderer + * + * @param player Reference to the player + */ virtual void addPlayer(const game::Player &player) = 0; + /** + * @brief Update a player's position + * + * @param id id of the player + * @param x x position of the player + * @param y y position of the player + * @param orientation orientation of the player + */ virtual void updatePlayerPosition( const int &id, const int &x, const int &y, const game::Orientation &orientation ) = 0; + /** + * @brief Update a player's level + * + * @param id id of the player + * @param level level of the player + */ virtual void updatePlayerLevel(const int &id, const size_t &level) = 0; + /** + * @brief Update a player's inventory + * + * @param id id of the player + * @param inventory inventory of the player + */ virtual void updatePlayerInventory(const int &id, const game::Inventory &inventory) = 0; + /** + * @brief Player expulsion + * + * @param id id of the player + */ virtual void playerExpulsion(const int &id) = 0; + /** + * @brief Update the time unit + * + * @param id id of the player + * @param message message to send to the player + */ virtual void playerBroadcast(const int &id, const std::string &message) = 0; + /** + * @brief Update the time unit + * + * @param x x position of the time unit + * @param y y position of the time unit + * @param level level of the time unit + * @param playerIds ids of the players who collected the time unit + */ virtual void startIncantation( const int &x, const int &y, const int &level, const std::vector &playerIds ) = 0; + /** + * @brief Update the time unit + * + * @param x x position of the time unit + * @param y y position of the time unit + * @param result result of the incantation + */ virtual void endIncantation(const int &x, const int &y, const bool &result) = 0; + /** + * @brief Update the time unit + * + * @param eggId id of the egg + */ virtual void hatchEgg(const int &eggId) = 0; + /** + * @brief Update the time unit + * + * @param eggId id of the egg + */ virtual void removeEgg(const int &eggId) = 0; + /** + * @brief Remove a player from the renderer + * + * @param id id of the player + */ virtual void removePlayer(const int &id) = 0; + /** + * @brief Update the time unit + * + * @param teamName name of the team + */ virtual void endGame(const std::string &teamName) = 0; }; } diff --git a/GUI/src/Renderer/NcursesRenderer.cpp b/GUI/src/Renderer/NcursesRenderer.cpp index 25f35f9..116d3ff 100644 --- a/GUI/src/Renderer/NcursesRenderer.cpp +++ b/GUI/src/Renderer/NcursesRenderer.cpp @@ -7,6 +7,9 @@ #include "NcursesRenderer.hpp" +/** + * @brief Construct a new zappy::gui::Ncurses Renderer::Ncurses Renderer object + */ zappy::gui::NcursesRenderer::NcursesRenderer() : ARenderer::ARenderer(), _shouldClose(false), @@ -14,6 +17,11 @@ zappy::gui::NcursesRenderer::NcursesRenderer() : _help(false) {} +/** + * @brief Initialize the NcursesRenderer + * + * Initializes the window, sets up colors, and calls the parent renderer's initialization method + */ void zappy::gui::NcursesRenderer::init() { _initWindow(); @@ -22,6 +30,11 @@ void zappy::gui::NcursesRenderer::init() ARenderer::init(); } +/** + * @brief Initialize the window + * + * Initializes the window and sets up the window size + */ void zappy::gui::NcursesRenderer::_initWindow() { initscr(); @@ -34,6 +47,11 @@ void zappy::gui::NcursesRenderer::_initWindow() _window = stdscr; } +/** + * @brief Initialize the colors + * + * Initialize the colors + */ void zappy::gui::NcursesRenderer::_initColors() { init_pair(1, COLOR_WHITE, COLOR_BLACK); @@ -42,6 +60,12 @@ void zappy::gui::NcursesRenderer::_initColors() init_pair(4, COLOR_YELLOW, COLOR_BLACK); } +/** + * @brief Handle the input + * + * Handles the input from the user + * Handles the help menu + */ void zappy::gui::NcursesRenderer::handleInput() { int ch = getch(); @@ -51,6 +75,11 @@ void zappy::gui::NcursesRenderer::handleInput() _help = !_help; } +/** + * @brief Update the renderer + * + * Handles the input and calls the parent renderer's update method + */ void zappy::gui::NcursesRenderer::render() const { werase(_window); @@ -60,6 +89,11 @@ void zappy::gui::NcursesRenderer::render() const wrefresh(_window); } +/** + * @brief Draw the map + * + * @return true or false + */ bool zappy::gui::NcursesRenderer::shouldClose() const { if (_shouldClose) { @@ -69,12 +103,20 @@ bool zappy::gui::NcursesRenderer::shouldClose() const return _shouldClose; } +/** + * @brief handle the end of the game + * + * @param teamName close the game and call the parent renderer's endGame method + */ void zappy::gui::NcursesRenderer::endGame(const std::string &teamName) { _shouldClose = true; ARenderer::endGame(teamName); } +/** + * @brief Draw the map + */ void zappy::gui::NcursesRenderer::_drawMap() const { const auto &map = _gameState->getMap(); @@ -91,6 +133,15 @@ void zappy::gui::NcursesRenderer::_drawMap() const } } +/** + * @brief Draw a tile + * + * @param tile The tile to draw containing the resources + * @param eggs The list of eggs on the tile + * @param players The list of players on the tile + * @param row row where to draw the tile + * @param col col where to draw the tile + */ void zappy::gui::NcursesRenderer::_drawTile( const zappy::game::Tile &tile, const game::EggList &eggs, diff --git a/GUI/src/Renderer/Raylib/Map/Floor/IFloor.hpp b/GUI/src/Renderer/Raylib/Map/Floor/IFloor.hpp index 8c31b5d..ee3249a 100644 --- a/GUI/src/Renderer/Raylib/Map/Floor/IFloor.hpp +++ b/GUI/src/Renderer/Raylib/Map/Floor/IFloor.hpp @@ -20,29 +20,101 @@ namespace zappy { namespace raylib { class IFloor { public: + /** + * @brief Destructeur virtuel par défaut. + */ virtual ~IFloor() = default; + /** + * @brief Initialise les ressources nécessaires au sol. + */ virtual void init() = 0; + + /** + * @brief Met à jour les données du sol (si nécessaire). + */ virtual void update() const = 0; + + /** + * @brief Affiche le sol à l'écran. + */ virtual void render() const = 0; - // Setters + /** + * @brief Définit la largeur de la carte. + * @param width Largeur (en tuiles). + */ virtual void setWidth(const size_t &width) = 0; + + /** + * @brief Définit la hauteur de la carte. + * @param height Hauteur (en tuiles). + */ virtual void setHeight(const size_t &height) = 0; + + /** + * @brief Définit la taille d'une tuile. + * @param tileSize Taille d'une tuile en unités. + */ virtual void setTileSize(const float &tileSize) = 0; - // Getters + /** + * @brief Récupère la largeur de la carte. + * @return Largeur (en tuiles). + */ virtual size_t getWidth() const = 0; + + /** + * @brief Récupère la hauteur de la carte. + * @return Hauteur (en tuiles). + */ virtual size_t getHeight() const = 0; + + /** + * @brief Récupère la taille d'une tuile. + * @return Taille d'une tuile en unités. + */ virtual float getTileSize() const = 0; + /** + * @brief Calcule le vecteur de décalage à appliquer en fonction de l'orientation. + * @param orientation Orientation du joueur. + * @return Vecteur 3D correspondant au décalage. + */ virtual Vector3 getGapFromOrientation(const game::Orientation &orientation) = 0; + + /** + * @brief Calcule le vecteur pointant vers le nord selon l'orientation donnée. + * @param orientation Orientation actuelle. + * @return Vecteur 3D pointant vers le nord. + */ virtual Vector3 getNorthVector(const game::Orientation &orientation) = 0; + /** + * @brief Convertit des coordonnées 2D (x, y) en coordonnées 3D. + * @param x Coordonnée X sur la carte. + * @param y Coordonnée Y sur la carte. + * @return Coordonnées 3D correspondantes. + */ virtual Vector3 get3DCoords(const int &x, const int &y) const = 0; + /** + * @brief Crée une structure de translation pour un joueur donné. + * @param player Joueur concerné. + * @param x Coordonnée X de destination. + * @param y Coordonnée Y de destination. + * @param timeUnit Temps de déplacement. + * @return Translation à effectuer. + */ virtual Translation createTranslation(const APlayerModel &player, const int &x, const int &y, const int &timeUnit) = 0; + /** + * @brief Applique une translation à un joueur en mettant à jour sa position. + * @param deltaUnits Temps écoulé depuis la dernière frame. + * @param translationVector Vecteur de déplacement. + * @param destination Position finale visée. + * @param player Joueur à déplacer. + */ virtual void translate(const float &deltaUnits, const Vector3 &translationVector, Vector3 &destination, APlayerModel &player) = 0; }; } diff --git a/GUI/src/Renderer/Raylib/Map/MapRenderer.cpp b/GUI/src/Renderer/Raylib/Map/MapRenderer.cpp index dadf9d0..8a05146 100644 --- a/GUI/src/Renderer/Raylib/Map/MapRenderer.cpp +++ b/GUI/src/Renderer/Raylib/Map/MapRenderer.cpp @@ -22,6 +22,10 @@ zappy::gui::raylib::MapRenderer::MapRenderer(const std::shared_ptr ma _players() {} +/** + * @brief Initialise le renderer avec une texture de sol. + * @param tileTexturePath Chemin vers la texture des tuiles (par défaut : BASIC_FLOOR_PATH). + */ void zappy::gui::raylib::MapRenderer::init(const std::string &tileTexturePath) { // Init la carte @@ -31,6 +35,10 @@ void zappy::gui::raylib::MapRenderer::init(const std::string &tileTexturePath) this->_lastTime = std::chrono::steady_clock::now(); } +/** + * @brief Met à jour l'état du renderer en fonction de la fréquence donnée. + * @param frequency Fréquence de mise à jour. + */ void zappy::gui::raylib::MapRenderer::update(const int &frequency) { // Mettre à jour la carte @@ -47,6 +55,9 @@ void zappy::gui::raylib::MapRenderer::update(const int &frequency) _updateActions(deltaUnits); } +/** + * @brief Rend la scène (joueurs, œufs, ressources, effets, etc.). + */ void zappy::gui::raylib::MapRenderer::render() { // Dessiner la carte @@ -59,21 +70,37 @@ void zappy::gui::raylib::MapRenderer::render() _renderAnimActions(); } +/** + * @brief Définit le type d'effet de diffusion (broadcast). + * @param type Type d'effet à appliquer. + */ void zappy::gui::raylib::MapRenderer::setBroadcastType(const zappy::gui::raylib::EffectType &type) { this->_broadcastType = type; } +/** + * @brief Définit la couleur de l'effet de diffusion (broadcast). + * @param color Couleur de l'effet. + */ void zappy::gui::raylib::MapRenderer::setIncantationType(const zappy::gui::raylib::EffectType &type) { this->_incantationType = type; } +/** + * @brief Définit le type d'effet d'incantation. + * @param type Type d'effet d'incantation. + */ void zappy::gui::raylib::MapRenderer::setIncantationColor(const Color &color) { this->_incantationColor = color; } +/** + * @brief Définit la couleur de l'effet d'incantation. + * @param color Couleur de l'effet. + */ void zappy::gui::raylib::MapRenderer::addEgg(std::unique_ptr egg) { egg->init(); @@ -81,6 +108,10 @@ void zappy::gui::raylib::MapRenderer::addEgg(std::unique_ptr egg) _eggs.push_back(std::move(egg)); } +/** + * @brief Ajoute un œuf dans la scène. + * @param egg Unique pointer vers le modèle d'œuf à ajouter. + */ void zappy::gui::raylib::MapRenderer::addPlayer(std::unique_ptr player) { player->init(); @@ -88,6 +119,10 @@ void zappy::gui::raylib::MapRenderer::addPlayer(std::unique_ptr pl this->_players.push_back(std::move(player)); } +/** + * @brief Ajoute un joueur dans la scène. + * @param player Unique pointer vers le modèle de joueur à ajouter. + */ void zappy::gui::raylib::MapRenderer::addResourceModel(const zappy::game::Resource &type, std::unique_ptr model) { if (model) @@ -95,6 +130,11 @@ void zappy::gui::raylib::MapRenderer::addResourceModel(const zappy::game::Resour _resourceModels[static_cast(type)] = std::move(model); } +/** + * @brief Ajoute un modèle de ressource. + * @param type Type de ressource. + * @param model Unique pointer vers le modèle de ressource à ajouter. + */ void zappy::gui::raylib::MapRenderer::setEggPosition(const int &id, const int &x, const int &y) { if (_eggs.empty()) @@ -112,6 +152,12 @@ void zappy::gui::raylib::MapRenderer::setEggPosition(const int &id, const int &x egg.setPosition(position3D); } +/** + * @brief Positionne un œuf sur la carte. + * @param id Identifiant de l'œuf. + * @param x Position x. + * @param y Position y. + */ void zappy::gui::raylib::MapRenderer::setPlayerPosition(const int &id, const int &x, const int &y, const game::Orientation &orientation) { if (this->_players.empty()) @@ -129,6 +175,13 @@ void zappy::gui::raylib::MapRenderer::setPlayerPosition(const int &id, const int player.look(orientation); } +/** + * @brief Positionne un joueur sur la carte avec une orientation donnée. + * @param id Identifiant du joueur. + * @param x Position x. + * @param y Position y. + * @param orientation Orientation du joueur. + */ void zappy::gui::raylib::MapRenderer::playerLook(const int &id, const game::Orientation &orientation) { if (this->_players.empty()) @@ -139,6 +192,11 @@ void zappy::gui::raylib::MapRenderer::playerLook(const int &id, const game::Orie player.look(orientation); } +/** + * @brief Change la direction du regard du joueur. + * @param id Identifiant du joueur. + * @param orientation Nouvelle orientation. + */ void zappy::gui::raylib::MapRenderer::playerLookLeft(const int &id, const game::Orientation &orientation) { if (this->_players.empty()) @@ -159,6 +217,17 @@ void zappy::gui::raylib::MapRenderer::playerLookLeft(const int &id, const game:: _addRotation(player, rotationAngle, player.getOrientation()); } +/** + * @brief Fait regarder le joueur vers la gauche. + * @param id Identifiant du joueur. + * @param orientation Orientation vers laquelle le joueur regarde. + */ + +/** + * @brief Fait regarder le joueur vers la droite. + * @param id Identifiant du joueur. + * @param orientation Orientation vers laquelle le joueur regarde. + */ void zappy::gui::raylib::MapRenderer::playerLookRight(const int &id, const game::Orientation &orientation) { if (this->_players.empty()) @@ -179,6 +248,15 @@ void zappy::gui::raylib::MapRenderer::playerLookRight(const int &id, const game: _addRotation(player, rotationAngle, player.getOrientation()); } +/** + * @brief Déplace le joueur vers l'avant selon sa position et orientation, en tenant compte des dimensions de la carte. + * @param id Identifiant du joueur. + * @param x Position cible x. + * @param y Position cible y. + * @param orientation Orientation du joueur. + * @param mapWidth Largeur de la carte. + * @param mapHeight Hauteur de la carte. + */ void zappy::gui::raylib::MapRenderer::playerForward( const int &id, const int &x, @@ -228,6 +306,12 @@ void zappy::gui::raylib::MapRenderer::playerForward( player.setGamePosition(Vector2{ static_cast(x), static_cast(y) }); } +/** + * @brief Gère l'expulsion d'un joueur à une position donnée. + * @param id Identifiant du joueur expulsé. + * @param x Position x. + * @param y Position y. + */ void zappy::gui::raylib::MapRenderer::playerExpulsion(const int &id, const int &x, const int &y) { if (this->_players.empty()) @@ -248,6 +332,10 @@ void zappy::gui::raylib::MapRenderer::playerExpulsion(const int &id, const int & player.setGamePosition(Vector2{ static_cast(x), static_cast(y) }); } +/** + * @brief Déclenche la diffusion d'un message par un joueur. + * @param id Identifiant du joueur qui diffuse. + */ void zappy::gui::raylib::MapRenderer::playerBroadcast(const int &id) { std::shared_ptr action = PlayerActionFactory::createBroadcast( @@ -261,6 +349,12 @@ void zappy::gui::raylib::MapRenderer::playerBroadcast(const int &id) this->_playerAnimAction.push_back(std::move(std::dynamic_pointer_cast(action))); } +/** + * @brief Démarre une incantation sur une case donnée avec les joueurs concernés. + * @param x Position x de l'incantation. + * @param y Position y de l'incantation. + * @param playerIds Identifiants des joueurs participants. + */ void zappy::gui::raylib::MapRenderer::startIncantation(const int &x, const int &y, const std::vector &playerIds) { Vector2 incantationPos = Vector2{static_cast(x), static_cast(y)}; @@ -282,6 +376,12 @@ void zappy::gui::raylib::MapRenderer::startIncantation(const int &x, const int & this->_incantationMap[animAction.getAnimationId()] = incantationPos; } +/** + * @brief Termine une incantation sur une case donnée avec le résultat. + * @param x Position x de l'incantation. + * @param y Position y de l'incantation. + * @param result Résultat de l'incantation (true = succès, false = échec). + */ void zappy::gui::raylib::MapRenderer::endIncantation(const int &x, const int &y, const bool &result) { Vector2 targetPos = Vector2{static_cast(x), static_cast(y)}; @@ -325,6 +425,10 @@ void zappy::gui::raylib::MapRenderer::endIncantation(const int &x, const int &y, incantation->startAction(); } +/** + * @brief Supprime un joueur de la scène. + * @param id Identifiant du joueur à supprimer. + */ void zappy::gui::raylib::MapRenderer::removeEgg(const int &id) { for (auto it = _eggs.begin(); it != _eggs.end(); it++) { @@ -335,6 +439,10 @@ void zappy::gui::raylib::MapRenderer::removeEgg(const int &id) } } +/** + * @brief Supprime un œuf de la scène. + * @param id Identifiant de l'œuf à supprimer. + */ void zappy::gui::raylib::MapRenderer::removePlayer(const int &id) { for (auto it = this->_players.begin(); it != this->_players.end(); it++) { @@ -345,6 +453,10 @@ void zappy::gui::raylib::MapRenderer::removePlayer(const int &id) } } +/** + * @brief Supprime toutes les actions de translation pour un joueur donné. + * @param id Identifiant du joueur. + */ void zappy::gui::raylib::MapRenderer::removeAllTranslations(const int &id) { std::queue> &queue = this->_playerActionQueues[id]; @@ -361,6 +473,10 @@ void zappy::gui::raylib::MapRenderer::removeAllTranslations(const int &id) queue = std::move(newQueue); } +/** + * @brief Supprime toutes les actions de rotation pour un joueur donné. + * @param id Identifiant du joueur. + */ void zappy::gui::raylib::MapRenderer::removeAllRotations(const int &id) { std::queue> &queue = this->_playerActionQueues[id]; @@ -376,6 +492,11 @@ void zappy::gui::raylib::MapRenderer::removeAllRotations(const int &id) queue = std::move(newQueue); } +/** + * @brief Récupère une référence non-const au modèle joueur correspondant à l'identifiant. + * @param id Identifiant du joueur. + * @return Référence au modèle joueur. + */ zappy::gui::raylib::APlayerModel &zappy::gui::raylib::MapRenderer::_getPlayer(const int &id) { for (auto &player : this->_players) { @@ -385,6 +506,11 @@ zappy::gui::raylib::APlayerModel &zappy::gui::raylib::MapRenderer::_getPlayer(co throw RendererError("Player " + std::to_string(id) + " not found", "MapRenderer"); } +/** + * @brief Récupère une référence const au modèle joueur correspondant à l'identifiant. + * @param id Identifiant du joueur. + * @return Référence const au modèle joueur. + */ const zappy::gui::raylib::APlayerModel &zappy::gui::raylib::MapRenderer::_getPlayer(const int &id) const { for (const auto &player : this->_players) { @@ -394,6 +520,11 @@ const zappy::gui::raylib::APlayerModel &zappy::gui::raylib::MapRenderer::_getPla throw RendererError("Player " + std::to_string(id) + " not found", "MapRenderer"); } +/** + * @brief Récupère une référence non-const au modèle œuf correspondant à l'identifiant. + * @param id Identifiant de l'œuf. + * @return Référence au modèle œuf. + */ zappy::gui::raylib::AEggModel &zappy::gui::raylib::MapRenderer::_getEgg(const int &id) { for (auto &egg : _eggs) { @@ -403,6 +534,11 @@ zappy::gui::raylib::AEggModel &zappy::gui::raylib::MapRenderer::_getEgg(const in throw RendererError("Egg " + std::to_string(id) + " not found", "MapRenderer"); } +/** + * @brief Récupère une référence const au modèle œuf correspondant à l'identifiant. + * @param id Identifiant de l'œuf. + * @return Référence const au modèle œuf. + */ const zappy::gui::raylib::AEggModel &zappy::gui::raylib::MapRenderer::_getEgg(const int &id) const { for (const auto &egg : _eggs) { @@ -412,6 +548,12 @@ const zappy::gui::raylib::AEggModel &zappy::gui::raylib::MapRenderer::_getEgg(co throw RendererError("Egg " + std::to_string(id) + " not found", "MapRenderer"); } +/** + * @brief Ajoute une rotation à un joueur avec un angle donné et une orientation. + * @param player Référence au modèle joueur. + * @param angle Angle de rotation en radians ou degrés. + * @param orientation Nouvelle orientation du joueur. + */ void zappy::gui::raylib::MapRenderer::_addRotation( const APlayerModel &player, const float &angle, @@ -439,6 +581,10 @@ void zappy::gui::raylib::MapRenderer::_addRotation( this->_playerActionQueues[player.getId()].push(std::move(action)); } +/** + * @brief Met à jour les positions des joueurs et œufs en fonction du temps écoulé. + * @param deltaUnits Temps écoulé depuis la dernière mise à jour. + */ void zappy::gui::raylib::MapRenderer::_updatePlayersAndEggs(const float &deltaUnits) { for (auto &player : this->_players) @@ -448,6 +594,10 @@ void zappy::gui::raylib::MapRenderer::_updatePlayersAndEggs(const float &deltaUn egg->update(deltaUnits); } +/** + * @brief Met à jour les actions en cours des joueurs. + * @param deltaUnits Temps écoulé depuis la dernière mise à jour. + */ void zappy::gui::raylib::MapRenderer::_updateActions(const float &deltaUnits) { for (auto it = this->_playerActionQueues.begin(); it != this->_playerActionQueues.end(); ) { @@ -475,6 +625,11 @@ void zappy::gui::raylib::MapRenderer::_updateActions(const float &deltaUnits) this->_updateAnimActions(deltaUnits); } +/** + * @brief Met à jour un joueur après l'exécution de ses actions. + * @param player Référence au modèle joueur à mettre à jour. + * @param actions Queue des actions du joueur. + */ void zappy::gui::raylib::MapRenderer::_updatePlayerAfterAction(APlayerModel &player, const std::queue> &actions) { if (actions.empty()) { @@ -488,6 +643,10 @@ void zappy::gui::raylib::MapRenderer::_updatePlayerAfterAction(APlayerModel &pla player.idle(); } +/** + * @brief Met à jour les animations liées aux actions des joueurs. + * @param deltaUnits Temps écoulé depuis la dernière mise à jour. + */ void zappy::gui::raylib::MapRenderer::_updateAnimActions(const float &deltaUnits) { for (auto it = this->_playerAnimAction.begin(); it != this->_playerAnimAction.end(); ++it) { @@ -501,6 +660,9 @@ void zappy::gui::raylib::MapRenderer::_updateAnimActions(const float &deltaUnits } } +/** + * @brief Rend les joueurs et œufs sur la scène. + */ void zappy::gui::raylib::MapRenderer::_renderPlayersAndEggs() { for (auto &player : this->_players) @@ -510,6 +672,9 @@ void zappy::gui::raylib::MapRenderer::_renderPlayersAndEggs() egg->render(); } +/** + * @brief Rend les ressources sur la scène. + */ void zappy::gui::raylib::MapRenderer::_renderResources() { constexpr float uniformHeight = 0.1f; @@ -543,6 +708,9 @@ void zappy::gui::raylib::MapRenderer::_renderResources() } } +/** + * @brief Rend les animations liées aux actions des joueurs. + */ void zappy::gui::raylib::MapRenderer::_renderAnimActions() { auto it = _playerAnimAction.begin(); diff --git a/GUI/src/Renderer/Raylib/Map/MapRenderer.hpp b/GUI/src/Renderer/Raylib/Map/MapRenderer.hpp index 4af35d2..b1a1eed 100644 --- a/GUI/src/Renderer/Raylib/Map/MapRenderer.hpp +++ b/GUI/src/Renderer/Raylib/Map/MapRenderer.hpp @@ -129,3 +129,52 @@ namespace zappy { } } } +/** + * @brief Initialise le renderer avec une texture de sol. + * @param tileTexturePath Chemin vers la texture des tuiles (par défaut : BASIC_FLOOR_PATH). + */ + +/** + * @brief Met à jour l'état du renderer en fonction de la fréquence donnée. + * @param frequency Fréquence de mise à jour. + */ + +/** + * @brief Rend la scène (joueurs, œufs, ressources, effets, etc.). + */ + +/** + * @brief Définit le type d'effet de diffusion (broadcast). + * @param type Type d'effet à appliquer. + */ + +/** + * @brief Définit la couleur de l'effet de diffusion (broadcast). + * @param color Couleur de l'effet. + */ + +/** + * @brief Définit le type d'effet d'incantation. + * @param type Type d'effet d'incantation. + */ + +/** + * @brief Définit la couleur de l'effet d'incantation. + * @param color Couleur de l'effet. + */ + +/** + * @brief Ajoute un œuf dans la scène. + * @param egg Unique pointer vers le modèle d'œuf à ajouter. + */ + +/** + * @brief Ajoute un joueur dans la scène. + * @param player Unique pointer vers le modèle de joueur à ajouter. + */ + +/** + * @brief Ajoute un modèle de ressource. + * @param type Type de ressource. + * @param model Unique pointer vers le modèle de ressource à ajouter. + */ diff --git a/GUI/src/Renderer/Raylib/Map/PlayerActions/IPlayerAction.hpp b/GUI/src/Renderer/Raylib/Map/PlayerActions/IPlayerAction.hpp index 331c70a..b7b2bd0 100644 --- a/GUI/src/Renderer/Raylib/Map/PlayerActions/IPlayerAction.hpp +++ b/GUI/src/Renderer/Raylib/Map/PlayerActions/IPlayerAction.hpp @@ -16,17 +16,53 @@ namespace zappy { class IPlayerAction { public: + /** + * @brief Destructeur virtuel par défaut. + */ virtual ~IPlayerAction() = default; + /** + * @brief Récupère l'identifiant du joueur associé à cette action. + * @return Identifiant du joueur. + */ virtual int getPlayerId() const = 0; + + /** + * @brief Récupère le type d'action. + * @return Type de l'action. + */ virtual ActionType getActionType() const = 0; + /** + * @brief Indique si l'action a déjà commencé. + * @return true si l'action a commencé, false sinon. + */ virtual bool hasActionStarted() const = 0; + + /** + * @brief Démarre l'action. + */ virtual void startAction() = 0; + /** + * @brief Met à jour l'action avec le temps écoulé et le joueur concerné. + * @param deltaUnits Temps écoulé depuis la dernière mise à jour. + * @param player Référence au joueur affecté par l'action. + */ virtual void update(const float &deltaUnits, APlayerModel &player) = 0; + /** + * @brief Indique si l'action va se terminer dans ce frame. + * @param deltaUnits Temps écoulé depuis la dernière mise à jour. + * @return true si l'action va se terminer, false sinon. + */ virtual bool ActionWillEnd(const float &deltaUnits) const = 0; + + /** + * @brief Termine l'action et effectue les opérations finales. + * @param deltaUnits Temps écoulé depuis la dernière mise à jour. + * @param player Référence au joueur affecté par l'action. + */ virtual void finishAction(const float &deltaUnits, APlayerModel &player) = 0; }; } // namespace raylib diff --git a/GUI/src/Renderer/Raylib/Menu/GameMenu.hpp b/GUI/src/Renderer/Raylib/Menu/GameMenu.hpp index edded03..fd50dd5 100644 --- a/GUI/src/Renderer/Raylib/Menu/GameMenu.hpp +++ b/GUI/src/Renderer/Raylib/Menu/GameMenu.hpp @@ -21,45 +21,133 @@ namespace zappy { namespace raylib { class GameMenu { public: + /** + * @brief Constructeur de GameMenu. + * @param gameState Pointeur partagé vers l'état du jeu. + */ GameMenu(const std::shared_ptr &gameState); + + /** + * @brief Destructeur par défaut. + */ ~GameMenu() = default; + /** + * @brief Initialise les composants du menu. + */ void init(); + /** + * @brief Définit la fréquence actuelle du serveur. + * @param frequency Nouvelle fréquence. + */ void setFrequency(const size_t &frequency) { this->_frequency = frequency; } + + /** + * @brief Récupère la fréquence actuelle. + * @return Fréquence actuelle. + */ size_t getFrequency() const { return this->_frequency; } + + /** + * @brief Vérifie si la fréquence a été modifiée depuis le dernier appel. + * @return true si modifiée, false sinon. + */ bool hasFrequencyChanged(); + /** + * @brief Gère les entrées utilisateur. + * @param inputManager Gestionnaire d'input. + */ void handleInput(const InputManager &inputManager); + + /** + * @brief Met à jour l'état du menu. + */ void update(); + /** + * @brief Affiche le menu à l'écran. + */ void render() const; + /** + * @brief Ajoute un joueur à la liste des joueurs affichés. + * @param id Identifiant du joueur. + */ void addPlayer(const int &id); - void playerBroadcast( - const int &id, - const std::string &message, - const std::string &playerTeam - ); - + /** + * @brief Affiche un message de broadcast reçu par un joueur. + * @param id ID du joueur. + * @param message Message reçu. + * @param playerTeam Nom de l'équipe du joueur. + */ + void playerBroadcast(const int &id, const std::string &message, const std::string &playerTeam); + + /** + * @brief Supprime un joueur du menu. + * @param id ID du joueur à retirer. + */ void removePlayer(const int &id); private: - std::string _decryptBroadcast( - const int &id, - const std::string &message, - const std::string &playerTeam - ); - + /** + * @brief Décrypte le message broadcast d’un joueur. + * @param id ID du joueur. + * @param message Message chiffré. + * @param playerTeam Équipe du joueur. + * @return Message déchiffré et affichable. + */ + std::string _decryptBroadcast(const int &id, const std::string &message, const std::string &playerTeam); + + /** + * @brief Gère les inputs liés à la fréquence. + * @param inputManager Gestionnaire d'input. + */ void _handleFreqInput(const InputManager &inputManager); + + /** + * @brief Gère les inputs liés aux joueurs affichés. + * @param inputManager Gestionnaire d'input. + */ void _handlePlayersInput(const InputManager &inputManager); + /** + * @brief Affiche l'aide pour afficher/masquer les infos. + */ void _renderShowHideHelp(const int &screenWidth, const int &screenHeight) const; + + /** + * @brief Affiche les messages broadcast. + */ void _renderBroadcasts(const int &screenWidth, const int &screenHeight) const; + + /** + * @brief Affiche l’aide du menu. + */ void _renderHelp(const int &screenWidth, const int &screenHeight) const; + + /** + * @brief Affiche et contrôle la fréquence. + */ void _renderFreq(const int &screenWidth, const int &screenHeight) const; + + /** + * @brief Affiche les infos de tous les joueurs sélectionnés. + */ void _renderPlayersInfos(const int &screenWidth, const int &screenHeight) const; + + /** + * @brief Affiche les infos d’un joueur individuel. + * @param playerId ID du joueur. + * @param x Position X du cadre. + * @param y Position Y du cadre. + * @param textSize Taille du texte. + * @param spacingY Espacement vertical entre les lignes. + * @param boxWidth Largeur du cadre. + * @param boxHeight Hauteur du cadre. + */ void _renderPlayerInfo( const int &playerId, const int &x, const int &y, @@ -69,31 +157,49 @@ namespace zappy { const int &boxHeight ) const; + /// Pointeur partagé vers l'état du jeu. const std::shared_ptr _gameState; + /// Taille de police utilisée dans le menu. int _fontSize; + /// Couleur du texte. Color _textColor; + /// Couleur des cadres de fond. Color _boxColor; + /// Fréquence actuelle du jeu. size_t _frequency; + /// Indique si la fréquence a été modifiée. bool _freqChanged; + /// Liste des IDs des joueurs suivis. std::vector _playersIds; + /// Index du premier joueur affiché. int _displayedPlayersIndex; + /// Nombre de joueurs affichés en même temps. int _numberPlayerDisplayed; + /// Largeur des cadres d’infos joueur. int _playerBoxWidth; + /// Historique des messages broadcast. std::list _broadcasts; + /// Section du menu actuellement modifiée. MenuModifiedSection _modifiedSection; + /// Gestionnaires associés aux sections modifiables. std::map _modifiedSectionHandlers; + /// Affiche toutes les infos si activé. bool _displayAll; + /// Raccourcis clavier pour activer/désactiver les parties du menu. std::map _menuStatesKeys; + /// État actif/inactif des différentes sections du menu. std::map _menuStates; + /// Fonctions d'affichage des sections. std::map _menuRenderFunctions; + /// Modificateurs de fréquence liés aux touches. const std::map _frequencyKeyModifiers = { { KEY_UP, 1 }, { KEY_DOWN, -1 }, diff --git a/GUI/src/Renderer/Raylib/Menu/InputManager.hpp b/GUI/src/Renderer/Raylib/Menu/InputManager.hpp index b04d4b3..92e1ac6 100644 --- a/GUI/src/Renderer/Raylib/Menu/InputManager.hpp +++ b/GUI/src/Renderer/Raylib/Menu/InputManager.hpp @@ -18,35 +18,87 @@ namespace zappy { namespace raylib { class InputManager { public: + /** + * @brief État possible d'une touche ou d'un bouton de souris. + */ enum class KeyState { - NONE, - PRESSED, - HELD, - RELEASED + NONE, ///< Aucun état détecté (pas d'interaction). + PRESSED, ///< Touche ou bouton pressé ce frame. + HELD, ///< Touche ou bouton maintenu. + RELEASED ///< Touche ou bouton relâché ce frame. }; + /** + * @brief Met à jour les états des touches et de la souris. + */ void update(); + /** + * @brief Récupère l'état d'une touche spécifique. + * @param key Code de la touche (ex : KEY_SPACE). + * @return État de la touche (PRESSED, HELD, etc.). + */ KeyState getKeyState(int key) const; + + /** + * @brief Vérifie si une touche a été pressée ce frame. + * @param key Code de la touche. + * @return true si pressée, false sinon. + */ bool isKeyPressed(int key) const; + + /** + * @brief Vérifie si une touche a été relâchée ce frame. + * @param key Code de la touche. + * @return true si relâchée, false sinon. + */ bool isKeyReleased(int key) const; + /** + * @brief Récupère l'état d'un bouton de souris. + * @param button Code du bouton (ex : MOUSE_LEFT_BUTTON). + * @return État du bouton. + */ KeyState getMouseButtonState(int button) const; + + /** + * @brief Vérifie si un bouton de souris a été pressé ce frame. + * @param button Code du bouton. + * @return true si pressé, false sinon. + */ bool isMouseButtonPressed(int button) const; + /** + * @brief Récupère le déplacement de la souris depuis le dernier frame. + * @return Vecteur de déplacement. + */ Vector2 getMouseDelta() const { return _mouseDelta; } + + /** + * @brief Récupère la dernière position connue de la souris. + * @return Position de la souris. + */ Vector2 getMousePosition() const { return _lastMousePosition; } private: + /** + * @brief Met à jour l’état d’un ensemble de touches ou boutons. + * @param states Référence vers la map d’état à mettre à jour. + * @param isDownFn Fonction qui indique si une touche/bouton est actuellement enfoncé. + */ void _updateState( std::unordered_map &states, const std::function &isDownFn ); + /// États des touches clavier. std::unordered_map _keyStates; + /// États des boutons de souris. std::unordered_map _mouseButtonStates; + /// Dernière position enregistrée de la souris. Vector2 _lastMousePosition = {0.0f, 0.0f}; + /// Déplacement de la souris depuis la dernière frame. Vector2 _mouseDelta = {0.0f, 0.0f}; }; } // namespace raylib diff --git a/GUI/src/Renderer/Raylib/Menu/PauseMenu.cpp b/GUI/src/Renderer/Raylib/Menu/PauseMenu.cpp index fb50a9e..79b0bad 100644 --- a/GUI/src/Renderer/Raylib/Menu/PauseMenu.cpp +++ b/GUI/src/Renderer/Raylib/Menu/PauseMenu.cpp @@ -56,10 +56,9 @@ void zappy::gui::raylib::PauseMenu::PauseMenu::init() void zappy::gui::raylib::PauseMenu::PauseMenu::handleInput(const InputManager &inputManager) { if (!this->_display) { - if (inputManager.getKeyState(this->_key) == InputManager::KeyState::RELEASED) { + if (inputManager.getKeyState(this->_key) == InputManager::KeyState::RELEASED) this->_display = true; - return; - } + return; } if (this->_menuState == PauseMenuState::MAIN_MENU) { @@ -96,6 +95,7 @@ void zappy::gui::raylib::PauseMenu::PauseMenu::handleInput(const InputManager &i if (inputManager.isKeyReleased(KEY_ENTER)) { this->_shouldChangeScene = true; + this->_menuState = PauseMenuState::MAIN_MENU; if (this->_themes[this->_selectedTheme].name == THEME_CLASSIC) this->_sceneType = SceneType::BASIC; diff --git a/GUI/src/Renderer/Raylib/Menu/PauseMenu.hpp b/GUI/src/Renderer/Raylib/Menu/PauseMenu.hpp index 11eedbe..1359c78 100644 --- a/GUI/src/Renderer/Raylib/Menu/PauseMenu.hpp +++ b/GUI/src/Renderer/Raylib/Menu/PauseMenu.hpp @@ -15,54 +15,137 @@ namespace zappy { namespace gui { namespace raylib { - class PauseMenu - { + class PauseMenu { public: + /** + * @brief Constructeur de PauseMenu. + */ PauseMenu(); + + /** + * @brief Destructeur de PauseMenu. + */ ~PauseMenu(); + /** + * @brief Initialise le menu pause (textures, couleurs, thèmes...). + */ void init(); + /** + * @brief Gère les entrées utilisateur. + * @param inputManager Référence vers le gestionnaire d'input. + */ void handleInput(const InputManager &inputManager); + + /** + * @brief Met à jour l’état du menu pause. + */ void update(); + /** + * @brief Vérifie si un changement de scène est demandé. + * @return true si un changement est requis, false sinon. + */ bool shouldChangeScene(); + + /** + * @brief Retourne le type de scène vers laquelle basculer. + * @return Type de la scène (jeu, menu principal, etc.). + */ SceneType getSceneType() const { return _sceneType; } + /** + * @brief Affiche le menu pause ou le sous-menu des thèmes à l’écran. + */ void render() const; + /** + * @brief Indique si le menu pause est actuellement actif. + * @return true si actif, false sinon. + */ bool isActive() const { return _display; } private: + /** + * @brief Structure représentant un thème disponible dans le menu pause. + */ struct Theme { - std::string name; - Texture2D texture; + std::string name; ///< Nom du thème. + Texture2D texture; ///< Texture associée au thème. }; + /// Taille de la police utilisée pour l’affichage. int _fontSize; + /// Couleur du texte. Color _textColor; + /// Couleur du cadre. Color _boxColor; + /// Couleur de sélection active. Color _selectedColor; + /// Couleur normale (non sélectionnée). Color _normalColor; + /// Indique si le menu est affiché. bool _display; + /// Indique si une scène doit être changée. bool _shouldChangeScene; + /// Scène cible à charger. SceneType _sceneType; + /// Dernière touche utilisée. int _key; + /// Bouton actuellement sélectionné. int _selectedButton; + /// Thème actuellement sélectionné. int _selectedTheme; + /// État courant du menu pause. PauseMenuState _menuState; + /// Liste des thèmes disponibles. std::vector _themes; + /// Indique si le sous-menu des thèmes est actif. bool _isThemeMenu; + /// Index du thème actuellement utilisé. int _currentThemeIndex; + /** + * @brief Calcule un facteur d’échelle uniforme basé sur la résolution. + * @return Facteur d’échelle. + */ float _getUniformScale() const; + + /** + * @brief Affiche le menu pause principal. + * @param scale Facteur d’échelle. + * @param x Position X de base. + * @param y Position Y de base. + * @param w Largeur du cadre. + * @param h Hauteur du cadre. + */ void _renderPauseMenu(float scale, int x, int y, int w, int h) const; + + /** + * @brief Affiche le sous-menu des thèmes disponibles. + * @param scale Facteur d’échelle. + * @param x Position X de base. + * @param y Position Y de base. + * @param w Largeur du cadre. + * @param h Hauteur du cadre. + */ void _renderThemeMenu(float scale, int x, int y, int w, int h) const; + + /** + * @brief Affiche un thème dans le menu des thèmes. + * @param theme Thème à afficher. + * @param x Position X. + * @param y Position Y. + * @param width Largeur du cadre. + * @param height Hauteur du cadre. + * @param selected true si le thème est sélectionné, false sinon. + */ void _renderTheme(const Theme& theme, int x, int y, int width, int height, bool selected) const; }; } diff --git a/GUI/src/Renderer/Raylib/Model/IModel.hpp b/GUI/src/Renderer/Raylib/Model/IModel.hpp index 1fe607e..5f31c90 100644 --- a/GUI/src/Renderer/Raylib/Model/IModel.hpp +++ b/GUI/src/Renderer/Raylib/Model/IModel.hpp @@ -15,34 +15,101 @@ namespace zappy { namespace gui { namespace raylib { + + /** + * @brief Interface représentant un modèle 3D affichable dans la scène. + */ class IModel { public: + /** + * @brief Destructeur virtuel par défaut. + */ virtual ~IModel() = default; + /** + * @brief Initialise le modèle. + */ virtual void init() = 0; // Setters + + /** + * @brief Définit la position du modèle. + * @param position Vecteur de position dans l'espace. + */ virtual void setPosition(const Vector3 &position) = 0; + /** + * @brief Définit l'échelle du modèle. + * @param scale Facteur d'échelle. + */ virtual void setScale(const float &scale) = 0; + + /** + * @brief Définit la rotation du modèle. + * @param rotation Vecteur représentant la rotation (pitch, yaw, roll). + */ virtual void setRotation(const Vector3 &rotation) = 0; + /** + * @brief Définit la couleur du modèle. + * @param color Couleur à appliquer au modèle. + */ virtual void setColor(const Color &color) = 0; // Getters + + /** + * @brief Récupère la position actuelle du modèle. + * @return Vecteur de position. + */ virtual Vector3 getPosition() const = 0; + /** + * @brief Récupère l'échelle actuelle du modèle. + * @return Valeur d'échelle. + */ virtual float getScale() const = 0; + + /** + * @brief Récupère la rotation actuelle du modèle. + * @return Vecteur de rotation. + */ virtual Vector3 getRotation() const = 0; + /** + * @brief Récupère la couleur actuelle du modèle. + * @return Couleur appliquée au modèle. + */ virtual Color getColor() const = 0; + /** + * @brief Met à jour l'état du modèle (par exemple animation ou déplacement). + * @param deltaUnits Temps ou facteur de déplacement depuis la dernière mise à jour. + */ virtual void update(const float &deltaUnits) = 0; + /** + * @brief Applique une échelle supplémentaire au modèle. + * @param scale Facteur d'échelle à appliquer. + */ virtual void scale(const float &scale) = 0; + + /** + * @brief Déplace le modèle. + * @param translation Vecteur de translation. + */ virtual void translate(const Vector3 &translation) = 0; + + /** + * @brief Applique une rotation supplémentaire au modèle. + * @param rotation Vecteur de rotation. + */ virtual void rotate(const Vector3 &rotation) = 0; + /** + * @brief Affiche le modèle à l'écran. + */ virtual void render() = 0; }; } // namespace raylib diff --git a/GUI/src/Renderer/Raylib/RaylibRenderer.cpp b/GUI/src/Renderer/Raylib/RaylibRenderer.cpp index 3d1793b..5c505f7 100644 --- a/GUI/src/Renderer/Raylib/RaylibRenderer.cpp +++ b/GUI/src/Renderer/Raylib/RaylibRenderer.cpp @@ -7,6 +7,8 @@ #include "RaylibRenderer.hpp" +/// @brief Constructeur du renderer Raylib. +/// Initialise les pointeurs de menu et la scène par défaut. zappy::gui::RaylibRenderer::RaylibRenderer() : ARenderer::ARenderer(), _sceneType(raylib::SceneType::BASIC), @@ -18,6 +20,8 @@ zappy::gui::RaylibRenderer::RaylibRenderer() : SetTraceLogLevel(LOG_NONE); } +/// @brief Initialise la fenêtre, les menus et la scène. +/// Lance la fenêtre Raylib en plein écran et configure les éléments graphiques du jeu. void zappy::gui::RaylibRenderer::init() { static constexpr const char *title = "Zappy"; @@ -36,31 +40,19 @@ void zappy::gui::RaylibRenderer::init() this->_gameMenu = std::make_unique(this->_gameState); this->_gameMenu->init(); - // game::Orientation orientation = game::Orientation::SOUTH; - // game::Player player(0, 2, 6, orientation); - // this->addPlayer(player); - - // this->updatePlayerPosition(0, 2, 6, game::Orientation::WEST); - // this->updatePlayerPosition(0, 2, 6, game::Orientation::NORTH); - // this->updatePlayerPosition(0, 2, 5, game::Orientation::NORTH); - // this->updatePlayerPosition(0, 2, 4, game::Orientation::NORTH); - // this->updatePlayerPosition(0, 2, 3, game::Orientation::NORTH); - // this->updatePlayerPosition(0, 2, 2, game::Orientation::NORTH); - // this->updatePlayerPosition(0, 2, 1, game::Orientation::NORTH); - // this->updatePlayerPosition(0, 2, 0, game::Orientation::NORTH); - - // this->startIncantation(2, 2, 1, {0}); - // this->endIncantation(2, 2, true); - ARenderer::init(); } +/// @brief Met à jour la fréquence du jeu. +/// @param frequency Nouvelle fréquence du serveur (unités de temps). void zappy::gui::RaylibRenderer::setFrequency(const size_t &frequency) { ARenderer::setFrequency(frequency); this->_gameMenu->setFrequency(frequency); } +/// @brief Gère les entrées clavier de l’utilisateur. +/// Redirige les entrées vers la scène active ou les menus si nécessaire. void zappy::gui::RaylibRenderer::handleInput() { this->_inputManager.update(); @@ -78,6 +70,8 @@ void zappy::gui::RaylibRenderer::handleInput() this->_gameMenu->handleInput(this->_inputManager); } +/// @brief Met à jour la scène, les menus et la caméra. +/// Gère les actions utilisateur, les changements de fréquence et les transitions de scène. void zappy::gui::RaylibRenderer::update() { ARenderer::update(); @@ -101,25 +95,32 @@ void zappy::gui::RaylibRenderer::update() this->_setScene(this->_pauseMenu->getSceneType()); } +/// @brief Effectue le rendu complet de la scène actuelle. +/// Dessine la scène, le menu de jeu et le menu pause à l’écran. void zappy::gui::RaylibRenderer::render() const { BeginDrawing(); ClearBackground(SKYBLUE); this->_scene->render(); - this->_gameMenu->render(); - this->_pauseMenu->render(); EndDrawing(); } +/// @brief Vérifie si la fenêtre doit être fermée. +/// @return true si l’utilisateur a demandé à fermer la fenêtre. bool zappy::gui::RaylibRenderer::shouldClose() const { return WindowShouldClose(); } +/// @brief Ajoute un œuf à la scène. +/// @param eggId Identifiant de l’œuf. +/// @param fatherId Identifiant du joueur ayant pondu l’œuf. +/// @param x Position X. +/// @param y Position Y. void zappy::gui::RaylibRenderer::addEgg(const int &eggId, const int &fatherId, const int &x, @@ -129,6 +130,8 @@ void zappy::gui::RaylibRenderer::addEgg(const int &eggId, this->_scene->addEgg(eggId); } +/// @brief Ajoute un joueur à la scène et au menu de jeu. +/// @param player Référence vers le joueur à ajouter. void zappy::gui::RaylibRenderer::addPlayer(const game::Player &player) { ARenderer::addPlayer(player); @@ -139,6 +142,11 @@ void zappy::gui::RaylibRenderer::addPlayer(const game::Player &player) this->_gameMenu->addPlayer(id); } +/// @brief Met à jour la position et l’orientation d’un joueur. +/// @param id Identifiant du joueur. +/// @param x Nouvelle position X. +/// @param y Nouvelle position Y. +/// @param orientation Orientation du joueur. void zappy::gui::RaylibRenderer::updatePlayerPosition(const int &id, const int &x, const int &y, @@ -148,26 +156,36 @@ void zappy::gui::RaylibRenderer::updatePlayerPosition(const int &id, ARenderer::updatePlayerPosition(id, x, y, orientation); } +/// @brief Met à jour le niveau d’un joueur. +/// @param id Identifiant du joueur. +/// @param level Nouveau niveau. void zappy::gui::RaylibRenderer::updatePlayerLevel(const int &id, const size_t &level) { ARenderer::updatePlayerLevel(id, level); } +/// @brief Met à jour l’inventaire d’un joueur. +/// @param id Identifiant du joueur. +/// @param inventory Nouvel inventaire du joueur. void zappy::gui::RaylibRenderer::updatePlayerInventory(const int &id, const game::Inventory &inventory) { ARenderer::updatePlayerInventory(id, inventory); } +/// @brief Joue l’animation d’expulsion d’un joueur. +/// @param id Identifiant du joueur expulsé. void zappy::gui::RaylibRenderer::playerExpulsion(const int &id) { this->_scene->playerExpulsion(id); ARenderer::playerExpulsion(id); } +/// @brief Affiche un message de broadcast d’un joueur. +/// @param id Identifiant du joueur. +/// @param message Message envoyé. void zappy::gui::RaylibRenderer::playerBroadcast(const int &id, const std::string &message) { ARenderer::playerBroadcast(id, message); - this->_scene->playerBroadcast(id, message); std::string playerTeam = this->_gameState->getPlayerById(id).teamName; @@ -175,6 +193,11 @@ void zappy::gui::RaylibRenderer::playerBroadcast(const int &id, const std::strin this->_gameMenu->playerBroadcast(id, message, playerTeam); } +/// @brief Démarre une incantation. +/// @param x Position X. +/// @param y Position Y. +/// @param level Niveau de l’incantation. +/// @param playerIds Liste des identifiants des joueurs impliqués. void zappy::gui::RaylibRenderer::startIncantation( const int &x, const int &y, const int &level, @@ -184,38 +207,52 @@ void zappy::gui::RaylibRenderer::startIncantation( this->_scene->startIncantation(x, y, level, playerIds); } +/// @brief Termine une incantation. +/// @param x Position X. +/// @param y Position Y. +/// @param result Résultat de l’incantation (réussite ou échec). void zappy::gui::RaylibRenderer::endIncantation(const int &x, const int &y, const bool &result) { ARenderer::endIncantation(x, y, result); this->_scene->endIncantation(x, y, result); } +/// @brief Fait éclore un œuf. +/// @param eggId Identifiant de l’œuf. void zappy::gui::RaylibRenderer::hatchEgg(const int &eggId) { ARenderer::hatchEgg(eggId); this->_scene->hatchEgg(eggId); } +/// @brief Supprime un œuf de la scène. +/// @param eggId Identifiant de l’œuf. void zappy::gui::RaylibRenderer::removeEgg(const int &eggId) { ARenderer::removeEgg(eggId); this->_scene->removeEgg(eggId); } +/// @brief Supprime un joueur de la scène et du menu. +/// @param id Identifiant du joueur. void zappy::gui::RaylibRenderer::removePlayer(const int &id) { ARenderer::removePlayer(id); - this->_scene->removePlayer(id); this->_gameMenu->removePlayer(id); } +/// @brief Termine la partie et affiche l’équipe gagnante. +/// @param teamName Nom de l’équipe gagnante. void zappy::gui::RaylibRenderer::endGame(const std::string &teamName) { ARenderer::endGame(teamName); this->_scene->endGame(teamName); } +/// @brief Change la scène active selon le type donné. +/// Réinitialise l’ancienne scène et charge tous les œufs et joueurs depuis l’état du jeu. +/// @param sceneType Type de la nouvelle scène à activer. void zappy::gui::RaylibRenderer::_setScene(const raylib::SceneType &sceneType) { if (this->_scene) @@ -226,16 +263,17 @@ void zappy::gui::RaylibRenderer::_setScene(const raylib::SceneType &sceneType) this->_scene->init(); const auto &eggs = this->_gameState->getEggs(); - for (const auto &egg : eggs) this->_scene->addEgg(egg.getId()); const auto &players = this->_gameState->getPlayers(); - for (const auto &player : players) this->_scene->addPlayer(player.getId()); } +/// @brief Vérifie si une touche non autorisée est pressée. +/// Empêche certaines touches d’interférer avec la navigation. +/// @return true si une touche non désirée est pressée. bool zappy::gui::RaylibRenderer::_checkUnwantedInput() const { const std::vector unwantedKeys = { diff --git a/GUI/src/Renderer/Raylib/Scene/AScene.cpp b/GUI/src/Renderer/Raylib/Scene/AScene.cpp index 05dccbe..6b0b497 100644 --- a/GUI/src/Renderer/Raylib/Scene/AScene.cpp +++ b/GUI/src/Renderer/Raylib/Scene/AScene.cpp @@ -15,6 +15,11 @@ zappy::gui::raylib::AScene::AScene(const std::shared_ptr &gameS _mapRenderer(std::make_unique(this->_gameState->getMap())) {} +/** @brief Initialise la scène. + * + * Configure la caméra en fonction de la taille de la carte + * et initialise l'audio. + */ void zappy::gui::raylib::AScene::init() { constexpr Vector3 up = { 0.0f, 1.0f, 0.0f }; @@ -42,6 +47,10 @@ void zappy::gui::raylib::AScene::init() SetMasterVolume(0.5f); } +/** @brief Met à jour les éléments de la scène. + * + * Met à jour le rendu de la carte, le ciel et la musique. + */ void zappy::gui::raylib::AScene::update() { this->_mapRenderer->update(this->_gameState->getFrequency()); @@ -49,6 +58,10 @@ void zappy::gui::raylib::AScene::update() this->_music.update(); } +/** @brief Dessine la scène à l'écran. + * + * Affiche la musique, le ciel et la carte en mode 3D. + */ void zappy::gui::raylib::AScene::render() const { this->_music.render(); @@ -61,11 +74,19 @@ void zappy::gui::raylib::AScene::render() const EndMode3D(); } +/** @brief Gère les entrées utilisateur. + * + * @param inputManager Le gestionnaire d'entrée. + */ void zappy::gui::raylib::AScene::handleInput(InputManager &inputManager) { (void)inputManager; } +/** @brief Ajoute un œuf à la scène. + * + * @param id L'identifiant de l'œuf à ajouter. + */ void zappy::gui::raylib::AScene::addEgg(const int &id) { // Egg supposed to be added to the map @@ -74,6 +95,10 @@ void zappy::gui::raylib::AScene::addEgg(const int &id) this->_mapRenderer->setEggPosition(id, egg.x, egg.y); } +/** @brief Ajoute un joueur à la scène. + * + * @param id L'identifiant du joueur à ajouter. + */ void zappy::gui::raylib::AScene::addPlayer(const int &id) { game::Player &player = this->_gameState->getPlayerById(id); @@ -81,6 +106,13 @@ void zappy::gui::raylib::AScene::addPlayer(const int &id) this->_mapRenderer->setPlayerPosition(id, player.x, player.y, player.orientation); } +/** @brief Met à jour la position et l’orientation d’un joueur. + * + * @param id L’identifiant du joueur. + * @param x La nouvelle position en x. + * @param y La nouvelle position en y. + * @param orientation La nouvelle orientation du joueur. + */ void zappy::gui::raylib::AScene::updatePlayerPosition(const int &id, const int &x, const int &y, const game::Orientation &orientation) { game::Player player = this->_gameState->getPlayerById(id); @@ -125,6 +157,10 @@ void zappy::gui::raylib::AScene::updatePlayerPosition(const int &id, const int & } } +/** @brief Déclenche l’expulsion des autres joueurs autour d’un joueur. + * + * @param id L’identifiant du joueur qui expulse. + */ void zappy::gui::raylib::AScene::playerExpulsion(const int &id) { game::Player &playerThatExpelled = this->_gameState->getPlayerById(id); @@ -153,12 +189,24 @@ void zappy::gui::raylib::AScene::playerExpulsion(const int &id) } } +/** @brief Déclenche une animation de broadcast pour un joueur. + * + * @param id L’identifiant du joueur. + * @param message Le message broadcasté (non utilisé ici). + */ void zappy::gui::raylib::AScene::playerBroadcast(const int &id, const std::string &message) { this->_mapRenderer->playerBroadcast(id); (void)message; } +/** @brief Lance une incantation sur une case. + * + * @param x Coordonnée x de la case. + * @param y Coordonnée y de la case. + * @param level Le niveau de l'incantation. + * @param playerIds Liste des identifiants des joueurs impliqués. + */ void zappy::gui::raylib::AScene::startIncantation( const int &x, const int &y, const int &level, @@ -168,21 +216,41 @@ void zappy::gui::raylib::AScene::startIncantation( (void)level; } +/** @brief Termine une incantation. + * + * @param x Coordonnée x de la case. + * @param y Coordonnée y de la case. + * @param result Résultat de l'incantation (réussie ou échouée). + */ void zappy::gui::raylib::AScene::endIncantation(const int &x, const int &y, const bool &result) { this->_mapRenderer->endIncantation(x, y, result); } + +/** @brief Fait éclore un œuf. + * + * @param id L'identifiant de l'œuf. + */ void zappy::gui::raylib::AScene::hatchEgg(const int &id) { this->removeEgg(id); } +/** @brief Supprime un œuf de la scène. + * + * @param id L'identifiant de l'œuf à retirer. + */ void zappy::gui::raylib::AScene::removeEgg(const int &id) { this->_mapRenderer->removeEgg(id); } + +/** @brief Supprime un joueur de la scène. + * + * @param id L'identifiant du joueur à retirer. + */ void zappy::gui::raylib::AScene::removePlayer(const int &id) { this->_mapRenderer->removePlayer(id); diff --git a/GUI/src/Renderer/Raylib/Scene/IScene.hpp b/GUI/src/Renderer/Raylib/Scene/IScene.hpp index 53c7d53..639006a 100644 --- a/GUI/src/Renderer/Raylib/Scene/IScene.hpp +++ b/GUI/src/Renderer/Raylib/Scene/IScene.hpp @@ -12,49 +12,153 @@ #include "GameState.hpp" -#include "raylib.h" +#include namespace zappy { namespace gui { namespace raylib { + /** + * @brief Interface représentant une scène dans le GUI. + */ class IScene { public: + /** + * @brief Destructeur virtuel par défaut. + */ virtual ~IScene() = default; + /** + * @brief Initialise la scène. + */ virtual void init() = 0; + /** + * @brief Récupère une référence modifiable vers la caméra. + * + * @return Référence modifiable vers la caméra. + */ virtual Camera &getCamera() = 0; + + /** + * @brief Récupère une référence constante vers la caméra. + * + * @return Référence constante vers la caméra. + */ virtual const Camera &getCamera() const = 0; + /** + * @brief Gère les entrées utilisateur. + * + * @param inputManager Gestionnaire des entrées utilisateur. + */ virtual void handleInput(InputManager &inputManager) = 0; + + /** + * @brief Met à jour l'état de la scène. + */ virtual void update() = 0; + /** + * @brief Rendu de la scène. + */ virtual void render() const = 0; + /** + * @brief Indique si la scène doit se fermer. + * + * @return true si la scène doit se fermer, sinon false. + */ virtual bool shouldClose() const = 0; + /** + * @brief Ajoute un œuf à la scène. + * + * @param eggId Identifiant de l'œuf. + */ virtual void addEgg(const int &eggId) = 0; + + /** + * @brief Ajoute un joueur à la scène. + * + * @param id Identifiant du joueur. + */ virtual void addPlayer(const int &id) = 0; + /** + * @brief Met à jour la position et l'orientation d'un joueur. + * + * @param id Identifiant du joueur. + * @param x Nouvelle position X. + * @param y Nouvelle position Y. + * @param orientation Nouvelle orientation. + */ virtual void updatePlayerPosition(const int &id, const int &x, const int &y, const game::Orientation &orientation) = 0; + /** + * @brief Déclenche une expulsion de joueur. + * + * @param id Identifiant du joueur. + */ virtual void playerExpulsion(const int &id) = 0; + /** + * @brief Envoie un message de broadcast d'un joueur. + * + * @param id Identifiant du joueur. + * @param message Message diffusé. + */ virtual void playerBroadcast(const int &id, const std::string &message) = 0; + /** + * @brief Démarre une incantation. + * + * @param x Position X de l'incantation. + * @param y Position Y de l'incantation. + * @param level Niveau de l'incantation. + * @param playerIds Liste des identifiants des joueurs participants. + */ virtual void startIncantation( const int &x, const int &y, const int &level, const std::vector &playerIds ) = 0; + + /** + * @brief Termine une incantation. + * + * @param x Position X de l'incantation. + * @param y Position Y de l'incantation. + * @param result Résultat de l'incantation (true si réussie). + */ virtual void endIncantation(const int &x, const int &y, const bool &result) = 0; + /** + * @brief Fait éclore un œuf. + * + * @param eggId Identifiant de l'œuf. + */ virtual void hatchEgg(const int &eggId) = 0; + /** + * @brief Supprime un œuf. + * + * @param eggId Identifiant de l'œuf. + */ virtual void removeEgg(const int &eggId) = 0; + + /** + * @brief Supprime un joueur. + * + * @param id Identifiant du joueur. + */ virtual void removePlayer(const int &id) = 0; + /** + * @brief Termine la partie. + * + * @param teamName Nom de l'équipe gagnante. + */ virtual void endGame(const std::string &teamName) = 0; }; } // namespace raylib diff --git a/GUI/src/Renderer/Raylib/Scene/Skybox.cpp b/GUI/src/Renderer/Raylib/Scene/Skybox.cpp index 355dabe..3e98621 100644 --- a/GUI/src/Renderer/Raylib/Scene/Skybox.cpp +++ b/GUI/src/Renderer/Raylib/Scene/Skybox.cpp @@ -8,6 +8,9 @@ #include "Skybox.hpp" #include "AssetPaths.hpp" +/// @brief Initialise le skybox avec l'image donnée. +/// @param imagePath Chemin de l'image HDR utilisée pour le skybox. +/// @return true si le skybox est correctement initialisé, false sinon. bool zappy::gui::raylib::Skybox::init(const std::string &imagePath) { this->_mesh = GenMeshCube(1.0f, 1.0f, 1.0f); @@ -63,6 +66,7 @@ bool zappy::gui::raylib::Skybox::init(const std::string &imagePath) return true; } +/// @brief Met à jour le skybox. Si un nouveau fichier est déposé, charge l'image en tant que nouveau skybox. void zappy::gui::raylib::Skybox::update() { if (IsFileDropped()) { @@ -82,6 +86,7 @@ void zappy::gui::raylib::Skybox::update() } } +/// @brief Affiche le skybox dans la scène. void zappy::gui::raylib::Skybox::render() const { rlDisableBackfaceCulling(); @@ -91,12 +96,14 @@ void zappy::gui::raylib::Skybox::render() const rlEnableDepthMask(); } +/// @brief Affiche des informations sur le fichier utilisé pour le skybox (en bas de l'écran). void zappy::gui::raylib::Skybox::renderInfo() const { DrawText(TextFormat("Skybox image: %s", GetFileName(this->_skyboxFileName.c_str())), 10, GetScreenHeight() - 20, 10, BLACK); } +/// @brief Libère toutes les ressources associées au skybox (shader, textures, modèle). void zappy::gui::raylib::Skybox::unload() { if (this->_model.materialCount > 0) @@ -104,3 +111,65 @@ void zappy::gui::raylib::Skybox::unload() UnloadTexture(this->_model.materials[0].maps[MATERIAL_MAP_CUBEMAP].texture); UnloadModel(this->_model); } + +/** + * @brief Génère un cubemap à partir d'une texture HDR. + * + * @param panorama Texture2D contenant l'image HDR. + * @param shader Shader utilisé pour le rendu. + * @param size Taille du cubemap. + * @param format Format de la texture. + * @return TextureCubemap généré. + */ +TextureCubemap zappy::gui::raylib::Skybox::_genCubemapFromHDR(const Texture2D &panorama, Shader shader, int size, int format) { + TextureCubemap cubemap = {}; + + rlDisableBackfaceCulling(); + + unsigned int rbo = rlLoadTextureDepth(size, size, true); + cubemap.id = rlLoadTextureCubemap(nullptr, size, format, 1); + + unsigned int fbo = rlLoadFramebuffer(); + rlFramebufferAttach(fbo, rbo, RL_ATTACHMENT_DEPTH, RL_ATTACHMENT_RENDERBUFFER, 0); + rlFramebufferAttach(fbo, cubemap.id, RL_ATTACHMENT_COLOR_CHANNEL0, RL_ATTACHMENT_CUBEMAP_POSITIVE_X, 0); + + rlEnableShader(shader.id); + Matrix matProj = MatrixPerspective(90.0f * DEG2RAD, 1.0f, RL_CULL_DISTANCE_NEAR, RL_CULL_DISTANCE_FAR); + rlSetUniformMatrix(shader.locs[SHADER_LOC_MATRIX_PROJECTION], matProj); + + Matrix fboViews[6] = { + MatrixLookAt({0,0,0}, {1,0,0}, {0,-1,0}), + MatrixLookAt({0,0,0}, {-1,0,0}, {0,-1,0}), + MatrixLookAt({0,0,0}, {0,1,0}, {0,0,1}), + MatrixLookAt({0,0,0}, {0,-1,0}, {0,0,-1}), + MatrixLookAt({0,0,0}, {0,0,1}, {0,-1,0}), + MatrixLookAt({0,0,0}, {0,0,-1}, {0,-1,0}) + }; + + rlViewport(0, 0, size, size); + rlActiveTextureSlot(0); + rlEnableTexture(panorama.id); + + for (int i = 0; i < 6; ++i) { + rlSetUniformMatrix(shader.locs[SHADER_LOC_MATRIX_VIEW], fboViews[i]); + rlFramebufferAttach(fbo, cubemap.id, RL_ATTACHMENT_COLOR_CHANNEL0, RL_ATTACHMENT_CUBEMAP_POSITIVE_X + i, 0); + rlEnableFramebuffer(fbo); + rlClearScreenBuffers(); + rlLoadDrawCube(); + } + + rlDisableShader(); + rlDisableTexture(); + rlDisableFramebuffer(); + rlUnloadFramebuffer(fbo); + + rlViewport(0, 0, rlGetFramebufferWidth(), rlGetFramebufferHeight()); + rlEnableBackfaceCulling(); + + cubemap.width = size; + cubemap.height = size; + cubemap.mipmaps = 1; + cubemap.format = format; + + return cubemap; +} diff --git a/GUI/src/Renderer/Raylib/Scene/Skybox.hpp b/GUI/src/Renderer/Raylib/Scene/Skybox.hpp index 11fc228..adbc7ae 100644 --- a/GUI/src/Renderer/Raylib/Scene/Skybox.hpp +++ b/GUI/src/Renderer/Raylib/Scene/Skybox.hpp @@ -7,7 +7,8 @@ #pragma once -#include +#include "AssetPaths.hpp" + #include #include #include @@ -42,58 +43,7 @@ namespace zappy { Model _model = {}; Mesh _mesh = {}; - TextureCubemap genCubemapFromHDR(const Texture2D &panorama, Shader shader, int size, int format) { - TextureCubemap cubemap = {}; - - rlDisableBackfaceCulling(); - - unsigned int rbo = rlLoadTextureDepth(size, size, true); - cubemap.id = rlLoadTextureCubemap(nullptr, size, format, 1); - - unsigned int fbo = rlLoadFramebuffer(); - rlFramebufferAttach(fbo, rbo, RL_ATTACHMENT_DEPTH, RL_ATTACHMENT_RENDERBUFFER, 0); - rlFramebufferAttach(fbo, cubemap.id, RL_ATTACHMENT_COLOR_CHANNEL0, RL_ATTACHMENT_CUBEMAP_POSITIVE_X, 0); - - rlEnableShader(shader.id); - Matrix matProj = MatrixPerspective(90.0f * DEG2RAD, 1.0f, RL_CULL_DISTANCE_NEAR, RL_CULL_DISTANCE_FAR); - rlSetUniformMatrix(shader.locs[SHADER_LOC_MATRIX_PROJECTION], matProj); - - Matrix fboViews[6] = { - MatrixLookAt({0,0,0}, {1,0,0}, {0,-1,0}), - MatrixLookAt({0,0,0}, {-1,0,0}, {0,-1,0}), - MatrixLookAt({0,0,0}, {0,1,0}, {0,0,1}), - MatrixLookAt({0,0,0}, {0,-1,0}, {0,0,-1}), - MatrixLookAt({0,0,0}, {0,0,1}, {0,-1,0}), - MatrixLookAt({0,0,0}, {0,0,-1}, {0,-1,0}) - }; - - rlViewport(0, 0, size, size); - rlActiveTextureSlot(0); - rlEnableTexture(panorama.id); - - for (int i = 0; i < 6; ++i) { - rlSetUniformMatrix(shader.locs[SHADER_LOC_MATRIX_VIEW], fboViews[i]); - rlFramebufferAttach(fbo, cubemap.id, RL_ATTACHMENT_COLOR_CHANNEL0, RL_ATTACHMENT_CUBEMAP_POSITIVE_X + i, 0); - rlEnableFramebuffer(fbo); - rlClearScreenBuffers(); - rlLoadDrawCube(); - } - - rlDisableShader(); - rlDisableTexture(); - rlDisableFramebuffer(); - rlUnloadFramebuffer(fbo); - - rlViewport(0, 0, rlGetFramebufferWidth(), rlGetFramebufferHeight()); - rlEnableBackfaceCulling(); - - cubemap.width = size; - cubemap.height = size; - cubemap.mipmaps = 1; - cubemap.format = format; - - return cubemap; - } + TextureCubemap _genCubemapFromHDR(const Texture2D &panorama, Shader shader, int size, int format); }; } } diff --git a/README.md b/README.md index f1203a4..4052fb6 100644 --- a/README.md +++ b/README.md @@ -1 +1,158 @@ -# Zappy +# 🛰️ ZAPPY + +ZAPPY is a multiplayer real-time strategy game where several teams compete on a toroidal tile-based map to elevate their players through resource collection, coordination, and survival. The first team to have six players reach the maximum level wins. + +## 🗂️ Project Structure + +- `zappy_server/` — Main server written in C++ +- `zappy_gui/` — Graphical interface written in C++ (using Raylib) +- `zappy_ai/` — AI client written in your language of choice (Python) + +Gui and Server are compiled via makefile +```bash +./build.sh +``` +The Client can be compiled thanks to the following command +```bash +python3 Client/client.py --port [PORT] --team [TEAM] +``` + +## 🧠 Concept + +Each team controls several drones (players) that spawn on a shared tile-based world called **Trantor**. Drones must: +- Gather food to survive +- Collect resources (7 types) +- Collaborate to perform **elevation rituals** to gain levels + +A player dies if they run out of food. Elevations are cooperative and require exact conditions to succeed. + +## 🌍 World Mechanics + +- The world is a **wrap-around 2D map** (toroidal) +- The map is populated with food and six resource types: + `linemate`, `deraumere`, `sibur`, `mendiane`, `phiras`, `thystame` +- Resources respawn every 20 time units + +The number of resources at spawn time is calculated using: +``` +quantity = width * height * density +``` + +## 🧾 How to Run + +### 🧠 Server + +```bash +./zappy_server -p PORT -x WIDTH -y HEIGHT -n TEAM1 TEAM2 ... -c CLIENTS_PER_TEAM -f FREQ +``` + +| Flag | Description | +|--------|-------------------------------------------------| +| `-p` | Port to listen on | +| `-x` | Map width | +| `-y` | Map height | +| `-n` | List of team names | +| `-c` | Number of clients per team | +| `-f` | Game frequency (time unit reciprocal) | + +### 🖥️ GUI + +```bash +./zappy_gui -p PORT -h HOST +``` + +The GUI connects to the server and visualizes the world in 2D (SFML-based). It receives real-time updates for tiles and player actions. + +### 🤖 AI Client + +```bash +./zappy_ai -p PORT -n TEAM_NAME -h HOST +``` + +The AI controls one drone. It sends commands to the server autonomously to: +- Gather food/resources +- Track inventory +- Coordinate elevations +- Reproduce (fork command) +- Communicate via broadcast + +## 🕹️ Game Flow + +1. Each team starts with `N` player slots (eggs). +2. Drones connect and spawn randomly. +3. Players must collect food to stay alive (`1 unit = 126 time units`). +4. Players must gather specific resources and team members to level up via the **incantation** command. +5. Level 8 requires a full group of 6 to win. + +## 🧬 Elevation Requirements + +| Level | Players | Linemate | Deraumere | Sibur | Mendiane | Phiras | Thystame | +|-------|---------|----------|-----------|-------|-----------|--------|----------| +| 1→2 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | +| 2→3 | 2 | 1 | 1 | 1 | 0 | 0 | 0 | +| 3→4 | 2 | 2 | 0 | 1 | 0 | 2 | 0 | +| 4→5 | 4 | 1 | 1 | 2 | 0 | 1 | 0 | +| 5→6 | 4 | 1 | 2 | 1 | 3 | 0 | 0 | +| 6→7 | 6 | 1 | 2 | 3 | 0 | 1 | 0 | +| 7→8 | 6 | 2 | 2 | 2 | 2 | 2 | 1 | + +> All players involved in an incantation must be of the same level. Stones are consumed if elevation succeeds. + +## 🧭 Commands Summary + +Clients communicate with the server using simple newline-terminated strings. Here's a few core commands: + +| Command | Description | Time Cost (in `f` units) | +|---------------|--------------------------------------------|---------------------------| +| `Forward` | Move forward | `7/f` | +| `Right`/`Left`| Turn right/left | `7/f` | +| `Look` | Get visible surroundings | `7/f` | +| `Inventory` | Get current inventory | `1/f` | +| `Broadcast` | Send a message | `7/f` | +| `Connect_nbr` | Remaining egg slots for the team | instant | +| `Fork` | Lay an egg | `42/f` | +| `Take`/`Set` | Pick up or drop a resource | `7/f` | +| `Incantation` | Start level-up ritual | `300/f` | + +If a command is invalid or fails: server replies with `ko`. + +## 📢 Broadcast & Direction + +When a player uses `Broadcast`, all other players receive: +``` +message K, text +``` +Where `K` is the direction (tile ID) relative to the receiver's orientation. + +## 🧪 Development & Debugging + +- All sockets are handled via `poll()` (non-blocking I/O) +- Protocol is fully ASCII, line-based +- GUI identifies itself by sending `GRAPHIC` as team name +- AI clients are autonomous after launch +- Multiple clients can run on localhost for testing + +## 📸 GUI Features + +- Real-time tile updates +- Resource and player display +- Support for player events: moves, pickups, drops, deaths, elevations +- Optimized updates via tile-based event broadcasting + +## ✅ Win Condition + +The game ends when **one team has at least six players at level 8**. + +--- + +## 🛠️ Dependencies + +- `zappy_gui`: SFML (>= 2.5) +- `zappy_server`: C standard library only +- `zappy_ai`: no constraints, can use any libs + +--- + +## 🧑‍💻 Authors + +Developed as part of the Epitech YEP project.