#include "include/jeu.h" #include "include/fichiers.h" #include "include/constantes.h" //Carte dans le heap int carte[NB_BLOCS_LARGEUR][NB_BLOCS_HAUTEUR]; SDL_Surface* mario[4]; // 4 surfaces pour chacune des directions de mario SDL_Surface *mur,*caisse,*caisseOK,*objectif,*marioActuel; SDL_Rect position, positionJoueur; SDL_Event event; int objectifsRestants = 0, i = 0, j = 0; //Pour detruireBloc int lastDirection; void afficher(SDL_Surface* ecran) { // Effacement de l'écran SDL_FillRect(ecran, NULL, SDL_MapRGB(ecran->format, 255, 255, 255)); // Placement des objets à l'écran for (i = 0 ; i < NB_BLOCS_LARGEUR ; i++) { for (j = 0 ; j < NB_BLOCS_HAUTEUR ; j++) { position.x = i * TAILLE_BLOC; position.y = j * TAILLE_BLOC; switch(carte[i][j]) { case MUR: SDL_BlitSurface(mur, NULL, ecran, &position); break; case CAISSE: SDL_BlitSurface(caisse, NULL, ecran, &position); break; case CAISSE_OK: SDL_BlitSurface(caisseOK, NULL, ecran, &position); break; case OBJECTIF: SDL_BlitSurface(objectif, NULL, ecran, &position); objectifsRestants = 1; break; } } } // On place le joueur à la bonne position position.x = positionJoueur.x * TAILLE_BLOC; position.y = positionJoueur.y * TAILLE_BLOC; SDL_BlitSurface(marioActuel, NULL, ecran, &position); //Tout afficher SDL_Flip(ecran); } void detruireBloc(int direction) { switch(direction) { case HAUT: carte[positionJoueur.x][positionJoueur.y-1] = VIDE; break; case BAS: carte[positionJoueur.x][positionJoueur.y+1] = VIDE; break; case GAUCHE: carte[positionJoueur.x-1][positionJoueur.y] = VIDE; break; case DROITE: carte[positionJoueur.x+1][positionJoueur.y] = VIDE; break; } } void deplacerCaisse(int *premiereCase, int *secondeCase) { if (*premiereCase == CAISSE || *premiereCase == CAISSE_OK) { if (*secondeCase == OBJECTIF) *secondeCase = CAISSE_OK; else *secondeCase = CAISSE; if (*premiereCase == CAISSE_OK) *premiereCase = OBJECTIF; else *premiereCase = VIDE; } } void deplacerJoueur(int direction) { //Pour la fonction detruire lastDirection = direction; switch(direction) { case HAUT: if (positionJoueur.y - 1 < 0) // Si le joueur dépasse l'écran, on arrête break; if (carte[positionJoueur.x][positionJoueur.y - 1] == MUR) // S'il y a un mur, on arrête break; // Si on veut pousser une caisse, il faut vérifier qu'il n'y a pas de mur derrière (ou une autre caisse, ou la limite du monde) if ((carte[positionJoueur.x][positionJoueur.y - 1] == CAISSE || carte[positionJoueur.x][positionJoueur.y - 1] == CAISSE_OK) && (positionJoueur.y - 2 < 0 || carte[positionJoueur.x][positionJoueur.y - 2] == MUR || carte[positionJoueur.x][positionJoueur.y - 2] == CAISSE || carte[positionJoueur.x][positionJoueur.y - 2] == CAISSE_OK)) break; // Si on arrive là, c'est qu'on peut déplacer le joueur ! // On vérifie d'abord s'il y a une caisse à déplacer deplacerCaisse(&carte[positionJoueur.x][positionJoueur.y - 1], &carte[positionJoueur.x][positionJoueur.y - 2]); positionJoueur.y--; // On peut enfin faire monter le joueur (oufff !) break; case BAS: if (positionJoueur.y + 1 >= NB_BLOCS_HAUTEUR) break; if (carte[positionJoueur.x][positionJoueur.y + 1] == MUR) break; if ((carte[positionJoueur.x][positionJoueur.y + 1] == CAISSE || carte[positionJoueur.x][positionJoueur.y + 1] == CAISSE_OK) && (positionJoueur.y + 2 >= NB_BLOCS_HAUTEUR || carte[positionJoueur.x][positionJoueur.y + 2] == MUR || carte[positionJoueur.x][positionJoueur.y + 2] == CAISSE || carte[positionJoueur.x][positionJoueur.y + 2] == CAISSE_OK)) break; deplacerCaisse(&carte[positionJoueur.x][positionJoueur.y + 1], &carte[positionJoueur.x][positionJoueur.y + 2]); positionJoueur.y++; break; case GAUCHE: if (positionJoueur.x - 1 < 0) break; if (carte[positionJoueur.x - 1][positionJoueur.y] == MUR) break; if ((carte[positionJoueur.x - 1][positionJoueur.y] == CAISSE || carte[positionJoueur.x - 1][positionJoueur.y] == CAISSE_OK) && (positionJoueur.x - 2 < 0 || carte[positionJoueur.x - 2][positionJoueur.y] == MUR || carte[positionJoueur.x - 2][positionJoueur.y] == CAISSE || carte[positionJoueur.x - 2][positionJoueur.y] == CAISSE_OK)) break; deplacerCaisse(&carte[positionJoueur.x - 1][positionJoueur.y], &carte[positionJoueur.x - 2][positionJoueur.y]); positionJoueur.x--; break; case DROITE: if (positionJoueur.x + 1 >= NB_BLOCS_LARGEUR) break; if (carte[positionJoueur.x + 1][positionJoueur.y] == MUR) break; if ((carte[positionJoueur.x + 1][positionJoueur.y] == CAISSE || carte[positionJoueur.x + 1][positionJoueur.y] == CAISSE_OK) && (positionJoueur.x + 2 >= NB_BLOCS_LARGEUR || carte[positionJoueur.x + 2][positionJoueur.y] == MUR || carte[positionJoueur.x + 2][positionJoueur.y] == CAISSE || carte[positionJoueur.x + 2][positionJoueur.y] == CAISSE_OK)) break; deplacerCaisse(&carte[positionJoueur.x + 1][positionJoueur.y], &carte[positionJoueur.x + 2][positionJoueur.y]); positionJoueur.x++; break; } } void jouer(SDL_Surface* ecran) { int continuer = 1; // Chargement des sprites (décors, personnage...) mur = IMG_Load("img/mur.jpg"); caisse = IMG_Load("img/caisse.jpg"); caisseOK = IMG_Load("img/caisse_ok.jpg"); objectif = IMG_Load("img/objectif.png"); mario[BAS] = IMG_Load("img/mario_bas.gif"); mario[GAUCHE] = IMG_Load("img/mario_gauche.gif"); mario[HAUT] = IMG_Load("img/mario_haut.gif"); mario[DROITE] = IMG_Load("img/mario_droite.gif"); marioActuel = mario[BAS]; // Mario sera dirigé vers le bas au départ // Chargement du niveau if (!chargerNiveau(&carte)) exit(EXIT_FAILURE); // On arrête le jeu si on n'a pas pu charger le niveau // Recherche de la position de Mario au départ for (i = 0 ; i < NB_BLOCS_LARGEUR ; i++) { for (j = 0 ; j < NB_BLOCS_HAUTEUR ; j++) { if (carte[i][j] == MARIO) // Si Mario se trouve à cette position sur la carte { positionJoueur.x = i; positionJoueur.y = j; carte[i][j] = VIDE; } } } // Activation de la répétition des touches SDL_EnableKeyRepeat(100, 100); while (continuer) { SDL_WaitEvent(&event); switch(event.type) { case SDL_QUIT: continuer = 0; break; case SDL_KEYDOWN: switch(event.key.keysym.sym) { case SDLK_ESCAPE: continuer = 0; break; case SDLK_UP: marioActuel = mario[HAUT]; deplacerJoueur(HAUT); break; case SDLK_DOWN: marioActuel = mario[BAS]; deplacerJoueur(BAS); break; case SDLK_RIGHT: marioActuel = mario[DROITE]; deplacerJoueur(DROITE); break; case SDLK_LEFT: marioActuel = mario[GAUCHE]; deplacerJoueur(GAUCHE); break; case SDLK_k: detruireBloc(lastDirection); afficher(ecran); break; } break; } // Effacement de l'écran SDL_FillRect(ecran, NULL, SDL_MapRGB(ecran->format, 255, 255, 255)); // Placement des objets à l'écran objectifsRestants = 0; for (i = 0 ; i < NB_BLOCS_LARGEUR ; i++) { for (j = 0 ; j < NB_BLOCS_HAUTEUR ; j++) { position.x = i * TAILLE_BLOC; position.y = j * TAILLE_BLOC; switch(carte[i][j]) { case MUR: SDL_BlitSurface(mur, NULL, ecran, &position); break; case CAISSE: SDL_BlitSurface(caisse, NULL, ecran, &position); break; case CAISSE_OK: SDL_BlitSurface(caisseOK, NULL, ecran, &position); break; case OBJECTIF: SDL_BlitSurface(objectif, NULL, ecran, &position); objectifsRestants = 1; break; } } } // Si on n'a trouvé aucun objectif sur la carte, c'est qu'on a gagné if (!objectifsRestants) continuer = 0; // On place le joueur à la bonne position position.x = positionJoueur.x * TAILLE_BLOC; position.y = positionJoueur.y * TAILLE_BLOC; SDL_BlitSurface(marioActuel, NULL, ecran, &position); SDL_Flip(ecran); } // Désactivation de la répétition des touches (remise à 0) SDL_EnableKeyRepeat(0, 0); // Libération des surfaces chargées SDL_FreeSurface(mur); SDL_FreeSurface(caisse); SDL_FreeSurface(caisseOK); SDL_FreeSurface(objectif); for (i = 0 ; i < 4 ; i++) SDL_FreeSurface(mario[i]); }