Bibliothèques Graphiques
Implémentation et utilisation des bibliothèques d'affichage dans ARCADE
Introduction aux bibliothèques graphiques
Les bibliothèques graphiques sont des composants essentiels du projet ARCADE. Elles permettent d'afficher les jeux avec différents rendus graphiques tout en maintenant une logique de jeu cohérente. L'architecture du projet permet de changer de bibliothèque graphique en temps réel, sans redémarrer l'application.
Chargement dynamique
Les bibliothèques graphiques sont chargées dynamiquement à l'exécution sous forme de bibliothèques partagées (.so).
Interface IDisplayModule
Toutes les bibliothèques graphiques doivent implémenter l'interface IDisplayModule. Cette interface définit les méthodes nécessaires pour initialiser, afficher et gérer les entrées utilisateur.
namespace arcade {
class IDisplayModule {
public:
virtual ~IDisplayModule() = default;
virtual void init() = 0; // Initialise la bibliothèque graphique
virtual void stop() = 0; // Arrête la bibliothèque graphique
virtual void clear() = 0; // Efface l'écran
virtual void render() = 0; // Effectue le rendu
virtual void present() = 0; // Présente le rendu à l'écran
virtual bool isKeyPressed(const std::string &key) = 0; // Vérifie si une touche est pressée
virtual std::string getName() const = 0; // Retourne le nom de la bibliothèque
virtual void handleInput() = 0; // Gère les entrées utilisateur
virtual bool shouldQuit() const = 0; // Vérifie si l'utilisateur veut quitter
virtual void drawRect(int x, int y, int width, int height, int r, int g, int b, int a) = 0; // Dessine un rectangle
virtual void drawText(const std::string& text, int x, int y, int r, int g, int b, int a) = 0; // Affiche du texte
virtual void drawCircle(int x, int y, int radius, int r, int g, int b, int a) = 0; // Dessine un cercle
};
}
Description des méthodes
init()
Initialise la bibliothèque graphique (création de fenêtre, chargement de ressources, etc.).
stop()
Arrête proprement la bibliothèque graphique (libération des ressources, fermeture de fenêtre).
clear()
Efface le contenu de l'écran pour préparer un nouveau rendu.
render()
Effectue le rendu des éléments graphiques.
present()
Présente le rendu à l'écran (équivalent à un swap buffer).
isKeyPressed(const std::string &key)
Vérifie si une touche spécifique est pressée. Les touches sont identifiées par des chaînes standardisées comme "UP", "DOWN", "ESCAPE", etc.
getName() const
Retourne le nom de la bibliothèque graphique pour l'affichage dans l'interface.
handleInput()
Gère les événements d'entrée utilisateur (clavier, souris).
shouldQuit() const
Indique si l'utilisateur a demandé à quitter l'application (par exemple en fermant la fenêtre).
drawRect(int x, int y, int width, int height, int r, int g, int b, int a)
Dessine un rectangle aux coordonnées (x,y) avec la largeur, hauteur et couleur RGBA spécifiées.
drawText(const std::string& text, int x, int y, int r, int g, int b, int a)
Affiche du texte aux coordonnées (x,y) avec la couleur RGBA spécifiée.
drawCircle(int x, int y, int radius, int r, int g, int b, int a)
Dessine un cercle aux coordonnées (x,y) avec le rayon et la couleur RGBA spécifiés.
virtual std::string getTextInput(const std::string& prompt, const std::string& initialText = "") = 0;
Permet de rentrer des caractères dans une chaine de charactères.
Exemple d'implémentation: SFML
Voici un exemple d'implémentation de l'interface IDisplayModule avec la bibliothèque SFML.
/*
** EPITECH PROJECT, 2025
** B-OOP-400-COT-4-1-arcade-james.gbetchedji
** File description:
** SFMLDisplay
*/
#ifndef SFMLDISPLAY_HPP_
#define SFMLDISPLAY_HPP_
#include "IDisplayModule.hpp"
#include <SFML/Graphics.hpp>
#include <SFML/Window.hpp>
#include <SFML/System.hpp>
#include <map>
namespace arcade {
class SFMLDisplay : public IDisplayModule {
public:
SFMLDisplay();
~SFMLDisplay() override;
void init() override;
void stop() override;
void clear() override;
void render() override;
void present() override;
bool isKeyPressed(const std::string &key) override;
std::string getName() const override;
void handleInput() override;
bool shouldQuit() const override;
void drawRect(int x, int y, int width, int height, int r, int g, int b, int a) override;
void drawText(const std::string& text, int x, int y, int r, int g, int b, int a) override;
void drawCircle(int x, int y, int radius, int r, int g, int b, int a) override;
virtual void drawCircle(int x, int y, int radius, int r, int g, int b, int a) = 0;
virtual std::string getTextInput(const std::string& prompt, const std::string& initialText = "") = 0;
private:
sf::RenderWindow* _window;
sf::Font _font;
std::map<std::string, sf::Keyboard::Key> _keyMap;
bool _quit;
};
}
#endif /* !SFMLDISPLAY_HPP_ */
/*
** EPITECH PROJECT, 2025
** B-OOP-400-COT-4-1-arcade-james.gbetchedji
** File description:
** SFMLDisplay
*/
#include "../includes/Display/SFMLDisplay.hpp"
using namespace arcade;
namespace arcade {
SFMLDisplay::SFMLDisplay() : _window(nullptr), _quit(false) {
_keyMap["UP"] = sf::Keyboard::Up;
_keyMap["DOWN"] = sf::Keyboard::Down;
_keyMap["LEFT"] = sf::Keyboard::Left;
_keyMap["RIGHT"] = sf::Keyboard::Right;
_keyMap["ESCAPE"] = sf::Keyboard::Escape;
_keyMap["RETURN"] = sf::Keyboard::Enter;
_keyMap["SPACE"] = sf::Keyboard::Space;
_keyMap["R"] = sf::Keyboard::R;
_keyMap["N"] = sf::Keyboard::N;
_keyMap["Q"] = sf::Keyboard::Q;
_keyMap["E"] = sf::Keyboard::E;
_keyMap["M"] = sf::Keyboard::M;
_keyMap["F5"] = sf::Keyboard::F5;
_keyMap["F6"] = sf::Keyboard::F6;
_keyMap["P"] = sf::Keyboard::P;
_keyMap["Y"] = sf::Keyboard::Y;
}
// Autres méthodes de l'implémentation...
}
/*
** EPITECH PROJECT, 2025
** B-OOP-400-COT-4-1-arcade-james.gbetchedji [WSL: Ubuntu]
** File description:
** SFMLModule
*/
#include "../includes/Display/SFMLDisplay.hpp"
extern "C" {
arcade::IDisplayModule *createDisplay()
{
return new arcade::SFMLDisplay();
}
void destroyDisplay(arcade::IDisplayModule *display)
{
delete display;
}
}
Créer une nouvelle bibliothèque graphique
Voici les étapes à suivre pour créer une nouvelle bibliothèque graphique compatible avec ARCADE :
- Créer une classe qui implémente IDisplayModule
Créez une classe qui hérite de l'interface IDisplayModule et implémentez toutes ses méthodes virtuelles.
- Implémenter les fonctions d'exportation
Définissez les fonctions externes createDisplay et destroyDisplay qui seront utilisées par le chargeur de bibliothèques dynamiques.
extern "C" {
arcade::IDisplayModule *createDisplay()
{
return new YourDisplayModule();
}
void destroyDisplay(arcade::IDisplayModule *display)
{
delete display;
}
}
- Compiler la bibliothèque partagée
Compilez votre code en une bibliothèque partagée (.so) selon la convention de nommage arcade_<nom_lib>.so et placez-la dans le répertoire ./lib/.
g++ -shared -fPIC -o lib/arcade_mylib.so MyDisplay.cpp MyModule.cpp -lmygraphlib
Conseils d'implémentation
Gestion des touches
Utilisez une map pour faire correspondre les noms de touches standardisés aux constantes spécifiques de votre bibliothèque graphique.
Gestion des ressources
Assurez-vous de bien initialiser et libérer les ressources dans les méthodes init() et stop().
Compatibilité
N'oubliez pas que votre bibliothèque doit être interchangeable avec les autres. Assurez-vous que les coordonnées et dimensions sont cohérentes.
Tests
Testez votre bibliothèque avec différents jeux pour vous assurer de sa compatibilité et de son bon fonctionnement.
Bibliothèques graphiques supportées
ARCADE supporte actuellement les bibliothèques graphiques suivantes :
nCurses
Interface en mode texte pour terminal.
SDL2
Simple DirectMedia Layer, bibliothèque multimédia cross-platform.
SFML
Simple and Fast Multimedia Library, bibliothèque orientée objet pour le développement de jeux.
Votre bibliothèque ?
Suivez ce guide pour ajouter votre propre bibliothèque graphique au projet !