GraphicalDisplay.cpp h - JulianKerignard/ProjetJeuDeLaVie_POO GitHub Wiki
#ifndef GRAPHICALDISPLAY_H
#define GRAPHICALDISPLAY_H
#include <SFML/Graphics.hpp>
#include "Grid.h"
#include "Cell.h"
#include "DisplayManager.h"
class GraphicalDisplay : public DisplayManager {
public:
// Constructeur avec initialisation des composants
GraphicalDisplay(int windowWidth = 800, int windowHeight = 600);
// Initialisation de l'affichage graphique
void initialize() override;
// Mise à jour de l'affichage graphique
void update(const Grid& grid) override;
// Gestion des événements utilisateur
void handleEvents();
// Fermeture de la fenêtre graphique
void close() override;
// Vérifie si la fenêtre est ouverte
bool isWindowOpen() const;
// Définir la grille à afficher
void setGrid(Grid* grid) { this->grid = grid; }
// Obtenir la vitesse d'itération actuelle
float getIterationSpeed() const { return iterationSpeed; }
// Définir la vitesse d'itération
void setIterationSpeed(float speed) { iterationSpeed = speed; }
// Mettre en pause ou reprendre le jeu
void togglePause() { paused = !paused; }
// Vérifie si le jeu est en pause
bool isPaused() const { return paused; }
// Définir le nombre d'itérations maximum
void setMaxIterations(int maxIterations) { this->maxIterations = maxIterations; }
// Définir le compteur d'itérations actuel
void setIterationCount(int currentIteration) { this->currentIteration = currentIteration; }
private:
sf::RenderWindow window; // Fenêtre de rendu SFML
sf::RenderTexture buffer; // Texture de rendu pour le double buffering
sf::RectangleShape cellShape; // Forme rectangulaire pour dessiner les cellules
sf::Font font; // Police pour le texte
sf::Text helpText; // Texte d'aide
sf::Text fpsText; // Texte pour l'affichage des FPS
sf::Clock fpsClock; // Horloge pour calculer les FPS
float cellSize; // Taille des cellules
bool isDrawing; // Indique si le dessin est en cours
Grid* grid; // Pointeur vers la grille à afficher
float lastFPS; // Dernière valeur des FPS
float iterationSpeed; // Vitesse d'itération en millisecondes
bool paused; // Indique si le jeu est en pause
int currentIteration; // Compteur d'itérations actuel
int maxIterations; // Nombre maximum d'itérations
// Vérifie si une cellule est visible dans la fenêtre
bool isCellVisible(float x, float y, float windowWidth, float windowHeight) const;
// Dessine une cellule à une position spécifiée
void drawCell(float x, float y, float size, sf::Color color, bool drawOutline = false);
// Met à jour l'affichage des FPS
void updateFPS();
// Dessine l'interface utilisateur
void drawInterface(const Grid& grid);
};
#endif // GRAPHICALDISPLAY_H
-
GraphicalDisplay(int windowWidth, int windowHeight) :
- Initialise les composants de la fenêtre SFML, configure les paramètres de la fenêtre, et charge la police utilisée pour afficher le texte.
GraphicalDisplay::GraphicalDisplay(int windowWidth, int windowHeight)
: window(sf::VideoMode(windowWidth, windowHeight), "Game of Life"),
cellSize(10.0f),
isDrawing(false),
grid(nullptr),
lastFPS(0.0f),
iterationSpeed(100.0f),
paused(false),
currentIteration(0),
maxIterations(0) {
window.setVerticalSyncEnabled(true);
window.setFramerateLimit(60);
buffer.create(windowWidth, windowHeight);
cellShape.setSize(sf::Vector2f(cellSize - 1, cellSize - 1));
if (!font.loadFromFile("arial.ttf")) {
std::cout << "Erreur de chargement de la police" << std::endl;
}
helpText.setFont(font);
helpText.setCharacterSize(14);
helpText.setFillColor(sf::Color::White);
helpText.setPosition(10, 10);
fpsText.setFont(font);
fpsText.setCharacterSize(14);
fpsText.setFillColor(sf::Color::Yellow);
fpsText.setPosition(10, window.getSize().y - 20);
}
-
void initialize() :
- Affiche un message d'initialisation et la vitesse initiale d'itération.
void GraphicalDisplay::initialize() {
std::cout << "Initialisation de l'affichage graphique" << std::endl;
std::cout << "Vitesse initiale : " << iterationSpeed << "ms" << std::endl;
}
-
bool isCellVisible(float x, float y, float windowWidth, float windowHeight) const :
- Vérifie si une cellule est visible dans la fenêtre graphique en fonction de ses coordonnées.
bool GraphicalDisplay::isCellVisible(float x, float y, float windowWidth, float windowHeight) const {
return x >= -cellSize && x <= windowWidth && y >= -cellSize && y <= windowHeight;
}
-
void drawCell(float x, float y, float size, sf::Color color, bool drawOutline) :
- Dessine une cellule à une position spécifiée avec une certaine taille et couleur.
void GraphicalDisplay::drawCell(float x, float y, float size, sf::Color color, bool drawOutline) {
cellShape.setPosition(x, y);
cellShape.setSize(sf::Vector2f(size - 1, size - 1));
cellShape.setFillColor(color);
buffer.draw(cellShape);
}
-
void updateFPS() :
- Met à jour l'affichage des FPS (frames per second).
void GraphicalDisplay::updateFPS() {
float currentTime = fpsClock.restart().asSeconds();
lastFPS = 1.f / currentTime;
std::stringstream fpsStr;
fpsStr << "FPS: " << static_cast<int>(lastFPS);
fpsText.setString(fpsStr.str());
}
-
void drawInterface(const Grid& grid) :
- Dessine l'interface utilisateur incluant les commandes et les informations de jeu (mode torique, vitesse d'itération, etc.).
void GraphicalDisplay::drawInterface(const Grid& grid) {
std::stringstream controls;
controls << "Controles:\n"
<< "T: Mode torique " << (grid.getToroidal() ? "(ON)" : "(OFF)") << "\n"
<< "G: Placer un Glider\n"
<< "O: Placer un obstacle\n"
<< "Espace: " << (paused ? "PAUSE" : "EN COURS") << "\n"
<< "Clic gauche: Activer/Desactiver une cellule\n"
<< "PageUp/PageDown: Vitesse [" << iterationSpeed << "ms]\n"
<< "Echap: Quitter\n"
<< "Taille: " << grid.getWidth() << "x" << grid.getHeight() << "\n"
<< "Itération: " << currentIteration << "/"
<< (maxIterations > 0 ? std::to_string(maxIterations) : "∞") << "\n";
helpText.setString(controls.str());
buffer.draw(helpText);
buffer.draw(fpsText);
}
-
void update(const Grid& grid) :
- Met à jour l'affichage graphique, dessine les cellules et l'interface, et gère les événements utilisateur.
- void update(const Grid& grid) :
void GraphicalDisplay::update(const Grid& grid) {
handleEvents();
updateFPS();
if (window.isOpen()) {
buffer.clear(DEAD_COLOR);
float gridWidth = static_cast<float>(window.getSize().x);
float gridHeight = static_cast<float>(window.getSize().y);
cellSize = std::min(gridWidth / grid.getWidth(), gridHeight / grid.getHeight());
float offsetX = (gridWidth - (cellSize * grid.getWidth())) / 2;
float offsetY = (gridHeight - (cellSize * grid.getHeight())) / 2;
int startX = std::max(0, static_cast<int>(-offsetX / cellSize));
int startY = std::max(0, static_cast<int>(-offsetY / cellSize));
int endX = std::min(grid.getWidth(), static_cast<int>((gridWidth - offsetX) / cellSize) + 1);
int endY = std::min(grid.getHeight(), static_cast<int>((gridHeight - offsetY) / cellSize) + 1);
for (int y = startY; y < endY; y++) {
for (int x = startX; x < endX; x++) {
float posX = offsetX + x * cellSize;
float posY = offsetY + y * cellSize;
if (isCellVisible(posX, posY, gridWidth, gridHeight)) {
const Cell& cell = grid.getCellAt(x, y);
if (cell.isObstacleCell()) {
drawCell(posX, posY, cellSize, OBSTACLE_COLOR);
} else if (cell.getCurrentState() == CellState::ALIVE) {
drawCell(posX, posY, cellSize, ALIVE_COLOR);
} else {
drawCell(posX, posY, cellSize, DEAD_COLOR, true);
}
}
}
}
drawInterface(grid);
buffer.display();
sf::Sprite sprite(buffer.getTexture());
window.clear();
window.draw(sprite);
window.display();
}
}
-
void handleEvents() :
- Gère les événements utilisateur, tels que les clics de souris et les pressions de touches, pour interagir avec le jeu (mettre en pause, ajuster la vitesse, etc.).
void GraphicalDisplay::handleEvents() {
sf::Event event;
while (window.pollEvent(event)) {
switch (event.type) {
case sf::Event::Closed:
window.close();
break;
case sf::Event::KeyPressed:
switch (event.key.code) {
case sf::Keyboard::Escape:
window.close();
break;
case sf::Keyboard::Space:
paused = !paused;
std::cout << (paused ? "Jeu en pause" : "Jeu repris") << std::endl;
break;
case sf::Keyboard::T:
if (grid) {
grid->setToroidal(!grid->getToroidal());
std::cout << "Mode torique : " << (grid->getToroidal() ? "activé" : "désactivé") << std::endl;
}
break;
case sf::Keyboard::PageUp:
iterationSpeed = std::max(50.0f, iterationSpeed - 50.0f);
std::cout << "Vitesse d'itération : " << iterationSpeed << "ms" << std::endl;
break;
case sf::Keyboard::PageDown:
iterationSpeed = std::min(1000.0f, iterationSpeed + 50.0f);
std::cout << "Vitesse d'itération : " << iterationSpeed << "ms" << std::endl;
break;
case sf::Keyboard::G:
if (grid) {
sf::Vector2i mousePos = sf::Mouse::getPosition(window);
int gridX = mousePos.x / cellSize;
int gridY = mousePos.y / cellSize;
if (gridX >= 0 && gridX < grid->getWidth() && gridY >= 0 && gridY < grid->getHeight()) {
grid->addPattern(Pattern::GLIDER, gridX, gridY);
std::cout << "Glider ajouté en (" << gridX << "," << gridY << ")" << std::endl;
}
}
break;
case sf::Keyboard::O:
if (grid) {
sf::Vector2i mousePos = sf::Mouse::getPosition(window);
int gridX = mousePos.x / cellSize;
int gridY = mousePos.y / cellSize;
if (gridX >= 0 && gridX < grid->getWidth() && gridY >= 0 && gridY < grid->getHeight()) {
grid->addObstacle(gridX, gridY);
std::cout << "Obstacle ajouté en (" << gridX << "," << gridY << ")" << std::endl;
}
}
break;
}
break;
case sf::Event::MouseButtonPressed:
if (event.mouseButton.button == sf::Mouse::Left && grid) {
sf::Vector2i mousePos = sf::Mouse::getPosition(window);
int gridX = mousePos.x / cellSize;
int gridY = mousePos.y / cellSize;
if (gridX >= 0 && gridX < grid->getWidth() && gridY >= 0 && gridY < grid->getHeight()) {
const Cell& currentCell = grid->getCellAt(gridX, gridY);
CellState newState = (currentCell.getCurrentState() == CellState::ALIVE)
? CellState::DEAD
: CellState::ALIVE;
grid->setCellAt(gridX, gridY, newState);
std::cout << "Cellule " << (newState == CellState::ALIVE ? "activée" : "désactivée")
<< " en (" << gridX << "," << gridY << ")" << std::endl;
}
}
break;
}
}
}
-
void close() :
- Ferme la fenêtre graphique si elle est ouverte.
void GraphicalDisplay::close() {
if (window.isOpen()) {
window.close();
}
}
-
bool isWindowOpen() const :
- Vérifie si la fenêtre graphique est ouverte.
bool GraphicalDisplay::isWindowOpen() const {
return window.isOpen();
}
-
void setGrid(Grid grid)* :
- Définit la grille à afficher.
-
float getIterationSpeed() const :
- Retourne la vitesse d'itération actuelle.
-
void setIterationSpeed(float speed) :
- Définit la vitesse d'itération.
-
void togglePause() :
- Met en pause ou reprend le jeu.
-
bool isPaused() const :
- Vérifie si le jeu est en pause.
-
void setMaxIterations(int maxIterations) :
- Définit le nombre d'itérations maximum.
-
void setIterationCount(int currentIteration) :
- Définit le compteur d'itérations actuel.
Avec cette documentation détaillée, tu devrais avoir une bonne compréhension de la structure et des fonctionnalités de la classe GraphicalDisplay
dans les fichiers GraphicalDisplay.cpp
et GraphicalDisplay.h
. Si tu as besoin de plus d'explications ou d'exemples, fais-le moi savoir ! 🚀📚😊