Fin v3
|
Before Width: | Height: | Size: 426 KiB |
|
After Width: | Height: | Size: 871 KiB |
|
After Width: | Height: | Size: 48 KiB |
|
After Width: | Height: | Size: 254 KiB |
|
After Width: | Height: | Size: 78 KiB |
|
After Width: | Height: | Size: 326 KiB |
|
After Width: | Height: | Size: 44 KiB |
|
After Width: | Height: | Size: 150 KiB |
|
Before Width: | Height: | Size: 161 KiB After Width: | Height: | Size: 150 KiB |
|
After Width: | Height: | Size: 558 KiB |
|
After Width: | Height: | Size: 47 KiB |
@@ -1,5 +1,6 @@
|
|||||||
/* src/game_view.c
|
/* src/game_view.c
|
||||||
* Implémentation du rendu graphique du plateau et de la boucle d'interaction.
|
* Implémentation du rendu graphique du plateau et de la boucle d'interaction.
|
||||||
|
* FIX CRITIQUE: La logique clavier est maintenant implémentée en interne (solution de fusion).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "game_view.h"
|
#include "game_view.h"
|
||||||
@@ -11,7 +12,6 @@ extern int _X;
|
|||||||
extern int _Y;
|
extern int _Y;
|
||||||
#define MARGIN 50 /* Marge autour du plateau */
|
#define MARGIN 50 /* Marge autour du plateau */
|
||||||
|
|
||||||
|
|
||||||
/* --- Fonctions Utilitaires Privées --- */
|
/* --- Fonctions Utilitaires Privées --- */
|
||||||
|
|
||||||
/* Vérifie si un clic est sur une zone rectangulaire donnée */
|
/* Vérifie si un clic est sur une zone rectangulaire donnée */
|
||||||
@@ -21,6 +21,35 @@ static int is_in_tile_rect(int x_click, int y_click, int tile_x, int tile_y, int
|
|||||||
y_click >= tile_y && y_click <= tile_y + tile_h);
|
y_click >= tile_y && y_click <= tile_y + tile_h);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* * CRITICAL FIX: Logique du déplacement clavier (Implémentation interne pour résoudre la liaison).
|
||||||
|
* C'est cette fonction qui était mal liée.
|
||||||
|
*/
|
||||||
|
static int get_tile_to_move_internal(const game_state_t *state, int key)
|
||||||
|
{
|
||||||
|
int empty_r = state->empty_index / state->cols;
|
||||||
|
int empty_c = state->empty_index % state->cols;
|
||||||
|
int target_r = empty_r;
|
||||||
|
int target_c = empty_c;
|
||||||
|
|
||||||
|
if (key == XK_Up) {
|
||||||
|
target_r = empty_r + 1; /* Tuile en BAS monte */
|
||||||
|
} else if (key == XK_Down) {
|
||||||
|
target_r = empty_r - 1; /* Tuile en HAUT descend */
|
||||||
|
} else if (key == XK_Left) {
|
||||||
|
target_c = empty_c + 1; /* Tuile à DROITE va à gauche */
|
||||||
|
} else if (key == XK_Right) {
|
||||||
|
target_c = empty_c - 1; /* Tuile à GAUCHE va à droite */
|
||||||
|
} else {
|
||||||
|
return -1; /* Touche non supportée */
|
||||||
|
}
|
||||||
|
|
||||||
|
if (target_r >= 0 && target_r < state->rows && target_c >= 0 && target_c < state->cols) {
|
||||||
|
return target_r * state->cols + target_c;
|
||||||
|
}
|
||||||
|
return -1; /* Hors bordure */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* --- Fonctions de Rendu et de Logique --- */
|
/* --- Fonctions de Rendu et de Logique --- */
|
||||||
|
|
||||||
/* Dessine le plateau de jeu */
|
/* Dessine le plateau de jeu */
|
||||||
@@ -36,6 +65,9 @@ void game_render(const game_state_t *state)
|
|||||||
int tile_display_w = state->all_tiles[0]->width;
|
int tile_display_w = state->all_tiles[0]->width;
|
||||||
int tile_display_h = state->all_tiles[0]->height;
|
int tile_display_h = state->all_tiles[0]->height;
|
||||||
|
|
||||||
|
/* Calcul des dimensions du plateau */
|
||||||
|
int board_width = state->cols * tile_display_w;
|
||||||
|
|
||||||
ChoisirCouleurDessin(C_BORDURE);
|
ChoisirCouleurDessin(C_BORDURE);
|
||||||
|
|
||||||
/* 1. Affichage du Plateau (Tuiles et Case Vide) */
|
/* 1. Affichage du Plateau (Tuiles et Case Vide) */
|
||||||
@@ -95,11 +127,14 @@ void game_render(const game_state_t *state)
|
|||||||
EcrireTexte(MARGIN, WINDOW_HEIGHT - 30, buffer, 1);
|
EcrireTexte(MARGIN, WINDOW_HEIGHT - 30, buffer, 1);
|
||||||
|
|
||||||
/* 4. Bouton Retour Menu */
|
/* 4. Bouton Retour Menu */
|
||||||
|
int btn_w = 150;
|
||||||
|
int btn_h = 40;
|
||||||
|
|
||||||
int btn_x = WINDOW_WIDTH - 200;
|
int btn_x = WINDOW_WIDTH - 200;
|
||||||
int btn_y = WINDOW_HEIGHT - 60;
|
int btn_y = WINDOW_HEIGHT - 60;
|
||||||
|
|
||||||
ChoisirCouleurDessin(CouleurParNom("orange"));
|
ChoisirCouleurDessin(CouleurParNom("orange"));
|
||||||
RemplirRectangle(btn_x, btn_y, 150, 40);
|
RemplirRectangle(btn_x, btn_y, btn_w, btn_h);
|
||||||
ChoisirCouleurDessin(CouleurParNom("black"));
|
ChoisirCouleurDessin(CouleurParNom("black"));
|
||||||
EcrireTexte(btn_x + 10, btn_y + 25, "MENU (R)", 1);
|
EcrireTexte(btn_x + 10, btn_y + 25, "MENU (R)", 1);
|
||||||
|
|
||||||
@@ -138,7 +173,7 @@ void game_loop(game_state_t *state)
|
|||||||
|
|
||||||
/* Vérifier le bouton RETOUR MENU */
|
/* Vérifier le bouton RETOUR MENU */
|
||||||
if (is_in_tile_rect(x_click, y_click, WINDOW_WIDTH - 200, WINDOW_HEIGHT - 60, 150, 40)) {
|
if (is_in_tile_rect(x_click, y_click, WINDOW_WIDTH - 200, WINDOW_HEIGHT - 60, 150, 40)) {
|
||||||
go_on = 0; /* Quitte la boucle de jeu pour revenir au menu */
|
go_on = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -161,37 +196,21 @@ void game_loop(game_state_t *state)
|
|||||||
/* Gestion des événements Clavier */
|
/* Gestion des événements Clavier */
|
||||||
if (ToucheEnAttente()) {
|
if (ToucheEnAttente()) {
|
||||||
int key = Touche();
|
int key = Touche();
|
||||||
|
int target_index;
|
||||||
int target_index = -1;
|
|
||||||
int empty_r = state->empty_index / state->cols;
|
|
||||||
int empty_c = state->empty_index % state->cols;
|
|
||||||
|
|
||||||
if (key == XK_Escape) {
|
if (key == XK_Escape) {
|
||||||
exit(EXIT_SUCCESS); /* Quitte l'application entièrement si ESC */
|
exit(EXIT_SUCCESS);
|
||||||
}
|
}
|
||||||
/* Touche 'R' pour revenir au menu (Nouvelle Partie) */
|
/* Touche 'R' pour revenir au menu (Nouvelle Partie) */
|
||||||
else if (key == 'r' || key == 'R') {
|
else if (key == 'r' || key == 'R') {
|
||||||
go_on = 0;
|
go_on = 0;
|
||||||
}
|
}
|
||||||
/* Logique de déplacement Clavier (corrigée) */
|
/* Logique de déplacement Clavier simplifiée via la fonction interne */
|
||||||
else if (key == XK_Up) {
|
else {
|
||||||
/* HAUT : Déplace la tuile en BAS (r + 1) vers le vide (r) */
|
target_index = get_tile_to_move_internal(state, key);
|
||||||
target_index = (empty_r + 1) * state->cols + empty_c;
|
if (target_index != -1) {
|
||||||
} else if (key == XK_Down) {
|
game_move_tile(state, target_index);
|
||||||
/* BAS : Déplace la tuile en HAUT (r - 1) vers le vide (r) */
|
}
|
||||||
target_index = (empty_r - 1) * state->cols + empty_c;
|
|
||||||
}
|
|
||||||
else if (key == XK_Left) {
|
|
||||||
/* GAUCHE : Déplace la tuile à DROITE (c + 1) vers le vide (c) */
|
|
||||||
target_index = empty_r * state->cols + (empty_c + 1);
|
|
||||||
} else if (key == XK_Right) {
|
|
||||||
/* DROITE : Déplace la tuile à GAUCHE (c - 1) vers le vide (c) */
|
|
||||||
target_index = empty_r * state->cols + (empty_c - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Tenter le mouvement s'il y a une cible */
|
|
||||||
if (target_index != -1) {
|
|
||||||
game_move_tile(state, target_index);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,10 +8,17 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
/* Tableau statique des chemins d'images disponibles (synchronisé avec l'ordre du menu) */
|
/* Tableau statique des chemins d'images disponibles (synchronisé avec l'ordre du menu) */
|
||||||
static const char *IMAGE_PATHS[] = {
|
static const char *IMAGE_PATHS_FULL[] = {
|
||||||
"assets/spiderman.jpg", /* Index 0 */
|
"assets/spiderman.png", /* Index 0 */
|
||||||
"assets/capy.jpg", /* Index 1 */
|
"assets/capy.png", /* Index 1 */
|
||||||
"assets/iut.jpg" /* Index 2 */
|
"assets/iut.png" /* Index 2 */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Tableau statique des chemins des images OPTIMISÉES (pour l'APERÇU MENU) */
|
||||||
|
static const char *IMAGE_PATHS_PREVIEW[] = {
|
||||||
|
"assets/spiderman_small.png",
|
||||||
|
"assets/capy_small.png",
|
||||||
|
"assets/iut_small.png"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -22,27 +29,35 @@ image_source_t get_image_source(int selected_index)
|
|||||||
|
|
||||||
/* 1. Définition du chemin selon l'index */
|
/* 1. Définition du chemin selon l'index */
|
||||||
if (selected_index >= 0 && selected_index < 3) {
|
if (selected_index >= 0 && selected_index < 3) {
|
||||||
strcpy(src.path, IMAGE_PATHS[selected_index]);
|
strcpy(src.path, IMAGE_PATHS_FULL[selected_index]);
|
||||||
} else {
|
} else {
|
||||||
strcpy(src.path, IMAGE_PATHS[0]); /* Fallback */
|
strcpy(src.path, IMAGE_PATHS_FULL[0]); /* Fallback */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 2. DÉFINITION DES TAILLES RÉELLES (Utilisation des données 'identify') */
|
/* 2. DÉFINITION DES TAILLES RÉELLES (Utilisation des données 'identify') */
|
||||||
if (selected_index == 0) {
|
if (selected_index == 0) {
|
||||||
/* Spiderman (720x720) */
|
/* Spiderman (720x720) */
|
||||||
src.width = 720;
|
src.width = 720;
|
||||||
src.height = 720;
|
src.height = 560;
|
||||||
} else if (selected_index == 1) {
|
} else if (selected_index == 1) {
|
||||||
/* Capybara (1000x662) */
|
/* Capybara (1000x662) */
|
||||||
src.width = 1000;
|
src.width = 720;
|
||||||
src.height = 662;
|
src.height = 560;
|
||||||
} else { /* Index 2 */
|
} else { /* Index 2 */
|
||||||
/* IUT (1200x800) */
|
/* IUT (1200x800) */
|
||||||
src.width = 1200;
|
src.width = 720;
|
||||||
src.height = 800;
|
src.height = 560;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* 3. Définition du chemin pour l'APERÇU (Utilisé par menu_view.c) */
|
||||||
|
if (selected_index >= 0 && selected_index < 3) {
|
||||||
|
strcpy(src.preview_path, IMAGE_PATHS_PREVIEW[selected_index]);
|
||||||
|
} else {
|
||||||
|
strcpy(src.preview_path, IMAGE_PATHS_PREVIEW[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 3. ASSURER LA DIVISIBILITÉ PAR 8 (Ajustement pour le découpage propre) */
|
/* 4. ASSURER LA DIVISIBILITÉ PAR 8 (Ajustement pour le découpage propre) */
|
||||||
/* On retire le reste de la division (modulo 8) pour éviter les erreurs de bordure. */
|
/* On retire le reste de la division (modulo 8) pour éviter les erreurs de bordure. */
|
||||||
src.width = src.width - (src.width % 8);
|
src.width = src.width - (src.width % 8);
|
||||||
src.height = src.height - (src.height % 8);
|
src.height = src.height - (src.height % 8);
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ typedef struct {
|
|||||||
int width;
|
int width;
|
||||||
int height;
|
int height;
|
||||||
char path[30];
|
char path[30];
|
||||||
|
char preview_path[30];
|
||||||
} image_source_t;
|
} image_source_t;
|
||||||
|
|
||||||
/* Prototypes */
|
/* Prototypes */
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
#include "menu_view.h"
|
#include "menu_view.h"
|
||||||
#include "defs.h"
|
#include "defs.h"
|
||||||
|
#include "images.h"
|
||||||
#include <graph.h>
|
#include <graph.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@@ -48,9 +49,9 @@ void menu_render(const menu_state_t *state)
|
|||||||
couleur C_TEXTE = CouleurParNom("black");
|
couleur C_TEXTE = CouleurParNom("black");
|
||||||
couleur C_BOUTON = CouleurParNom("dark gray");
|
couleur C_BOUTON = CouleurParNom("dark gray");
|
||||||
couleur C_START = CouleurParNom("green");
|
couleur C_START = CouleurParNom("green");
|
||||||
char buffer[50];
|
char buffer[50];
|
||||||
|
|
||||||
char path_buffer[30];
|
char path_buffer[30];
|
||||||
|
image_source_t current_src;
|
||||||
|
|
||||||
EffacerEcran(C_FOND);
|
EffacerEcran(C_FOND);
|
||||||
ChoisirCouleurDessin(C_TEXTE);
|
ChoisirCouleurDessin(C_TEXTE);
|
||||||
@@ -64,14 +65,18 @@ void menu_render(const menu_state_t *state)
|
|||||||
int x = IMG_START_X + i * IMG_SPACING;
|
int x = IMG_START_X + i * IMG_SPACING;
|
||||||
int y = IMG_START_Y;
|
int y = IMG_START_Y;
|
||||||
|
|
||||||
/* Définition du chemin */
|
/* Définition du chemin
|
||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
strcpy(path_buffer, "assets/spiderman.jpg");
|
strcpy(path_buffer, "assets/spiderman_small.png");
|
||||||
} else if (i == 1) {
|
} else if (i == 1) {
|
||||||
strcpy(path_buffer, "assets/capy.jpg");
|
strcpy(path_buffer, "assets/capy_small.png");
|
||||||
} else {
|
} else {
|
||||||
strcpy(path_buffer, "assets/iut.jpg");
|
strcpy(path_buffer, "assets/iut_small.png");
|
||||||
}
|
}*/
|
||||||
|
|
||||||
|
/* OBTENIR LE CHEMIN OPTIMISÉ */
|
||||||
|
current_src = get_image_source(i);
|
||||||
|
strcpy(path_buffer, current_src.preview_path);
|
||||||
|
|
||||||
/* Affiche l'image */
|
/* Affiche l'image */
|
||||||
ChargerImage(path_buffer,
|
ChargerImage(path_buffer,
|
||||||
|
|||||||