diff --git a/Makefile b/Makefile index 140eca7..b358db2 100644 --- a/Makefile +++ b/Makefile @@ -2,12 +2,12 @@ # Variables de compilation CC = gcc -CFLAGS = -Wall -Wextra -std=c89 +CFLAGS = -Wall -Wextra -std=c89 LDFLAGS = -lgraph TARGET = taquin -# Liste de tous les fichiers sources (.c) -SRCS = src/main.c src/menu_view.c src/game_logic.c src/images.c src/utils.c +# Liste de tous les fichiers sources (.c) - INCLUT game_view.c +SRCS = src/main.c src/menu_view.c src/game_logic.c src/images.c src/utils.c src/game_view.c # Liste de tous les fichiers objets (.o) correspondants OBJS = $(patsubst src/%.c, obj/%.o, $(SRCS)) @@ -21,20 +21,22 @@ all: dir $(TARGET) # Crée le dossier obj/ si non existant dir: - @mkdir -p obj + @mkdir -p obj # Règle de liaison : crée l'exécutable taquin à partir de tous les objets $(TARGET): $(OBJS) - $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) + $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) # Règle générique pour la compilation de tous les .c en .o obj/%.o: src/%.c - $(CC) $(CFLAGS) -c $< -o $@ + $(CC) $(CFLAGS) -c $< -o $@ # Exécute le programme run: $(TARGET) - ./$(TARGET) + ./$(TARGET) # Nettoyage clean: - @rm -rf obj $(TARGET) + @rm -rf obj $(TARGET) + +.PHONY : all clean run diff --git a/obj/main.o b/obj/main.o index 945b9cb..9e8a3b2 100644 Binary files a/obj/main.o and b/obj/main.o differ diff --git a/src/game_view.c b/src/game_view.c new file mode 100644 index 0000000..d40b349 --- /dev/null +++ b/src/game_view.c @@ -0,0 +1,141 @@ +#include "game_view.h" +#include +#include +#include + +#define WINDOW_WIDTH 800 +#define WINDOW_HEIGHT 600 + +extern int _X; +extern int _Y; +#define MARGIN 50 /* Marge autour du plateau */ + + +/* Fonction utilitaire : vérifie si un clic est sur une tuile donnée */ +static int is_in_tile_rect(int x_click, int y_click, int tile_x, int tile_y, int tile_w, int tile_h) +{ + return (x_click >= tile_x && x_click <= tile_x + tile_w && + y_click >= tile_y && y_click <= tile_y + tile_h); +} + + +/* Dessine le plateau de jeu */ +void game_render(const game_state_t *state) +{ + int i, r, c; + couleur C_FOND = CouleurParNom("gray"); + couleur C_BORDURE = CouleurParNom("black"); + + EffacerEcran(C_FOND); + + /* Calcul de la taille de chaque tuile pour l'affichage (utilise la taille de la première tuile) */ + int tile_display_w = state->all_tiles[0]->width; + int tile_display_h = state->all_tiles[0]->height; + + + ChoisirCouleurDessin(C_BORDURE); + + /* Boucle sur toutes les cases du plateau */ + for (i = 0; i < state->rows * state->cols; i++) { + int tile_id = state->permutation[i]; + int x_pos, y_pos; + + r = i / state->cols; + c = i % state->cols; + + /* Position d'affichage sur l'écran */ + x_pos = MARGIN + c * tile_display_w; + y_pos = MARGIN + r * tile_display_h; + + if (tile_id != -1) { /* Ne dessine pas si c'est la case vide */ + tile_t *current_tile = state->all_tiles[tile_id]; + + /* ChargerImage(fichier, x_dst, y_dst, x_src, y_src, l, h) */ + ChargerImage(current_tile->path, + x_pos, y_pos, + current_tile->src_x, current_tile->src_y, + tile_display_w, tile_display_h); + + /* Dessine une fine bordure autour de la tuile */ + DessinerRectangle(x_pos, y_pos, tile_display_w, tile_display_h); + + } else { + /* Dessine la case vide en jaune (ou couleur distincte) */ + ChoisirCouleurDessin(CouleurParNom("yellow")); + RemplirRectangle(x_pos, y_pos, tile_display_w, tile_display_h); + ChoisirCouleurDessin(C_BORDURE); + DessinerRectangle(x_pos, y_pos, tile_display_w, tile_display_h); + } + } + + /* Affichage du compteur de coups */ + char buffer[100]; + sprintf(buffer, "Coups: %lu", state->moves); + EcrireTexte(MARGIN, WINDOW_HEIGHT - 30, buffer, 1); + + /* Affichage de la victoire si résolu */ + if (state->is_solved) { + /* TODO: Afficher un grand BRAVO */ + } +} + + +/* Gère les entrées (clic/clavier) et la boucle principale du jeu */ +void game_loop(game_state_t *state) +{ + unsigned long next_update = Microsecondes() + 50000L; + int go_on = 1; + + while (go_on && !state->is_solved) + { + /* Rendu et rafraîchissement */ + if (Microsecondes() > next_update) + { + game_render(state); + CopierZone(0, 0, 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT, 0, 0); + next_update = Microsecondes() + 50000L; + } + + /* Gestion des événements Souris */ + if (SourisCliquee()) + { + int i; + int x_click = _X; + int y_click = _Y; + int tile_w = state->all_tiles[0]->width; + int tile_h = state->all_tiles[0]->height; + + /* Parcourir toutes les tuiles pour voir laquelle a été cliquée */ + for (i = 0; i < state->rows * state->cols; i++) { + int r = i / state->cols; + int c = i % state->cols; + + int x_pos = MARGIN + c * tile_w; + int y_pos = MARGIN + r * tile_h; + + if (is_in_tile_rect(x_click, y_click, x_pos, y_pos, tile_w, tile_h)) { + /* Tenter de déplacer la tuile cliquée */ + game_move_tile(state, i); + break; + } + } + } + + /* Gestion des événements Clavier */ + if (ToucheEnAttente()) { + int key = Touche(); + if (key == XK_Escape) { + go_on = 0; /* Quitter la boucle de jeu */ + } + /* TODO: Ajouter les flèches pour les déplacements clavier */ + } + } + + /* Si la boucle est terminée par la victoire, on affiche le BRAVO */ + if (state->is_solved) { + game_render(state); /* Dernière mise à jour pour montrer l'image complète */ + CopierZone(0, 0, 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT, 0, 0); + printf("BRAVO ! Partie terminee en %lu coups.\n", state->moves); + Touche(); /* Attend une touche avant de nettoyer */ + } +} \ No newline at end of file diff --git a/src/game_view.h b/src/game_view.h new file mode 100644 index 0000000..e3e4015 --- /dev/null +++ b/src/game_view.h @@ -0,0 +1,12 @@ +#ifndef GAME_VIEW_H +#define GAME_VIEW_H + +#include "game_logic.h" /* Nécessaire pour connaître la structure game_state_t */ + +/* Dessine le plateau de jeu, les tuiles à leur position actuelle, et le compteur de coups. */ +void game_render(const game_state_t *state); + +/* Gère la boucle principale du jeu, les événements (clics/clavier) et les rafraîchissements. */ +void game_loop(game_state_t *state); + +#endif /* GAME_VIEW_H */ \ No newline at end of file diff --git a/src/main.c b/src/main.c index bb57b5c..bd2428a 100644 --- a/src/main.c +++ b/src/main.c @@ -2,6 +2,7 @@ * Point d'entrée du programme Taquin. * Gère la boucle principale des événements et la transition de vue (Menu -> Jeu). */ +#include "game_view.h" #include "menu_view.h" #include "game_logic.h" /* Nouveau: pour initialiser le jeu */ @@ -76,6 +77,7 @@ int main(void) game_state.rows, game_state.cols); /* TODO: Boucle de JEU (GRANDE PARTIE 3) */ + game_loop(&game_state); /* 3.2. Nettoyage après la fin de la partie */ images_free_tiles(tiles, num_tiles); diff --git a/taquin b/taquin deleted file mode 100755 index dbd973c..0000000 Binary files a/taquin and /dev/null differ