Accueil > > > [DEV-CPP]UN TETRIS, ENCORE...
[DEV-CPP]UN TETRIS, ENCORE...
Information sur la source
Description
Bon alrs c'est un tétris tout simple. C'est mon premier programme en C/C++, je me suis basé sur les sources du PinkTetris de Hylvenir (http://www.cppfrance.com/codes/PINKTRIS-SIMPLE-TE TRIS-SDL_25010.aspx) J'ai totalement refais le jeu. Refais la gestion d'une partie, des scores, des blocs. J'ai mis des variables un peu partout dans le codes pour pouvoir plus simplement modifié le code. Une version 2 est en préparation dans laquelle vous pourrez changer plusieurs options du jeu ; par exemple, les blocs, le nombre de lignes pour changer de niveau, la taille du plateau de jeu. Dans cette version, je distribuerais également les sources qui cette fois seront intégralement commentées. ------------------------------------- ------------------ 19/08/2007 16h00 Tetris V2.0 Par Thierry POINOT Sources initiales du PinkTetris de Hylvenir sur http://www.cppfrance.com : http://www.cppfrance.com/codes/PINKTRIS-SIMPLE-TET RIS-SDL_25010.aspx Ce programme à été développé en C++ avec Dev-cpp. Il utilise les librairie SDL (pour l'affichage) et SDL_TTF pour l'affichage de texte (genre les scores), ainsi que la librairie FMOD pour la gestion du son. Et voilà la version 2 de mon Tétris ! Une interface remanié, les bloc sont, à mon goût, d'une plus jolie couleur (dégradé blanc) que dans la version 1. Les sons ont été changés : il n'y a plus de son pour les déplacements latéraux de blocs. Un bug de fin de partie à été corrigé; lorsqu'une partie était perdu, et que le jeu était figé, à chaque fois que l'utilisateur faisait une action sur la fenêtre, le son de fin de partie se répétait. Désormais, il est possible de jouer avec ses propres blocs ! Le fichier 'blocs.txt' contient les blocs du jeu, et le fichier 'special_blocs.txt' contient les blocs pour généré les bordures et le fond coloré ^^ Il y a également un fichier de configuration 'options.txt' qui contient les principales variable du jeu pour personnalisé votre tétris (taille de la zone de jeu, nombre de ligne pour monter d'un niveau...) Si les fichiers de configuration n'existe pas, ce n'est pas un problème, les options par défaut du programme seront utilisé. Il y a aussi l'affichage du meilleur score sur le plateau de jeu pour vous situer par rapport au meilleur ! Bref cette version est plus personnalisable, plus intéractive, vous pouvez jouez avec les blocs que vous voulez, ce qui donne une nouvelle dimension au jeu ! A VENIR, une version 3 j'espère bien ! avec des blocs plus que spécial qui auront une action spéciale sur le jeu ! Par exemple le bloc point '.' pourra bouché les trous dans votre jeu et compléter les lignes que vous avez raté ! J'espère bien faire aussi un tableau de score, et crypter les score pour éviter la triche, qui donnera un esprit de compétition au jeu. Je prévois dans une version supérieur de faire un éditeur de blocs et de niveau ! comme au snake, après chaque niveau possèdera des murs impossible à enlever, qu'il faudra contourner ! Je prévois également de faire en sorte d'envoyer les score sur le net pour un classement général du jeu, ce qui me permettra avec cette fonctionnalité d'ouvrir un site web. Bref tout ça ne sont que des prévisions et des idées, je ne garantit rien mais bon.... Je remercie encore une fois Hylvenir pour sa source initiale, et Funto qui m'a fait découvrir la lib <vector> tableau multidimensionnel redimensionnable. http://thierry.poinot.fr/ http: //dev.thierry.poinot.fr/ P.S. : regarder les touches du pavé numérique ya un ptit truc nul certes mais marrant, c'était juste pour déconner :P
Source
- ########TETRIS.CPP########
-
- #include "tetris.h"
-
-
- // Fonction principale ----------------------------------------------------------------------------------------------------
- int main( int, char** ) try
- {
- srand( time(NULL) ); // Randomize
-
- // Initialise l'affichage (librairie SDL)
- if ( SDL_Init( SDL_INIT_VIDEO | SDL_INIT_TIMER )== -1 )
- throw runtime_error( SDL_GetError() );
-
- // initialise la librairie qui gère le son (Fmod)
- if ( FSOUND_Init(44100, 32, 0) == -1 )
- throw runtime_error( "FMOD n'a pas pu s'initialiser" );
-
- // initialise la librairie qui gère l'affichage de texte
- if ( TTF_Init() == -1 ) // si la lib ne s'initialise pas...
- throw runtime_error( TTF_GetError() ); // on arrête le programme en renvoyant l'erreur
-
-
- init_options(); // appel de la fonction qui initialise toutes les variables du jeu
-
-
- police = TTF_OpenFont("fonts/courbd.ttf", tetris.case_unit - 4); // on charge la police (le fichier doit obligatoirement exister !!)
- if (!police) // si il y a une erreur dans le chargement de la police...
- throw runtime_error( TTF_GetError() ); // on arrête le programme en renvoyant l'erreur
-
- police_m = TTF_OpenFont("fonts/courbd.ttf", 15); // on charge la police (ici la taille est plus petite) (le fichier doit obligatoirement exister !!)
-
-
- /* jouer un son court avec FMOD
- FSOUND_SAMPLE *grudge = NULL;
- grudge = FSOUND_Sample_Load(FSOUND_FREE, "sounds/the grudge.mp3", 0, 0, 0);
- FSOUND_PlaySound(FSOUND_FREE, grudge);
- //*/
-
- /* jouer un son long (musique) avec FMOD
- FSOUND_STREAM *musique = NULL;
- FSOUND_Stream_SetLoopCount(musique, -1); // répétition à l'infini
- //musique = FSOUND_Stream_Open("musics/Gabry Ponte Dance - Tetris RMX.MP3", FSOUND_LOOP_NORMAL, 110000, 219500); // on charge la musique
- musique = FSOUND_Stream_Open("musics/Gabry Ponte Dance - Tetris RMX.MP3", FSOUND_LOOP_NORMAL, 5 * 109500, 20 * 219500); // on charge la musique
- //FSOUND_Stream_Play(FSOUND_FREE, musique); // on lit la musique
-
- //FSOUND_Stream_Stop(musique); // Arrêt de la musique
- //FSOUND_Stream_Close(musique); // On libère la mémoire (décharge la musique de la mémoire)
- //*/
- /* Faire une pause avec FMOD
- // remplacer FSOUND_ALL par le numéro du canal à mettre en pause
- if (FSOUND_GetPaused(0)) // Si le canal 0 est en pause
- FSOUND_SetPaused(FSOUND_ALL, 0); // On enlève la pause de tous les canaux
- else // Sinon, elle est en cours de lecture
- FSOUND_SetPaused(FSOUND_ALL, 1); // On met en pause tous les canaux
- //*/
-
- /* jouer un midi
- FMUSIC_MODULE *musique = NULL;
- musique = FMUSIC_LoadSong("musics/tetris.mid");
- FMUSIC_SetLooping(musique, 1); // répétition à l'infini
- FMUSIC_PlaySong(musique);
- FMUSIC_SetMasterVolume(musique, 120); // volume
- //FMUSIC_StopSong(musique); // stopper la lecture du midi
- //FMUSIC_FreeSong(musique); // on libère la mémoire (décharge le midi de la mémoire)
- //*/
- /* mettre en pause un midi
- if (FMUSIC_GetPaused(musique)) // Si la chanson est en pause
- FMUSIC_SetPaused(musique, 0); // On enlève la pause
- else // Sinon, elle est en cours de lecture
- FMUSIC_SetPaused(musique, 1); // On active la pause
- //*/
-
-
-
- FSOUND_SetVolume(FSOUND_ALL, 255); // change le volume de tous les canaux ( de 0 à 255)
-
- screen = SDL_SetVideoMode( tetris.board_width + tetris.right_panel_width + tetris.grid_width, tetris.board_height + (tetris.case_unit + tetris.grid_width) + tetris.grid_width, 32, /*SDL_FULLSCREEN | */SDL_HWSURFACE | SDL_DOUBLEBUF ); // création de la fenêtre
- if ( !screen ) // Si il y a une erreur sur la création de la fenêtre... on envoie un runtime error (erreur d'éxécution)
- throw runtime_error( SDL_GetError() );
-
- SDL_EnableKeyRepeat(500,30); // active la répétition des touches du clavier (rester appuyer pour faire plusieurs fois la même action)
-
- init_colors(screen); // on initialise les couleurs
- init_blocs(); // on initialise les blocs
-
- SDL_WM_SetCaption( tetris.window_title, 0 ); // Attribut le titre de la fenêtre (voir 'init_options()')
- SDL_WM_SetIcon( SDL_LoadBMP( "icon.bmp" ), 0 ); // Chargement de l'icône de la fenêtre
-
- init_window_style();
- new_game();
-
- SDL_Event event;
- //while( SDL_PollEvent( &event ) )
- while( SDL_WaitEvent( &event ) )
- {
- switch( event.type )
- {
- case SDL_KEYDOWN:
- switch( event.key.keysym.sym )
- {
- // -- MOUVEMENT --
- case SDLK_RIGHT:
- userMode = goRight; // déplacement du bloc à droite
- break;
- case SDLK_LEFT:
- userMode = goLeft; // déplacement du bloc à gauche
- break;
- case SDLK_DOWN:
- userMode = goDown; // déplacement du bloc en bas
- break;
-
- case SDLK_UP:
- //userMode = goUp; break;
- //FSOUND_PlaySound(FSOUND_FREE, tetris.bloc_is_fixed); break; // on joue le son qui correspond au fait que le joueur souhaite faire descendre le bloc
- case SDLK_KP0:
- userMode = turnRight; // rotation du bloc
- break;
-
-
- //* SONS BONUS !!!!
- case SDLK_KP1:
- FSOUND_PlaySound(FSOUND_FREE, tetris.sound_one);
- break;
- case SDLK_KP2:
- FSOUND_PlaySound(FSOUND_FREE, tetris.sound_two);
- break;
- case SDLK_KP3:
- FSOUND_PlaySound(FSOUND_FREE, tetris.sound_three);
- break;
- case SDLK_KP4:
- FSOUND_PlaySound(FSOUND_FREE, tetris.sound_go);
- break;
-
- case SDLK_RCTRL:
- // remplacer FSOUND_ALL par le numéro du canal à mettre en pause
- if (FSOUND_GetPaused(0)) // Si le canal 0 est en pause
- FSOUND_SetPaused(FSOUND_ALL, 0); // On enlève la pause de tous les canaux
- else // Sinon, elle est en cours de lecture
- FSOUND_SetPaused(FSOUND_ALL, 1); // On met en pause tous les canaux
- FSOUND_Stream_Play(FSOUND_FREE, tetris.musique);
- break;
- case SDLK_RSHIFT:
- FSOUND_Stream_Stop(tetris.musique); // Arrêt de la musique
- FSOUND_SetPaused(FSOUND_ALL, 1); // On met la pause
- break;
- //*/
-
- case SDLK_F2: new_game(); break;
-
- // -- PAUSE --
- case SDLK_SPACE:
- case SDLK_p: pause = !pause; break;
-
- // -- EXIT --
- case SDLK_ESCAPE: userMode = quit; break;
- }
- break;
- case SDL_KEYUP: userMode = none; break;
- case SDL_QUIT: userMode = quit; continue;
- }
- if ( pause )
- {
- update_surface(screen); // Mise à jour de l'écran
- continue;
- }
-
- MoveBloc( userMode );
- update_game();
- }
-
- quit_game();
-
- return 0;
- }
- catch( exception& e )
- {
- ofstream cerr( "program_error.txt" );
- cerr << e.what();
- return 1;
- }
-
-
-
- // Fonction d'initialisation des variables principales du jeu ----------------------------------------------------------------------------------------------------
- void init_options()
- {
-
- tetris.case_unit = 25; // la longueur en pixel du côté du carré qui forme une tuile (la tuile est ce qui compose un bloc ce sont les cases unitaires...)
- tetris.board_size_x = 10 + 2; // la largeur de la matrice (zone de jeu) en 'case_unit' + les 2 côtés qui forment les bords (droit et gauche)
- tetris.board_size_y = 22 + 1; // la hauteur de la matrice en 'case_unit' + le bas de la zone de jeu (le sol)
- tetris.grid_width = 1; // la largeur en pixel de la grille, du cadrillage
-
- tetris.line_number_to_level_up = 10; // nombre de lignes à compléter pour monter d'un niveau (mettez la valeur que vous souhaitez, la valeur officielle est 10 lignes pour monter d'un niveau, mais si vous souhaitez que vos parties durent plus longtemps mettez 20)
-
- //* chargement des options dans le fichier de configuration
- ifstream fichier;
- fichier.open("options.txt", ios::in);
-
- if(fichier)
- {
- fichier >> tetris.case_unit >> tetris.board_size_x >> tetris.board_size_y >> tetris.grid_width >> tetris.line_number_to_level_up;
- /*
- vector <string> file_content; // variable qui contiendra le fichier (tableau avec une ligne par entrée du tableau)
- string ligne;
- while(getline(fichier, ligne)) {
- file_content.push_back( ligne );
- }
- //*/
- }
- else
- {
- throw runtime_error( "Impossible d'ouvrir le fichier de configuration !" );
- cout << "Impossible d'ouvrir le fichier de configuration !" << endl;
- }
- fichier.close();
-
- //*/
-
-
- tetris.init_posY = 0; // position initiale d'un nouveau bloc (ordonnée)
- tetris.init_posX = (tetris.board_size_x - 2) / 2; // position initiale d'un nouveau bloc (abscisse) : ici un bloc nouveau apparaîtra toujours centré dans la zone de jeu (-2 pour les bordures de droite et gauche)
-
- tetris.bloc_number = 0; // initialise le nombre de blocs (laissé à 0 car cette variable est automatiquement incrémenté lors de l'ajout de bloc avec la fonction 'add_bloc()')
- tetris.special_bloc_number = 0; // initialise le nombre de blocs spéciaux (laissé à 0 car cette variable est automatiquement incrémenté lors de l'ajout de bloc avec la fonction 'add_special_bloc()')
-
- tetris.board_width = tetris.board_size_x * (tetris.case_unit + tetris.grid_width); // calcul de la largeur de la matrice en pixel
- tetris.board_height = tetris.board_size_y * (tetris.case_unit + tetris.grid_width); // calcul de la hauteur de la matrice en pixel
- tetris.right_panel_width = (tetris.case_unit + tetris.grid_width) * 10; // taille de la zone à droite de la matrice en pixel (ici la zone fait 10 tuiles de largeur)
-
- tetris.next_bloc_preview_x = tetris.board_width; // abscisse du coin supérieur gauche de la zone d'aperçu du bloc suivant (ici, c'est juste à côté de la matrice)
- tetris.next_bloc_preview_y = 0; // ordonée du coin supérieur gauche de la zone d'aperçu du bloc suivant (ici, c'est tout en haut)
- tetris.next_bloc_preview_size_x = 5; // largeur en 'case_unit' de la zone d'aperçu du bloc suivant
- tetris.next_bloc_preview_size_y = 5; // hauteur en 'case_unit' de la zone d'aperçu du bloc suivant
- tetris.next_bloc_preview_width = tetris.next_bloc_preview_size_x * (tetris.case_unit + tetris.grid_width); // largeur en pixel de la zone d'aperçu du bloc suivant
- tetris.next_bloc_preview_height = tetris.next_bloc_preview_size_y * (tetris.case_unit + tetris.grid_width); // hauteur en pixel de la zone d'aperçu du bloc suivant
-
- tetris.window_title = "* Tetris V2 * ...du 18/08/2007 15h45..."; // titre de la fenêtre
-
- tetris.musique = FSOUND_Stream_Open("musics/Gabry Ponte Dance - Tetris RMX.MP3", FSOUND_LOOP_NORMAL, 5 * 109500, 20 * 219500); // on charge la musique
- FSOUND_Stream_SetLoopCount(tetris.musique, 0); // répétition à l'infini
- FSOUND_SetPaused(FSOUND_ALL, 1); // On met la pause
-
- tetris.sound_bloc_rotate_right = FSOUND_Sample_Load(FSOUND_FREE, "sounds/user_rotate_bloc_at_right.sound", 0, 0, 0);
- tetris.sound_bloc_rotate_left = FSOUND_Sample_Load(FSOUND_FREE, "sounds/user_rotate_bloc_at_left.sound", 0, 0, 0);
-
- tetris.sound_bloc_go_right_user = FSOUND_Sample_Load(FSOUND_FREE, "sounds/user_move_bloc_at_right.sound", 0, 0, 0);
- tetris.sound_bloc_go_left_user = FSOUND_Sample_Load(FSOUND_FREE, "sounds/user_move_bloc_at_left.sound", 0, 0, 0);
- tetris.sound_bloc_go_down_user = FSOUND_Sample_Load(FSOUND_FREE, "sounds/when_bloc_go_down_by_user.sound", 0, 0, 0);
- tetris.sound_bloc_go_up_user = FSOUND_Sample_Load(FSOUND_FREE, "sounds/when_bloc_go_up_by_user.sound", 0, 0, 0);
-
- tetris.sound_bloc_go_down = FSOUND_Sample_Load(FSOUND_FREE, "sounds/when_bloc_go_down_auto.sound", 0, 0, 0);
- tetris.sound_bloc_go_up = FSOUND_Sample_Load(FSOUND_FREE, "sounds/when_bloc_go_up_auto.sound", 0, 0, 0);
-
- tetris.sound_bloc_is_fixed = FSOUND_Sample_Load(FSOUND_FREE, "sounds/when_bloc_is_fixed_on_the_floor.sound", 0, 0, 0);
- tetris.sound_line_completed = FSOUND_Sample_Load(FSOUND_FREE, "sounds/when_line_is_completed.sound", 0, 0, 0);
- tetris.sound_level_up = FSOUND_Sample_Load(FSOUND_FREE, "sounds/level_up.sound", 0, 0, 0);
- tetris.sound_loose_game = FSOUND_Sample_Load(FSOUND_FREE, "sounds/loose_game.sound", 0, 0, 0);
- tetris.sound_new_game = FSOUND_Sample_Load(FSOUND_FREE, "sounds/new_game.sound", 0, 0, 0);
-
- //* Sons bonus (3...2...1...GO)
- tetris.sound_three = FSOUND_Sample_Load(FSOUND_FREE, "sounds/three.ogg", 0, 0, 0);
- tetris.sound_two = FSOUND_Sample_Load(FSOUND_FREE, "sounds/two.ogg", 0, 0, 0);
- tetris.sound_one = FSOUND_Sample_Load(FSOUND_FREE, "sounds/one.ogg", 0, 0, 0);
- tetris.sound_go = FSOUND_Sample_Load(FSOUND_FREE, "sounds/go.ogg", 0, 0, 0);
- //*/
- }
-
- // Fonction d'initialisation des couleurs du jeu ----------------------------------------------------------------------------------------------------
- void init_colors (SDL_Surface* screen)
- {
- tetris.bloc_border_color = SDL_MapRGB(screen->format, 0, 0, 0); // couleur de bordure d'un bloc (a utilisé uniquement sans la génération automatique du dégradé sur les bloc : voir code commenté dans la fonction addBloc)
- tetris.background_color = SDL_MapRGB(screen->format, 212, 208, 200); // On créé une variable qui contient la couleur du background (fond d'écran) en format RGB ou RVB (Rouge, Vert, Bleu)
- tetris.matrice_color = SDL_MapRGB(screen->format, 255, 255, 255); // On créé une variable qui contient la couleur du background (fond d'écran) en format RGB ou RVB (Rouge, Vert, Bleu)
- tetris.grid_color = SDL_MapRGB(screen->format, 150, 150, 150); // On créé une variable qui contient la couleur du background (fond d'écran) en format RGB ou RVB (Rouge, Vert, Bleu)
- }
- // Fonction d'initialisation des blocs utilisant la fonction addBloc ----------------------------------------------------------------------------------------------------
- void init_blocs ()
- {
- if (!get_blocs_by_file(true)) { // Si l'initialisation par fichier de configuration a échouée, on créé les blocs
- //*
- add_special_bloc( 1, "1", 50, 50, 50 ); // bloc unitaire pour les bordures (tétrion)
- //* blocs unitaires pour le fond aléatoire
- add_special_bloc( 1, "1", 255, 0, 0 );
- add_special_bloc( 1, "1", 51, 102, 255 );
- add_special_bloc( 1, "1", 255, 220, 0 );
- add_special_bloc( 1, "1", 255, 0, 255 );
- add_special_bloc( 1, "1", 210, 210, 200 );
- add_special_bloc( 1, "1", 0, 255, 0 );
- add_special_bloc( 1, "1", 0, 0, 255 );
- /*
- for (int x = 0; x < 50; x++) // ajout de 50 blocs spéciaux unitaires dont la couleur est aléatoire
- add_special_bloc( 1, "1" );
- //*/
- //*/
- }
- if (!get_blocs_by_file()) { // Si l'initialisation par fichier de configuration a échouée, on créé les blocs
- //*
- //* Blocs originaux
- add_bloc( 4, "0010001000100010", 255, 0, 0 ); // barre I
- add_bloc( 2, "1111", 51, 102, 255 ); // carré O
- add_bloc( 3, "010111000", 153, 51, 0 ); // T
- add_bloc( 3, "001111000", 255, 0, 255 ); // L
- add_bloc( 3, "100111000", 200, 200, 200 ); // J couleur originale : le blanc
- add_bloc( 3, "100110010", 0, 255, 0 ); // S
- add_bloc( 3, "001011010", 0, 204, 255 ); // Z
- //*/
- /* blocs du tétris B
- add_bloc( 1, "1"); // le point .
- add_bloc( 2, "1011", 255, 220, 0 ); // mini L
- //add_bloc( 3, "111010010" ); // T (grand)
- //add_bloc( 3, "010111010" ); // +
- add_bloc( 3, "010010010" ); // la barre de 3
- add_bloc( 2, "0101" ); // la barre de 2
- add_bloc( 3, "101111000" ); // la cuvette de 3
- //*/
-
- //*/
- }
- }
-
- // Fonction appelée lors d'une nouvelle partie ----------------------------------------------------------------------------------------------------
- void new_game()
- {
- if (game == true) // Si il y a une partie en cours...
- end_game(); // on termine la partie
-
- pause = false; // On enlève la pause au cas où elle serait activée
-
- init_window_style(); // on réinitialise l'affichage de la fenêtre pour afficher un nouveau fond aléatoire
-
- FSOUND_PlaySound(FSOUND_FREE, tetris.sound_new_game); // on joue le son qui correspond à une nouvelle partie
-
- //* chargement du score maximal
- ifstream scoreFile( "score.txt" ); // on ouvre le fichier qui contient le record
- if ( scoreFile ) // si le fichier existe...
- scoreFile >> scoreMax >> lineMax; // on met la première ligne du fichier comme score max et la deuxième ligne du fichier comme nombre de lignes max
- //*/
-
- board.init_board(); // Initialise le tableau de jeu (objet voir 'board.h')
-
- currentBloc = blocs[ rand() % tetris.bloc_number ]; // On sélectionne un bloc au hasard pour le bloc courant
- nextBloc = blocs[ rand() % tetris.bloc_number ]; // On sélectionne un bloc au hasard pour le prochain bloc
-
- tetris.posX = tetris.init_posX; // On initialise la position du bloc à sa position initiale (abscisse)
- tetris.posY = tetris.init_posY; // On initialise la position du bloc à sa position initiale (ordonnée)
-
- tetris.score = 0; // initialise le score à 0 (laisser à 0 sinon vous triché :P)
- tetris.lines = 0; // initialise le nombre de lignes complétées (laisser à 0, changer la valeur n'a aucune influence sur le score, c'est juste indicatif)
- tetris.level = 1; // initialise le niveau on commence au niveau 1 et pas 0 sinon les blocs ne descendent pas ^^ (augmenter le niveau de départ d'une partie influe sur la vitesse de descente du bloc)
-
- game = true; // On met true à la variable qui dit qu'une partie est en cours
-
- SDL_Delay( 500 ); // On met en pause le programme pour une demie seconde pour donner le temps au joueur de se mettre en place (utile pour ceux qui ne connaissent pas par coeur le clavier :P)
-
- //* On créé le timer pour la descente automatique du bloc
- GAMES_MODE tmp = goDown;
- timer_MoveBloc_auto = SDL_AddTimer(1000 / tetris.level, MoveBloc_auto, &tmp); // Démarrage du Timer
- //*/
- }
-
- // Fonction appelée à la fin d'une partie ----------------------------------------------------------------------------------------------------
- void end_game(bool loose_game)
- {
- //* Sauvegarde les informations de la dernière partie (un genre de log)
- ofstream cout( "last_game.txt");
-
- time_t ltime;
- struct tm *today;
- time( <ime );
- today = localtime( <ime );
- char tmpbuf[128];
- strftime(tmpbuf, 128, "%A %d %B %Y à %H:%M:%S", today);
-
- cout << "----------------------------------------------------------------------------------------------------" << endl;
- cout << "Partie terminée le " << tmpbuf << endl;
- cout << "Score : " << tetris.score << endl;
- cout << "Lignes : " << tetris.lines << endl;
- cout << "Niveau : " << tetris.level << endl;
- //*/
-
- //* Sauvegarde du score maximal (meilleur score)
- if (tetris.score > scoreMax) { // Si le score de la partie est supérieur au score maximum atteint...
- ofstream scoreFile( "score.txt" );
- scoreFile << tetris.score << endl << tetris.lines; // on sauvegarde le score actuel et son nombre de lignes
- }
- //*/
-
- if (loose_game == true) // si la partie est terminé parce que le joueur vient de perdre...
- FSOUND_PlaySound(FSOUND_FREE, tetris.sound_loose_game); // on joue le son qui correspond à la perte de la partie
-
-
- SDL_RemoveTimer(timer_MoveBloc_auto); // Arrêt du Timer qui fait la descente automatique du bloc
-
- game = false;
- }
-
- int update_game()
- {
-
- draw_surface( matrice, 0, 0, matrice->w, matrice->h, background, tetris.case_unit + tetris.grid_width, tetris.case_unit + tetris.grid_width ); // Effacement de l'écran
- //SDL_BlitSurface( background, 0, screen, 0 ); // Effacement de l'écran
- //update_surface(background);
- //update_surface(matrice);
- draw_surface(background, 0, 0, background->w, background->h, screen, 0, 0);
-
- board.display( screen ); // Affichage du fond d'écran
- currentBloc.display( screen, tetris.posX, tetris.posY ); // Affichage de la pièce courante
- nextBloc.display( screen, tetris.next_bloc_preview_x / (tetris.case_unit + tetris.grid_width), tetris.next_bloc_preview_y / (tetris.case_unit + tetris.grid_width)); // Affichage de la prochaine pièce
-
- // Affichage du niveau
- char level_str[100];
- sprintf(level_str, "Niveau = %d", tetris.level);
- show_text(level_str, police, screen, tetris.board_width + tetris.grid_width, (tetris.next_bloc_preview_size_y + 1 + 1) * (tetris.case_unit + tetris.grid_width), 0, 0, 0);
-
- // Affichage du score
- char score_str[100];
- sprintf(score_str, "Score = %d", tetris.score);
- show_text(score_str, police, screen, tetris.board_width + tetris.grid_width, (tetris.next_bloc_preview_size_y + 1 + 2) * (tetris.case_unit + tetris.grid_width), 0, 0, 0);
-
- // Affichage des lignes
- char lines_str[100];
- sprintf(lines_str, "Lignes = %d", tetris.lines);
- show_text(lines_str, police, screen, tetris.board_width + tetris.grid_width, (tetris.next_bloc_preview_size_y + 1 + 3) * (tetris.case_unit + tetris.grid_width), 0, 0, 0);
-
- show_text("F2 = Nouvelle partie", police_m, screen, tetris.board_width + tetris.grid_width, (tetris.next_bloc_preview_size_y + 1 + 4 + 1) * (tetris.case_unit + tetris.grid_width), 0, 0, 0);
- show_text("Espace = Pause", police_m, screen, tetris.board_width + tetris.grid_width, (tetris.next_bloc_preview_size_y + 1 + 4 + 2) * (tetris.case_unit + tetris.grid_width), 0, 0, 0);
- show_text("Echap = Quitter", police_m, screen, tetris.board_width + tetris.grid_width, (tetris.next_bloc_preview_size_y + 1 + 4 + 3) * (tetris.case_unit + tetris.grid_width), 0, 0, 0);
-
- char highScore[100];
- sprintf(highScore, "Meilleur score = %d", scoreMax);
- show_text(highScore, police_m, screen, tetris.board_width + tetris.grid_width, (tetris.next_bloc_preview_size_y + 1 + 4 + 5) * (tetris.case_unit + tetris.grid_width), 0, 0, 0);
-
- update_surface(screen); // Mise à jour de l'écran
-
- if ( !board.isMouvementValid( tetris.posX, tetris.posY, currentBloc ) && game == true ) // partie terminée
- end_game(true);
-
- if (userMode == quit) {
- quit_game();
- return 0;
- }
-
- }
-
- // Fonction d'ajout de bloc : Si les taux des trois couleurs Rouge Vert Bleu ne sont pas spécifié, il y a génération aléatoire du taux de chaque couleur : voir le prototype de la fonction addBloc dans 'tetris.h' ----------------------------------------------------------------------------------------------------
- void add_bloc(int blocMaxWidth, string blocShape, int redRate, int greenRate, int blueRate)
- {
- redRate = (redRate > 255) ? (rand() % 256) : redRate;
- greenRate = (greenRate > 255) ? (rand() % 256) : greenRate;
- blueRate = (blueRate > 255) ? (rand() % 256) : blueRate;
-
- blocs.push_back( Bloc( tetris.bloc_number, blocMaxWidth, blocShape.c_str(), redRate, greenRate, blueRate ) ); // ajout du bloc avec dégradé vers le noir
- tetris.bloc_number++;
- }
-
- void add_special_bloc(int blocMaxWidth, string blocShape, int redRate, int greenRate, int blueRate)
- {
- redRate = (redRate > 255) ? (rand() % 256) : redRate;
- greenRate = (greenRate > 255) ? (rand() % 256) : greenRate;
- blueRate = (blueRate > 255) ? (rand() % 256) : blueRate;
-
- special_blocs.push_back( Bloc( tetris.special_bloc_number, blocMaxWidth, blocShape.c_str(), redRate, greenRate, blueRate ) ); // ajout du bloc avec dégradé vers le noir
- tetris.special_bloc_number++;
- }
-
- bool get_blocs_by_file (bool get_special_blocs)
- {
- //* chargement des blocs à partir du fichier
- ifstream blocs_file;
- if (!get_special_blocs)
- blocs_file.open("blocs.txt", ios::in);
- else
- blocs_file.open("special_blocs.txt", ios::in);
-
- int len, redRate, greenRate, blueRate;
- string shape;
- vector <string> file_content; // variable qui contiendra le fichier (tableau avec une ligne par entrée du tableau)
- string ligne, tmp;
- int i = 0, j = 0, last_pos = 0, num = 0;
- bool no_error = false;
- if(blocs_file)
- {
- while(getline(blocs_file, ligne)) {
- no_error = false;
- file_content.push_back( ligne );
- num = 0;
- last_pos = 0;
- if (file_content[i].substr( 0, 2) != "//") {
- for (j = 0; j < file_content[i].size(); j++) {
- if (file_content[i].substr( j, 1 ) == ";") {
- tmp = file_content[i].substr( last_pos, j - last_pos );
- last_pos = j + 1;
- num++;
- switch (num) {
- case 1:
- len = atoi(tmp.c_str());
- break;
- case 2:
- shape = tmp.c_str();
- break;
- case 3:
- redRate = atoi(tmp.c_str());
- break;
- case 4:
- greenRate = atoi(tmp.c_str());
- break;
- case 5:
- blueRate = atoi(tmp.c_str());
- no_error = true;
- break;
- }
- }
- }
- if (no_error)
- if (!get_special_blocs)
- add_bloc( len, shape, redRate, greenRate, blueRate );
- else
- add_special_bloc( len, shape, redRate, greenRate, blueRate );
- }
- i++;
- }
- }
- else
- {
- return false;
- }
- blocs_file.close();
- return true;
-
- //*/
- }
-
-
-
- void update_surface (SDL_Surface* surface)
- {
- SDL_UpdateRect( surface, 0, 0, surface->w, surface->h );
- SDL_Flip(surface);
- }
-
- // Fonction d'affichage de surface sur une surface de destination ----------------------------------------------------------------------------------------------------
- void draw_surface (SDL_Surface* src, int X_ori, int Y_ori, int srcWidth, int srcHeight, SDL_Surface* dest, int posX_onDest, int posY_onDest, Uint32 color)
- {
- // Les coordonnées de la surface sur la surface de destination
- SDL_Rect srcPositionOnDestination; // définition de la variable
- srcPositionOnDestination.x = posX_onDest; // abscisse
- srcPositionOnDestination.y = posY_onDest; // ordonnée
- SDL_Rect srcPosition;
- srcPosition.x = X_ori;
- srcPosition.y = Y_ori;
- srcPosition.w = srcWidth;
- srcPosition.h = srcHeight;
- if (color != 0) {
- SDL_FillRect(src, NULL, color); // Remplissage de la surface avec la couleur (color) passée en paramètre
- }
- SDL_BlitSurface(src, &srcPosition, dest, &srcPositionOnDestination); // Collage de la surface (src) sur la destination (dest)
- // SDL_Flip(dest);
- }
-
- void init_window_style ()
- {
- int i = 0; // variables pour les boucles
- // Chargement du fond d'écran
- SDL_Surface* random_background = generate_random_bmp_tuiles(); // génération aléatoire d'une image remplie de tuiles (special_blocs)
- background = SDL_CreateRGBSurface(SDL_HWSURFACE, screen->w, screen->h, 32, 0, 0, 0, 0); // On créé une surface nommée background
- SDL_FillRect(background, NULL, tetris.background_color); // Remplissage de la surface avec la couleur (color) passée en paramètre
- draw_surface(random_background, 0, 0, random_background->w, random_background->h, background, 0, 0); // On dessine le background sur la fenêtre (screen)
- //background = SDL_LoadBMP( "alea.bmp" ); // On charge une image de fond d'écran
- draw_surface(background, 0, 0, background->w, background->h, screen, 0, 0); // On dessine le background sur la fenêtre (screen)
- if ( !background ) // Si il y a une erreur sur la création du background... on envoie un runtime error (erreur d'éxécution)
- throw runtime_error( SDL_GetError() );
-
- // Chargement de la matrice (zone de jeu)
- matrice = SDL_CreateRGBSurface(SDL_HWSURFACE, tetris.board_width - (2 * tetris.case_unit) - tetris.grid_width, tetris.board_height - tetris.case_unit, 32, 0, 0, 0, 0); // On créé une surface pour la matrice
- draw_surface(matrice, 0, 0, matrice->w, matrice->h, background, tetris.case_unit + tetris.grid_width, tetris.case_unit + tetris.grid_width, tetris.matrice_color); // On dessine la matrice sur le fond d'écran
- if ( !matrice )
- throw runtime_error( SDL_GetError() );
- //*/
-
- //* Chargement du cadrillage
- int numberLineY = tetris.board_size_y, numberLineX = tetris.board_size_y;
- grid = SDL_CreateRGBSurface(SDL_HWSURFACE, matrice->w, matrice->h, 32, 0, 0, 0, 0); // On créé une surface pour la grille (grid)
- SDL_FillRect(grid, NULL, tetris.matrice_color); // on remet la couleur de la matrice comme couleur de fond
- SDL_Surface* gridX[numberLineX];
- for (i = 0; i < numberLineX; i++) {
- gridX[i] = SDL_CreateRGBSurface(SDL_HWSURFACE, numberLineX * (tetris.case_unit + tetris.grid_width), tetris.grid_width, 32, 0, 0, 0, 0); // On créé une surface pour la ligne
- draw_surface(gridX[i], 0, 0, gridX[i]->w, gridX[i]->h, grid, 0, i*(tetris.case_unit + tetris.grid_width), tetris.grid_color); // On dessine la ligne (gridX[i]) sur la grille (grid)
- if ( !gridX[i] )
- throw runtime_error( SDL_GetError() );
- }
-
- SDL_Surface* gridY[numberLineY];
- for (i = 0; i < numberLineY; i++) {
- gridY[i] = SDL_CreateRGBSurface(SDL_HWSURFACE, tetris.grid_width, numberLineY * (tetris.case_unit + tetris.grid_width), 32, 0, 0, 0, 0); // On créé une surface pour la ligne
- draw_surface(gridY[i], 0, 0, gridY[i]->w, gridY[i]->h, grid, i*(tetris.case_unit + tetris.grid_width), 0, tetris.grid_color); // On dessine la ligne (gridY[i]) sur la grille (grid)
- if ( !gridY[i] )
- throw runtime_error( SDL_GetError() );
- }
- draw_surface(grid, 0, 0, grid->w, grid->h, matrice, 0, 0);
- //*/
-
- //* Chargement du fond de la zone d'aperçu du bloc suivant
- previewBloc = SDL_CreateRGBSurface(SDL_HWSURFACE, tetris.next_bloc_preview_width + tetris.grid_width, tetris.next_bloc_preview_height + tetris.grid_width, 32, 0, 0, 0, 0); // On créé une surface pour la grille (grid)
- draw_surface(grid, 0, 0, grid->w, grid->h, previewBloc, 0, 0);
- draw_surface(previewBloc, 0, 0, tetris.next_bloc_preview_width + tetris.grid_width, tetris.next_bloc_preview_height + tetris.grid_width, background, tetris.next_bloc_preview_x, tetris.next_bloc_preview_y + (tetris.case_unit + tetris.grid_width));
- //*/
-
- //* Chargement du tétrion (contour de la matrice)
- for (i = 0; i < tetris.board_size_x; i++) {
- draw_surface( special_blocs[0].get_tuile(), tetris.grid_width, tetris.grid_width, tetris.case_unit, tetris.case_unit, background, i * (tetris.case_unit + tetris.grid_width) + tetris.grid_width, tetris.grid_width);
- draw_surface( special_blocs[0].get_tuile(), tetris.grid_width, tetris.grid_width, tetris.case_unit, tetris.case_unit, background, i * (tetris.case_unit + tetris.grid_width) + tetris.grid_width, tetris.board_height + tetris.grid_width);
- }
- for (i = 0; i < tetris.board_size_y; i++) {
- draw_surface( special_blocs[0].get_tuile(), tetris.grid_width, tetris.grid_width, tetris.case_unit, tetris.case_unit, background, tetris.grid_width, i * (tetris.case_unit + tetris.grid_width) + tetris.grid_width);
- draw_surface( special_blocs[0].get_tuile(), tetris.grid_width, tetris.grid_width, tetris.case_unit, tetris.case_unit, background, tetris.board_width - tetris.case_unit, i * (tetris.case_unit + tetris.grid_width) + tetris.grid_width);
- }
- //*/
- //* Chargement du tétrion de la zone d'aperçu du bloc suivant
- for (i = 0; i < tetris.next_bloc_preview_size_x; i++) {
- draw_surface( special_blocs[0].get_tuile(), tetris.grid_width, tetris.grid_width, tetris.case_unit, tetris.case_unit, background, tetris.next_bloc_preview_x + i * (tetris.case_unit + tetris.grid_width) + tetris.grid_width, tetris.next_bloc_preview_y + tetris.grid_width);
- draw_surface( special_blocs[0].get_tuile(), tetris.grid_width, tetris.grid_width, tetris.case_unit, tetris.case_unit, background, tetris.next_bloc_preview_x + i * (tetris.case_unit + tetris.grid_width) + tetris.grid_width, (tetris.next_bloc_preview_size_y + 1) * (tetris.case_unit + tetris.grid_width) + tetris.next_bloc_preview_y + tetris.grid_width);
- }
- for (i = 0; i < tetris.next_bloc_preview_size_y + 2; i++) { // + 2 pour le haut et le bas
- draw_surface( special_blocs[0].get_tuile(), tetris.grid_width, tetris.grid_width, tetris.case_unit, tetris.case_unit, background, tetris.next_bloc_preview_x - tetris.case_unit, tetris.next_bloc_preview_y + i * (tetris.case_unit + tetris.grid_width) + tetris.grid_width);
- draw_surface( special_blocs[0].get_tuile(), tetris.grid_width, tetris.grid_width, tetris.case_unit, tetris.case_unit, background, tetris.next_bloc_preview_x + tetris.next_bloc_preview_width + tetris.grid_width, tetris.next_bloc_preview_y + i * (tetris.case_unit + tetris.grid_width) + tetris.grid_width);
- }
- //*/
- //* Chargement du tétrion de la zone d'affichage du score, des lignes et du niveau
- for (i = 0; i < tetris.right_panel_width; i++) {
- draw_surface( special_blocs[0].get_tuile(), tetris.grid_width, tetris.grid_width, tetris.case_unit, tetris.case_unit, background, i * (tetris.case_unit + tetris.grid_width) + tetris.grid_width + tetris.board_width, (tetris.next_bloc_preview_size_y + 1)*(tetris.case_unit + tetris.grid_width) + tetris.grid_width);
- draw_surface( special_blocs[0].get_tuile(), tetris.grid_width, tetris.grid_width, tetris.case_unit, tetris.case_unit, background, i * (tetris.case_unit + tetris.grid_width) + tetris.grid_width + tetris.board_width, (tetris.next_bloc_preview_size_y + 1 + 4)*(tetris.case_unit + tetris.grid_width) + tetris.grid_width);
- }
- SDL_Surface* score_background = SDL_CreateRGBSurface(SDL_HWSURFACE, tetris.right_panel_width - tetris.grid_width, 3 * (tetris.case_unit + tetris.grid_width) - tetris.grid_width, 32, 0, 0, 0, 0); // On créé une surface pour la matrice
- draw_surface( score_background, 0, 0, score_background->w, score_background->h, background, tetris.grid_width + tetris.board_width, (tetris.next_bloc_preview_size_y + 1 + 1)*(tetris.case_unit + tetris.grid_width) + tetris.grid_width, tetris.matrice_color);
- //*/
- //* Chargement du tétrion de la zone d'affichage des aides
- for (i = 0; i < tetris.right_panel_width; i++) {
- draw_surface( special_blocs[0].get_tuile(), tetris.grid_width, tetris.grid_width, tetris.case_unit, tetris.case_unit, background, i * (tetris.case_unit + tetris.grid_width) + tetris.grid_width + tetris.board_width, (tetris.next_bloc_preview_size_y + 1 + 4)*(tetris.case_unit + tetris.grid_width) + tetris.grid_width);
- draw_surface( special_blocs[0].get_tuile(), tetris.grid_width, tetris.grid_width, tetris.case_unit, tetris.case_unit, background, i * (tetris.case_unit + tetris.grid_width) + tetris.grid_width + tetris.board_width, (tetris.next_bloc_preview_size_y + 1 + 4 + 6)*(tetris.case_unit + tetris.grid_width) + tetris.grid_width);
- }
- SDL_Surface* help_background = SDL_CreateRGBSurface(SDL_HWSURFACE, tetris.right_panel_width - tetris.grid_width, 5 * (tetris.case_unit + tetris.grid_width) - tetris.grid_width, 32, 0, 0, 0, 0); // On créé une surface pour la matrice
- draw_surface( help_background, 0, 0, help_background->w, help_background->h, background, tetris.grid_width + tetris.board_width, (tetris.next_bloc_preview_size_y + 1 + 4 + 1)*(tetris.case_unit + tetris.grid_width) + tetris.grid_width, tetris.matrice_color);
- //*/
- }
-
- void show_text (char* text, TTF_Font* font, SDL_Surface* dest, int posX, int posY, int redRate, int greenRate, int blueRate, int alpha)
- {
- SDL_Color color = {redRate, greenRate, blueRate};
- SDL_Surface* text_surface = TTF_RenderText_Blended(font, text, color);
- SDL_SetAlpha(text_surface, SDL_SRCALPHA, alpha); // Transparence Alpha
-
- draw_surface(text_surface, 0, 0, text_surface->w, text_surface->h, dest, posX, posY);
- }
-
- SDL_Surface* generate_random_bmp_tuiles (bool saveBMP)
- {
- //* Génération d'un fond aléatoire pleins de tuiles avec les blocs spéciaux excepté le premier bloc spécial qui sert pour le tétrion
- SDL_Surface* random_background = SDL_CreateRGBSurface(SDL_HWSURFACE, screen->w, screen->h, 32, 0, 0, 0, 0); // On créé une surface nommée background
- int num_width = (screen->w / (tetris.case_unit + tetris.grid_width));
- int num_height = (screen->h / (tetris.case_unit + tetris.grid_width));
- Bloc bloc2;
- for (int x = 0; x < num_width; x++) {
- for (int y = 0; y < num_height; y++) {
- bloc2 = special_blocs[ (rand() % (special_blocs.size() - 1)) + 1 ];
- draw_surface( bloc2.get_tuile(), tetris.grid_width, tetris.grid_width, tetris.case_unit, tetris.case_unit, random_background, (x*(tetris.case_unit + tetris.grid_width)) + tetris.grid_width, (y*(tetris.case_unit + tetris.grid_width)) + tetris.grid_width);
- }
- }
- if (saveBMP)
- SDL_SaveBMP(random_background, "alea.bmp"); // on sauvegarde l'image créé pour le fun ;)
-
- return random_background;
- //*/
- }
-
- // Fonction d'arrêt du programme ----------------------------------------------------------------------------------------------------
- void quit_game()
- {
- if (game == true) // Si il y a une partie en cours...
- end_game(); // on termine la partie
-
- // Libération des surfaces
- SDL_FreeSurface( grid );
- SDL_FreeSurface( matrice );
- SDL_FreeSurface( background );
- SDL_FreeSurface( screen );
-
- FSOUND_Close(); // on arrête FMOD (librairie qui gère le son)
-
- /*
- TTF_CloseFont(police); // ferme la police chargée
- TTF_CloseFont(police_m); // ferme la police chargée
- TTF_Quit(); // arrêt de SDL_TTF
- //*/
- SDL_Quit(); // On arrête SDL (lib qui gère l'affichage)
- }
-
-
- Uint32 MoveBloc_auto( Uint32 intervalle, void *param )
- {
- if ( pause )
- {
- //SDL_BlitSurface( background, 0, screen, 0 ); // Effacement du plateau de jeu
- //SDL_BlitSurface(grid, 0,
- update_surface(screen); // Mise à jour de l'écran
- return intervalle;
- }
-
-
- GAMES_MODE tmp = goDown;
- MoveBloc(tmp);
- update_game();
-
-
- return intervalle;
- }
- void MoveBloc( GAMES_MODE& mode )
- {
- if (game == true) {
- switch( mode )
- {
- case quit : break;
- case goLeft:
- FSOUND_PlaySound(FSOUND_FREE, tetris.sound_bloc_go_left_user); // on joue le son qui correspond au fait que le joueur souhaite déplacer le bloc à gauche
- GoLeft();
- break;
- case goRight:
- FSOUND_PlaySound(FSOUND_FREE, tetris.sound_bloc_go_right_user); // on joue le son qui correspond au fait que le joueur souhaite déplacer le bloc à droite
- GoRight();
- break;
- case turnRight:
- FSOUND_PlaySound(FSOUND_FREE, tetris.sound_bloc_rotate_right); // on joue le son qui correspond à la rotation du bloc
- currentBloc.rotationRight();
- break;
- case turnLeft:
- FSOUND_PlaySound(FSOUND_FREE, tetris.sound_bloc_rotate_right); // on joue le son qui correspond à la rotation du bloc
- currentBloc.rotationLeft();
- break;
- case goDown:
- FSOUND_PlaySound(FSOUND_FREE, tetris.sound_bloc_go_down_user); // on joue le son qui correspond au fait que le joueur souhaite faire descendre le bloc
- GoDown();
- break;
- case goUp:
- GoUp();
- break;
- }
-
- if ( !board.isMouvementValid( tetris.posX, tetris.posY, currentBloc ) )
- {
- switch( mode )
- {
- case goLeft:
- FSOUND_PlaySound(FSOUND_FREE, tetris.sound_bloc_go_left_user); // on joue le son qui correspond au fait que le joueur souhaite déplacer le bloc à gauche
- GoRight();
- break;
- case goRight:
- FSOUND_PlaySound(FSOUND_FREE, tetris.sound_bloc_go_right_user); // on joue le son qui correspond au fait que le joueur souhaite déplacer le bloc à droite
- GoLeft();
- break;
- case turnRight:
- FSOUND_PlaySound(FSOUND_FREE, tetris.sound_bloc_rotate_right); // on joue le son qui correspond à la rotation du bloc
- currentBloc.rotationLeft();
- userMode = none;
- break;
- case goDown:
- GoUp();
- board.addPiece( tetris.posX, tetris.posY, currentBloc );
- currentBloc = nextBloc;
- nextBloc = blocs[ rand() % blocs.size() ];
- tetris.posY = tetris.init_posY;
- tetris.posX = tetris.init_posX;
- int result = board.reduce();
- if (result == 2) {
- SDL_RemoveTimer(timer_MoveBloc_auto); // Arrêt du Timer
- GAMES_MODE tmp = goDown;
- timer_MoveBloc_auto = SDL_AddTimer(1000 / tetris.level, MoveBloc_auto, &tmp); // Démarrage du Timer
- FSOUND_PlaySound(FSOUND_FREE, tetris.sound_level_up); // on joue le son pour dire que le bloc à été posé
- } else if (result == 1) {
- FSOUND_PlaySound(FSOUND_FREE, tetris.sound_line_completed); // on joue le son pour dire que le bloc à été posé
- } else if (result == 0 ) {
- FSOUND_PlaySound(FSOUND_FREE, tetris.sound_bloc_is_fixed); // on joue le son pour dire que le bloc à été posé
- }
- userMode = none; // On arrête de descendre
- // pour une nouvelle pièce
- break;
- }
- }
- }
-
- if ( mode == turnRight ) userMode = none; // On évite de tourner en rond en continue
- if ( mode == goLeft ) userMode = none;
- if ( mode == goRight ) userMode = none;
- if ( mode == goDown ) userMode = none;
- }
-
-
- ########TETRIS.H########
- #include <SDL/SDL.h> // librairie SDL qui gère l'affichage
- #include <SDL/SDL_ttf.h> // librairie SDL_TTF qui gère l'affichage de texte
- #include <FMOD/fmod.h> // librairie FMOD qui gère le son
-
- #include <iostream>
- #include <fstream>
-
- #include <vector>
- #include <stdexcept> // pour la gestion des erreurs
- #include <stdlib.h>
-
- #include <string>
-
- using namespace std;
-
- // ------------------- Déclarations des constantes (options du jeu)
- struct options
- {
- int board_size_x;
- int board_size_y;
-
- int case_unit;
- int board_width;
- int board_height;
- int grid_width;
-
- int next_bloc_preview_x;
- int next_bloc_preview_y;
- int next_bloc_preview_size_x;
- int next_bloc_preview_size_y;
- int next_bloc_preview_width;
- int next_bloc_preview_height;
-
- int right_panel_width;
-
- int bloc_border_width;
- Uint32 bloc_border_color;
-
- int bloc_number;
- int special_bloc_number;
-
- int window_width;
- int window_height;
- char* window_title;
-
- int score;
- int lines;
- int line_number_to_level_up;
- int level;
-
- int init_posX;
- int init_posY;
- int posX;
- int posY;
-
- Uint32 background_color;
- Uint32 matrice_color;
- Uint32 tetrion_color;
- Uint32 grid_color;
-
- FSOUND_SAMPLE *sound_bloc_rotate_right;
- FSOUND_SAMPLE *sound_bloc_rotate_left;
- FSOUND_SAMPLE *sound_bloc_go_down;
- FSOUND_SAMPLE *sound_bloc_go_down_user;
- FSOUND_SAMPLE *sound_bloc_go_up_user;
- FSOUND_SAMPLE *sound_bloc_go_up;
- FSOUND_SAMPLE *sound_bloc_go_right_user;
- FSOUND_SAMPLE *sound_bloc_go_left_user;
-
- FSOUND_SAMPLE *sound_line_completed;
- FSOUND_SAMPLE *sound_level_up;
- FSOUND_SAMPLE *sound_loose_game;
- FSOUND_SAMPLE *sound_new_game;
-
- FSOUND_SAMPLE *sound_bloc_is_fixed;
-
- FSOUND_SAMPLE *sound_three;
- FSOUND_SAMPLE *sound_two;
- FSOUND_SAMPLE *sound_one;
- FSOUND_SAMPLE *sound_go;
-
- FSOUND_STREAM *musique;
-
- };
- options tetris;
-
-
- // -------------------
- enum GAMES_MODE { none, quit, turnRight, turnLeft, goDown, goUp, goRight, goLeft };
- GAMES_MODE userMode = none;
-
- bool pause = false;
-
- #include "bloc.h"
- vector<Bloc> blocs;
- vector<Bloc> special_blocs;
-
- Bloc currentBloc; // défini la variable qui contient le bloc qui descend
- Bloc nextBloc; // défini la variable qui contient le bloc suivant (afficher en aperçu)
-
-
- #include "board.h"
- Board board; // Initialise le tableau de jeu (objet voir 'board.h')
-
- SDL_Surface* screen; // la fenêtre
- SDL_Surface* background; // le fond de la fenêtre
- SDL_Surface* matrice; // la matrice (zone de jeu)
- SDL_Surface* grid; // la grille de la matrice
- SDL_Surface* previewBloc; // la zone d'aperçu du bloc suivant
-
- int scoreMax = 0, lineMax = 0;
-
- SDL_TimerID timer_MoveBloc_auto; // Variable pour stocker le numéro du Timer pout bouger le bloc automatiquement
-
- int game = false; // variable boolean qui détermine si une partie est en cours ou non
-
- TTF_Font* police = NULL;
- TTF_Font* police_m = NULL;
-
-
- void GoDown() { ++tetris.posY; }
- void GoUp() { --tetris.posY; }
- void GoLeft() { --tetris.posX; }
- void GoRight() { ++tetris.posX; }
-
-
- //* Prototypes des fonction de tetris.cpp
- void DisplayNumber( SDL_Surface* screen, SDL_Surface* tuiles, int x, int y, int s, int taille );
- void MoveBloc( GAMES_MODE& mode );
- Uint32 MoveBloc_auto( Uint32 intervalle, void *param ); // Timer pour le mouvement automatique du bloc
- void draw_surface (SDL_Surface* src, int X_ori, int Y_ori, int srcWidth, int srcHeight, SDL_Surface* dest, int posX_onDest, int posY_onDest, Uint32 color = 0);
- void update_surface (SDL_Surface* surface);
- void init_blocs();
- void init_colors(SDL_Surface* screen);
- void init_options();
- void add_bloc(int blocMaxWidth, string blocShape, int redRate = 256, int greenRate = 256, int blueRate = 256);
- void add_special_bloc(int blocMaxWidth, string blocShape, int redRate = 256, int greenRate = 256, int blueRate = 256);
- bool save_options(string filename);
- int update_game();
- void quit_game();
- void new_game();
- void end_game(bool loose_game = false);
- void show_grid();
- void show_text (char* text,TTF_Font* font, SDL_Surface* dest, int posX = 0, int posY = 0, int redRate = 0, int greenRate = 0, int blueRate = 0, int alpha = 255);
- SDL_Surface* generate_random_bmp_tuiles (bool saveBMP = false);
- void init_window_style();
- bool get_blocs_by_file(bool get_special_blocs = false);
- //*/
-
-
-
- ########BLOC.H########
-
- // ----------------------------------------------------
- class Bloc
- {
- public:
- Bloc ();
- Bloc( int, int, const char*, int redRate = (rand() % 256), int greenRate = (rand() % 256), int blueRate = (rand() % 256), const char* tuile_image = NULL );
-
- void display( SDL_Surface*, int, int ) const;
-
- void rotationRight();
- void rotationLeft();
-
- int index() const { return index_; }
- int size() const { return size_; }
- SDL_Surface* get_tuile() const { return tuile; }
- int get( int x, int y ) const { return data_[ x * size() + y ]; }
-
-
- private:
- int index_;
- int redRate_;
- int greenRate_;
- int blueRate_;
- SDL_Surface* tuile;
- int size_; // nb de lignes/colonne de la matrice du bloc
- std::vector<int> data_;
- };
-
-
- Bloc::Bloc() {
- }
- // ----------------------------------------------------
- Bloc::Bloc( int c, int s, const char* tab, int redRate, int greenRate, int blueRate, const char* tuile_image ) : index_( c ), size_( s ), redRate_( redRate ), greenRate_( greenRate ), blueRate_( blueRate )
- {
- for ( ; *tab; ++tab )
- data_.push_back( (*tab=='1')?1:0 );
-
- if (tuile_image == NULL) {
- SDL_Surface* blocDegrade;
- tuile = SDL_CreateRGBSurface(SDL_HWSURFACE, tetris.case_unit + 2*tetris.grid_width, tetris.case_unit + 2*tetris.grid_width, 32, 0, 0, 0, 0); // La bordure du bloc
- // Fait un dégradé de la couleur vers le noir
- for (int i = 0; i < (tetris.case_unit / 2); i++) { // On parcourt la tuile de l'extérieur vers l'intérieur, pixel par pixel et plus on va vers l'intérieur, plus on va ver le noir
- blocDegrade = SDL_CreateRGBSurface(SDL_HWSURFACE, tetris.case_unit - (2 * i), tetris.case_unit - (2 * i), 32, 0, 0, 0, 0); // La bordure du bloc
- // Les coordonnées de la surface sur la surface de destination
- SDL_Rect srcPosition; // définition de la variable
- srcPosition.x = i + tetris.grid_width; // abscisse
- srcPosition.y = i + tetris.grid_width; // ordonnée
- //Uint32 color = SDL_MapRGB(tuile->format, redRate_ - (i * (redRate_ / ((tetris.case_unit / 2) - 1))), greenRate_ - (i * (greenRate_ / ((tetris.case_unit / 2) - 1))), blueRate_ - (i * (blueRate_ / ((tetris.case_unit / 2) - 1)))); // dégradé vers le noir
- Uint32 color = SDL_MapRGB(tuile->format, redRate_ + (i * ((255 - redRate_) / ((tetris.case_unit / 2) - 1))), greenRate_ + (i * ((255 - greenRate_) / ((tetris.case_unit / 2) - 1))), blueRate_ + (i * ((255 - blueRate_) / ((tetris.case_unit / 2) - 1)))); // dégradé vers le blanc
- SDL_FillRect(blocDegrade, NULL, color); // Remplissage de la surface avec la couleur (color) passée en paramètre
- SDL_BlitSurface(blocDegrade, NULL, tuile, &srcPosition); // Collage de la surface sur la destination (dest)
-
- }
- } else {
- tuile = SDL_LoadBMP( tuile_image ); // chargement d'une image pour la tuiles
- }
- }
-
- // ----------------------------------------------------
- void Bloc::rotationRight()
- {
- for ( int i = 0; i < size() / 2 ; ++i )
- for ( int j = 0; j < ( size() + 1 )/ 2; ++j )
- {
- int iAux = size() - 1 - i;
- int jAux = size() - 1 - j;
- swap( data_[i * size() + j], data_[jAux * size() + i] );
- swap( data_[i * size() + j], data_[iAux * size() + jAux] );
- swap( data_[i * size() + j], data_[j * size() + iAux] );
- }
- }
-
- // ----------------------------------------------------
- void Bloc::rotationLeft()
- {
- for ( int i = 0; i < size() / 2 ; ++i )
- for ( int j = 0; j < ( size() + 1 )/ 2; ++j )
- {
- int iAux = size() - 1 - i;
- int jAux = size() - 1 - j;
- swap( data_[i * size() + j], data_[j * size() + iAux] );
- swap( data_[i * size() + j], data_[iAux * size() + jAux] );
- swap( data_[i * size() + j], data_[jAux * size() + i] );
- }
- }
-
- // ----------------------------------------------------
- void Bloc::display( SDL_Surface* screen, int x, int y ) const
- {
- for ( int i = 0; i < size(); ++i )
- for ( int j = 0; j < size(); ++j )
- if ( get( i, j ) )
- {
-
- SDL_Rect rectDest;
- rectDest.x = i * (tetris.case_unit + tetris.grid_width) + x * (tetris.case_unit + tetris.grid_width) + tetris.grid_width;
- rectDest.y = j * (tetris.case_unit + tetris.grid_width) + (y+1) * (tetris.case_unit + tetris.grid_width) + tetris.grid_width;
- rectDest.w = rectDest.h = 0;
-
- SDL_Rect rectSrc;
- rectSrc.x = tetris.grid_width;
- rectSrc.y = tetris.grid_width;
- rectSrc.w = rectSrc.h = tetris.case_unit;
-
- SDL_BlitSurface( tuile, &rectSrc, screen, &rectDest );
- }
- }
-
-
-
- ########BOARD.H########
-
-
- //--------------------------------------------
- //*
- class Board
- {
- public:
- Board()
- { // Initialisation des bordures
- }
- void display( SDL_Surface* ) const;
-
- bool isMouvementValid( int, int, const Bloc& ) const;
- void addPiece( int, int, const Bloc& );
-
- void init_board()
- {
- _board.resize(tetris.board_size_x); // redimensionne le tableau à sa taille réelle calculée dans l'initialisation des options
- for ( int x = 0; x < tetris.board_size_x; ++x ) {
- _board[x].resize(tetris.board_size_y);
- for ( int y = 0; y < tetris.board_size_y; ++y ) {
- _board[x][y] = ( x == 0 || x == tetris.board_size_x - 1 || y == tetris.board_size_y - 1 );
- }
- }
- }
-
- void reduceLine( int );
- int reduce();
-
- private:
- vector < vector<int> > _board; // utilisation d'un tableau multidimensionnel redimensionnable vector
- };
-
- // ----------------------------------------------------
- void Board::display( SDL_Surface* screen ) const
- {
- for ( int x = 1; x < tetris.board_size_x-1; ++x )
- for ( int y = 0; y < tetris.board_size_y-1; ++y )
- if ( _board[x][y] )
- {
- SDL_Rect rectDest;
- rectDest.x = x * (tetris.case_unit + tetris.grid_width);
- rectDest.y = (y+1)* (tetris.case_unit + tetris.grid_width);
- rectDest.w = rectDest.h = 0;
-
- SDL_Rect rectSrc;
- rectSrc.x = 0;
- rectSrc.y = 0;
- rectSrc.w = rectSrc.h = tetris.case_unit + (2*tetris.grid_width);
-
- SDL_BlitSurface( blocs[_board[x][y] - 1].get_tuile(), &rectSrc, screen, &rectDest );
- }
- }
-
- // ----------------------------------------------------
- bool Board::isMouvementValid( int posX, int posY, const Bloc& bloc ) const
- {
- for ( int x = posX; x < posX + bloc.size(); ++x )
- for ( int y = posY; y < posY + bloc.size(); ++y )
- if ( bloc.get( x - posX, y - posY ) && _board[x][y] )
- return false;
- return true;
- }
-
- // ----------------------------------------------------
- void Board::addPiece( int posX, int posY, const Bloc& bloc )
- {
- for ( int x = posX; x < posX + bloc.size(); ++x )
- for ( int y = posY; y < posY + bloc.size(); ++y )
- if ( bloc.get( x - posX, y - posY ) )
- _board[x][y] = bloc.index() + 1;
- }
-
- // ----------------------------------------------------
- int Board::reduce()
- {
- int addedLine = 0;
- for ( int y = 1; y < tetris.board_size_y - 1 ; ++y )
- {
- bool lineFull = true;
- for ( int x = 1; ( x < tetris.board_size_x - 1 ) && lineFull; ++x )
- if ( !_board[x][y] ) lineFull = false;
-
- if ( lineFull )
- {
- ++addedLine; // Une ligne suplémentaire
- for ( int z = y; z > 1 ; --z )
- for ( int x = 1; x < tetris.board_size_x - 1; ++x )
- _board[x][z] = _board[x][z-1];
-
- for ( int x = 1; x < tetris.board_size_x - 1; ++x )
- _board[x][0] = 0;
- }
- }
-
- tetris.lines += addedLine;
- if (tetris.level < ( tetris.lines / tetris.line_number_to_level_up ) + 1) {
- tetris.level++; // Un niveau supplémentaire
- tetris.score += (tetris.level * 100) + (tetris.level * min( 4, addedLine ) + addedLine) * 150; // Un point pour le niveau
- return 2;
- }
- if (addedLine > 0) {
- tetris.score += (tetris.level * min( 4, addedLine ) + addedLine) * 150; // Un point pour le niveau
- return 1;
- }
- return 0;
- }
########TETRIS.CPP########
#include "tetris.h"
// Fonction principale ----------------------------------------------------------------------------------------------------
int main( int, char** ) try
{
srand( time(NULL) ); // Randomize
// Initialise l'affichage (librairie SDL)
if ( SDL_Init( SDL_INIT_VIDEO | SDL_INIT_TIMER )== -1 )
throw runtime_error( SDL_GetError() );
// initialise la librairie qui gère le son (Fmod)
if ( FSOUND_Init(44100, 32, 0) == -1 )
throw runtime_error( "FMOD n'a pas pu s'initialiser" );
// initialise la librairie qui gère l'affichage de texte
if ( TTF_Init() == -1 ) // si la lib ne s'initialise pas...
throw runtime_error( TTF_GetError() ); // on arrête le programme en renvoyant l'erreur
init_options(); // appel de la fonction qui initialise toutes les variables du jeu
police = TTF_OpenFont("fonts/courbd.ttf", tetris.case_unit - 4); // on charge la police (le fichier doit obligatoirement exister !!)
if (!police) // si il y a une erreur dans le chargement de la police...
throw runtime_error( TTF_GetError() ); // on arrête le programme en renvoyant l'erreur
police_m = TTF_OpenFont("fonts/courbd.ttf", 15); // on charge la police (ici la taille est plus petite) (le fichier doit obligatoirement exister !!)
/* jouer un son court avec FMOD
FSOUND_SAMPLE *grudge = NULL;
grudge = FSOUND_Sample_Load(FSOUND_FREE, "sounds/the grudge.mp3", 0, 0, 0);
FSOUND_PlaySound(FSOUND_FREE, grudge);
//*/
/* jouer un son long (musique) avec FMOD
FSOUND_STREAM *musique = NULL;
FSOUND_Stream_SetLoopCount(musique, -1); // répétition à l'infini
//musique = FSOUND_Stream_Open("musics/Gabry Ponte Dance - Tetris RMX.MP3", FSOUND_LOOP_NORMAL, 110000, 219500); // on charge la musique
musique = FSOUND_Stream_Open("musics/Gabry Ponte Dance - Tetris RMX.MP3", FSOUND_LOOP_NORMAL, 5 * 109500, 20 * 219500); // on charge la musique
//FSOUND_Stream_Play(FSOUND_FREE, musique); // on lit la musique
//FSOUND_Stream_Stop(musique); // Arrêt de la musique
//FSOUND_Stream_Close(musique); // On libère la mémoire (décharge la musique de la mémoire)
//*/
/* Faire une pause avec FMOD
// remplacer FSOUND_ALL par le numéro du canal à mettre en pause
if (FSOUND_GetPaused(0)) // Si le canal 0 est en pause
FSOUND_SetPaused(FSOUND_ALL, 0); // On enlève la pause de tous les canaux
else // Sinon, elle est en cours de lecture
FSOUND_SetPaused(FSOUND_ALL, 1); // On met en pause tous les canaux
//*/
/* jouer un midi
FMUSIC_MODULE *musique = NULL;
musique = FMUSIC_LoadSong("musics/tetris.mid");
FMUSIC_SetLooping(musique, 1); // répétition à l'infini
FMUSIC_PlaySong(musique);
FMUSIC_SetMasterVolume(musique, 120); // volume
//FMUSIC_StopSong(musique); // stopper la lecture du midi
//FMUSIC_FreeSong(musique); // on libère la mémoire (décharge le midi de la mémoire)
//*/
/* mettre en pause un midi
if (FMUSIC_GetPaused(musique)) // Si la chanson est en pause
FMUSIC_SetPaused(musique, 0); // On enlève la pause
else // Sinon, elle est en cours de lecture
FMUSIC_SetPaused(musique, 1); // On active la pause
//*/
FSOUND_SetVolume(FSOUND_ALL, 255); // change le volume de tous les canaux ( de 0 à 255)
screen = SDL_SetVideoMode( tetris.board_width + tetris.right_panel_width + tetris.grid_width, tetris.board_height + (tetris.case_unit + tetris.grid_width) + tetris.grid_width, 32, /*SDL_FULLSCREEN | */SDL_HWSURFACE | SDL_DOUBLEBUF ); // création de la fenêtre
if ( !screen ) // Si il y a une erreur sur la création de la fenêtre... on envoie un runtime error (erreur d'éxécution)
throw runtime_error( SDL_GetError() );
SDL_EnableKeyRepeat(500,30); // active la répétition des touches du clavier (rester appuyer pour faire plusieurs fois la même action)
init_colors(screen); // on initialise les couleurs
init_blocs(); // on initialise les blocs
SDL_WM_SetCaption( tetris.window_title, 0 ); // Attribut le titre de la fenêtre (voir 'init_options()')
SDL_WM_SetIcon( SDL_LoadBMP( "icon.bmp" ), 0 ); // Chargement de l'icône de la fenêtre
init_window_style();
new_game();
SDL_Event event;
//while( SDL_PollEvent( &event ) )
while( SDL_WaitEvent( &event ) )
{
switch( event.type )
{
case SDL_KEYDOWN:
switch( event.key.keysym.sym )
{
// -- MOUVEMENT --
case SDLK_RIGHT:
userMode = goRight; // déplacement du bloc à droite
break;
case SDLK_LEFT:
userMode = goLeft; // déplacement du bloc à gauche
break;
case SDLK_DOWN:
userMode = goDown; // déplacement du bloc en bas
break;
case SDLK_UP:
//userMode = goUp; break;
//FSOUND_PlaySound(FSOUND_FREE, tetris.bloc_is_fixed); break; // on joue le son qui correspond au fait que le joueur souhaite faire descendre le bloc
case SDLK_KP0:
userMode = turnRight; // rotation du bloc
break;
//* SONS BONUS !!!!
case SDLK_KP1:
FSOUND_PlaySound(FSOUND_FREE, tetris.sound_one);
break;
case SDLK_KP2:
FSOUND_PlaySound(FSOUND_FREE, tetris.sound_two);
break;
case SDLK_KP3:
FSOUND_PlaySound(FSOUND_FREE, tetris.sound_three);
break;
case SDLK_KP4:
FSOUND_PlaySound(FSOUND_FREE, tetris.sound_go);
break;
case SDLK_RCTRL:
// remplacer FSOUND_ALL par le numéro du canal à mettre en pause
if (FSOUND_GetPaused(0)) // Si le canal 0 est en pause
FSOUND_SetPaused(FSOUND_ALL, 0); // On enlève la pause de tous les canaux
else // Sinon, elle est en cours de lecture
FSOUND_SetPaused(FSOUND_ALL, 1); // On met en pause tous les canaux
FSOUND_Stream_Play(FSOUND_FREE, tetris.musique);
break;
case SDLK_RSHIFT:
FSOUND_Stream_Stop(tetris.musique); // Arrêt de la musique
FSOUND_SetPaused(FSOUND_ALL, 1); // On met la pause
break;
//*/
case SDLK_F2: new_game(); break;
// -- PAUSE --
case SDLK_SPACE:
case SDLK_p: pause = !pause; break;
// -- EXIT --
case SDLK_ESCAPE: userMode = quit; break;
}
break;
case SDL_KEYUP: userMode = none; break;
case SDL_QUIT: userMode = quit; continue;
}
if ( pause )
{
update_surface(screen); // Mise à jour de l'écran
continue;
}
MoveBloc( userMode );
update_game();
}
quit_game();
return 0;
}
catch( exception& e )
{
ofstream cerr( "program_error.txt" );
cerr << e.what();
return 1;
}
// Fonction d'initialisation des variables principales du jeu ----------------------------------------------------------------------------------------------------
void init_options()
{
tetris.case_unit = 25; // la longueur en pixel du côté du carré qui forme une tuile (la tuile est ce qui compose un bloc ce sont les cases unitaires...)
tetris.board_size_x = 10 + 2; // la largeur de la matrice (zone de jeu) en 'case_unit' + les 2 côtés qui forment les bords (droit et gauche)
tetris.board_size_y = 22 + 1; // la hauteur de la matrice en 'case_unit' + le bas de la zone de jeu (le sol)
tetris.grid_width = 1; // la largeur en pixel de la grille, du cadrillage
tetris.line_number_to_level_up = 10; // nombre de lignes à compléter pour monter d'un niveau (mettez la valeur que vous souhaitez, la valeur officielle est 10 lignes pour monter d'un niveau, mais si vous souhaitez que vos parties durent plus longtemps mettez 20)
//* chargement des options dans le fichier de configuration
ifstream fichier;
fichier.open("options.txt", ios::in);
if(fichier)
{
fichier >> tetris.case_unit >> tetris.board_size_x >> tetris.board_size_y >> tetris.grid_width >> tetris.line_number_to_level_up;
/*
vector <string> file_content; // variable qui contiendra le fichier (tableau avec une ligne par entrée du tableau)
string ligne;
while(getline(fichier, ligne)) {
file_content.push_back( ligne );
}
//*/
}
else
{
throw runtime_error( "Impossible d'ouvrir le fichier de configuration !" );
cout << "Impossible d'ouvrir le fichier de configuration !" << endl;
}
fichier.close();
//*/
tetris.init_posY = 0; // position initiale d'un nouveau bloc (ordonnée)
tetris.init_posX = (tetris.board_size_x - 2) / 2; // position initiale d'un nouveau bloc (abscisse) : ici un bloc nouveau apparaîtra toujours centré dans la zone de jeu (-2 pour les bordures de droite et gauche)
tetris.bloc_number = 0; // initialise le nombre de blocs (laissé à 0 car cette variable est automatiquement incrémenté lors de l'ajout de bloc avec la fonction 'add_bloc()')
tetris.special_bloc_number = 0; // initialise le nombre de blocs spéciaux (laissé à 0 car cette variable est automatiquement incrémenté lors de l'ajout de bloc avec la fonction 'add_special_bloc()')
tetris.board_width = tetris.board_size_x * (tetris.case_unit + tetris.grid_width); // calcul de la largeur de la matrice en pixel
tetris.board_height = tetris.board_size_y * (tetris.case_unit + tetris.grid_width); // calcul de la hauteur de la matrice en pixel
tetris.right_panel_width = (tetris.case_unit + tetris.grid_width) * 10; // taille de la zone à droite de la matrice en pixel (ici la zone fait 10 tuiles de largeur)
tetris.next_bloc_preview_x = tetris.board_width; // abscisse du coin supérieur gauche de la zone d'aperçu du bloc suivant (ici, c'est juste à côté de la matrice)
tetris.next_bloc_preview_y = 0; // ordonée du coin supérieur gauche de la zone d'aperçu du bloc suivant (ici, c'est tout en haut)
tetris.next_bloc_preview_size_x = 5; // largeur en 'case_unit' de la zone d'aperçu du bloc suivant
tetris.next_bloc_preview_size_y = 5; // hauteur en 'case_unit' de la zone d'aperçu du bloc suivant
tetris.next_bloc_preview_width = tetris.next_bloc_preview_size_x * (tetris.case_unit + tetris.grid_width); // largeur en pixel de la zone d'aperçu du bloc suivant
tetris.next_bloc_preview_height = tetris.next_bloc_preview_size_y * (tetris.case_unit + tetris.grid_width); // hauteur en pixel de la zone d'aperçu du bloc suivant
tetris.window_title = "* Tetris V2 * ...du 18/08/2007 15h45..."; // titre de la fenêtre
tetris.musique = FSOUND_Stream_Open("musics/Gabry Ponte Dance - Tetris RMX.MP3", FSOUND_LOOP_NORMAL, 5 * 109500, 20 * 219500); // on charge la musique
FSOUND_Stream_SetLoopCount(tetris.musique, 0); // répétition à l'infini
FSOUND_SetPaused(FSOUND_ALL, 1); // On met la pause
tetris.sound_bloc_rotate_right = FSOUND_Sample_Load(FSOUND_FREE, "sounds/user_rotate_bloc_at_right.sound", 0, 0, 0);
tetris.sound_bloc_rotate_left = FSOUND_Sample_Load(FSOUND_FREE, "sounds/user_rotate_bloc_at_left.sound", 0, 0, 0);
tetris.sound_bloc_go_right_user = FSOUND_Sample_Load(FSOUND_FREE, "sounds/user_move_bloc_at_right.sound", 0, 0, 0);
tetris.sound_bloc_go_left_user = FSOUND_Sample_Load(FSOUND_FREE, "sounds/user_move_bloc_at_left.sound", 0, 0, 0);
tetris.sound_bloc_go_down_user = FSOUND_Sample_Load(FSOUND_FREE, "sounds/when_bloc_go_down_by_user.sound", 0, 0, 0);
tetris.sound_bloc_go_up_user = FSOUND_Sample_Load(FSOUND_FREE, "sounds/when_bloc_go_up_by_user.sound", 0, 0, 0);
tetris.sound_bloc_go_down = FSOUND_Sample_Load(FSOUND_FREE, "sounds/when_bloc_go_down_auto.sound", 0, 0, 0);
tetris.sound_bloc_go_up = FSOUND_Sample_Load(FSOUND_FREE, "sounds/when_bloc_go_up_auto.sound", 0, 0, 0);
tetris.sound_bloc_is_fixed = FSOUND_Sample_Load(FSOUND_FREE, "sounds/when_bloc_is_fixed_on_the_floor.sound", 0, 0, 0);
tetris.sound_line_completed = FSOUND_Sample_Load(FSOUND_FREE, "sounds/when_line_is_completed.sound", 0, 0, 0);
tetris.sound_level_up = FSOUND_Sample_Load(FSOUND_FREE, "sounds/level_up.sound", 0, 0, 0);
tetris.sound_loose_game = FSOUND_Sample_Load(FSOUND_FREE, "sounds/loose_game.sound", 0, 0, 0);
tetris.sound_new_game = FSOUND_Sample_Load(FSOUND_FREE, "sounds/new_game.sound", 0, 0, 0);
//* Sons bonus (3...2...1...GO)
tetris.sound_three = FSOUND_Sample_Load(FSOUND_FREE, "sounds/three.ogg", 0, 0, 0);
tetris.sound_two = FSOUND_Sample_Load(FSOUND_FREE, "sounds/two.ogg", 0, 0, 0);
tetris.sound_one = FSOUND_Sample_Load(FSOUND_FREE, "sounds/one.ogg", 0, 0, 0);
tetris.sound_go = FSOUND_Sample_Load(FSOUND_FREE, "sounds/go.ogg", 0, 0, 0);
//*/
}
// Fonction d'initialisation des couleurs du jeu ----------------------------------------------------------------------------------------------------
void init_colors (SDL_Surface* screen)
{
tetris.bloc_border_color = SDL_MapRGB(screen->format, 0, 0, 0); // couleur de bordure d'un bloc (a utilisé uniquement sans la génération automatique du dégradé sur les bloc : voir code commenté dans la fonction addBloc)
tetris.background_color = SDL_MapRGB(screen->format, 212, 208, 200); // On créé une variable qui contient la couleur du background (fond d'écran) en format RGB ou RVB (Rouge, Vert, Bleu)
tetris.matrice_color = SDL_MapRGB(screen->format, 255, 255, 255); // On créé une variable qui contient la couleur du background (fond d'écran) en format RGB ou RVB (Rouge, Vert, Bleu)
tetris.grid_color = SDL_MapRGB(screen->format, 150, 150, 150); // On créé une variable qui contient la couleur du background (fond d'écran) en format RGB ou RVB (Rouge, Vert, Bleu)
}
// Fonction d'initialisation des blocs utilisant la fonction addBloc ----------------------------------------------------------------------------------------------------
void init_blocs ()
{
if (!get_blocs_by_file(true)) { // Si l'initialisation par fichier de configuration a échouée, on créé les blocs
//*
add_special_bloc( 1, "1", 50, 50, 50 ); // bloc unitaire pour les bordures (tétrion)
//* blocs unitaires pour le fond aléatoire
add_special_bloc( 1, "1", 255, 0, 0 );
add_special_bloc( 1, "1", 51, 102, 255 );
add_special_bloc( 1, "1", 255, 220, 0 );
add_special_bloc( 1, "1", 255, 0, 255 );
add_special_bloc( 1, "1", 210, 210, 200 );
add_special_bloc( 1, "1", 0, 255, 0 );
add_special_bloc( 1, "1", 0, 0, 255 );
/*
for (int x = 0; x < 50; x++) // ajout de 50 blocs spéciaux unitaires dont la couleur est aléatoire
add_special_bloc( 1, "1" );
//*/
//*/
}
if (!get_blocs_by_file()) { // Si l'initialisation par fichier de configuration a échouée, on créé les blocs
//*
//* Blocs originaux
add_bloc( 4, "0010001000100010", 255, 0, 0 ); // barre I
add_bloc( 2, "1111", 51, 102, 255 ); // carré O
add_bloc( 3, "010111000", 153, 51, 0 ); // T
add_bloc( 3, "001111000", 255, 0, 255 ); // L
add_bloc( 3, "100111000", 200, 200, 200 ); // J couleur originale : le blanc
add_bloc( 3, "100110010", 0, 255, 0 ); // S
add_bloc( 3, "001011010", 0, 204, 255 ); // Z
//*/
/* blocs du tétris B
add_bloc( 1, "1"); // le point .
add_bloc( 2, "1011", 255, 220, 0 ); // mini L
//add_bloc( 3, "111010010" ); // T (grand)
//add_bloc( 3, "010111010" ); // +
add_bloc( 3, "010010010" ); // la barre de 3
add_bloc( 2, "0101" ); // la barre de 2
add_bloc( 3, "101111000" ); // la cuvette de 3
//*/
//*/
}
}
// Fonction appelée lors d'une nouvelle partie ----------------------------------------------------------------------------------------------------
void new_game()
{
if (game == true) // Si il y a une partie en cours...
end_game(); // on termine la partie
pause = false; // On enlève la pause au cas où elle serait activée
init_window_style(); // on réinitialise l'affichage de la fenêtre pour afficher un nouveau fond aléatoire
FSOUND_PlaySound(FSOUND_FREE, tetris.sound_new_game); // on joue le son qui correspond à une nouvelle partie
//* chargement du score maximal
ifstream scoreFile( "score.txt" ); // on ouvre le fichier qui contient le record
if ( scoreFile ) // si le fichier existe...
scoreFile >> scoreMax >> lineMax; // on met la première ligne du fichier comme score max et la deuxième ligne du fichier comme nombre de lignes max
//*/
board.init_board(); // Initialise le tableau de jeu (objet voir 'board.h')
currentBloc = blocs[ rand() % tetris.bloc_number ]; // On sélectionne un bloc au hasard pour le bloc courant
nextBloc = blocs[ rand() % tetris.bloc_number ]; // On sélectionne un bloc au hasard pour le prochain bloc
tetris.posX = tetris.init_posX; // On initialise la position du bloc à sa position initiale (abscisse)
tetris.posY = tetris.init_posY; // On initialise la position du bloc à sa position initiale (ordonnée)
tetris.score = 0; // initialise le score à 0 (laisser à 0 sinon vous triché :P)
tetris.lines = 0; // initialise le nombre de lignes complétées (laisser à 0, changer la valeur n'a aucune influence sur le score, c'est juste indicatif)
tetris.level = 1; // initialise le niveau on commence au niveau 1 et pas 0 sinon les blocs ne descendent pas ^^ (augmenter le niveau de départ d'une partie influe sur la vitesse de descente du bloc)
game = true; // On met true à la variable qui dit qu'une partie est en cours
SDL_Delay( 500 ); // On met en pause le programme pour une demie seconde pour donner le temps au joueur de se mettre en place (utile pour ceux qui ne connaissent pas par coeur le clavier :P)
//* On créé le timer pour la descente automatique du bloc
GAMES_MODE tmp = goDown;
timer_MoveBloc_auto = SDL_AddTimer(1000 / tetris.level, MoveBloc_auto, &tmp); // Démarrage du Timer
//*/
}
// Fonction appelée à la fin d'une partie ----------------------------------------------------------------------------------------------------
void end_game(bool loose_game)
{
//* Sauvegarde les informations de la dernière partie (un genre de log)
ofstream cout( "last_game.txt");
time_t ltime;
struct tm *today;
time( <ime );
today = localtime( <ime );
char tmpbuf[128];
strftime(tmpbuf, 128, "%A %d %B %Y à %H:%M:%S", today);
cout << "----------------------------------------------------------------------------------------------------" << endl;
cout << "Partie terminée le " << tmpbuf << endl;
cout << "Score : " << tetris.score << endl;
cout << "Lignes : " << tetris.lines << endl;
cout << "Niveau : " << tetris.level << endl;
//*/
//* Sauvegarde du score maximal (meilleur score)
if (tetris.score > scoreMax) { // Si le score de la partie est supérieur au score maximum atteint...
ofstream scoreFile( "score.txt" );
scoreFile << tetris.score << endl << tetris.lines; // on sauvegarde le score actuel et son nombre de lignes
}
//*/
if (loose_game == true) // si la partie est terminé parce que le joueur vient de perdre...
FSOUND_PlaySound(FSOUND_FREE, tetris.sound_loose_game); // on joue le son qui correspond à la perte de la partie
SDL_RemoveTimer(timer_MoveBloc_auto); // Arrêt du Timer qui fait la descente automatique du bloc
game = false;
}
int update_game()
{
draw_surface( matrice, 0, 0, matrice->w, matrice->h, background, tetris.case_unit + tetris.grid_width, tetris.case_unit + tetris.grid_width ); // Effacement de l'écran
//SDL_BlitSurface( background, 0, screen, 0 ); // Effacement de l'écran
//update_surface(background);
//update_surface(matrice);
draw_surface(background, 0, 0, background->w, background->h, screen, 0, 0);
board.display( screen ); // Affichage du fond d'écran
currentBloc.display( screen, tetris.posX, tetris.posY ); // Affichage de la pièce courante
nextBloc.display( screen, tetris.next_bloc_preview_x / (tetris.case_unit + tetris.grid_width), tetris.next_bloc_preview_y / (tetris.case_unit + tetris.grid_width)); // Affichage de la prochaine pièce
// Affichage du niveau
char level_str[100];
sprintf(level_str, "Niveau = %d", tetris.level);
show_text(level_str, police, screen, tetris.board_width + tetris.grid_width, (tetris.next_bloc_preview_size_y + 1 + 1) * (tetris.case_unit + tetris.grid_width), 0, 0, 0);
// Affichage du score
char score_str[100];
sprintf(score_str, "Score = %d", tetris.score);
show_text(score_str, police, screen, tetris.board_width + tetris.grid_width, (tetris.next_bloc_preview_size_y + 1 + 2) * (tetris.case_unit + tetris.grid_width), 0, 0, 0);
// Affichage des lignes
char lines_str[100];
sprintf(lines_str, "Lignes = %d", tetris.lines);
show_text(lines_str, police, screen, tetris.board_width + tetris.grid_width, (tetris.next_bloc_preview_size_y + 1 + 3) * (tetris.case_unit + tetris.grid_width), 0, 0, 0);
show_text("F2 = Nouvelle partie", police_m, screen, tetris.board_width + tetris.grid_width, (tetris.next_bloc_preview_size_y + 1 + 4 + 1) * (tetris.case_unit + tetris.grid_width), 0, 0, 0);
show_text("Espace = Pause", police_m, screen, tetris.board_width + tetris.grid_width, (tetris.next_bloc_preview_size_y + 1 + 4 + 2) * (tetris.case_unit + tetris.grid_width), 0, 0, 0);
show_text("Echap = Quitter", police_m, screen, tetris.board_width + tetris.grid_width, (tetris.next_bloc_preview_size_y + 1 + 4 + 3) * (tetris.case_unit + tetris.grid_width), 0, 0, 0);
char highScore[100];
sprintf(highScore, "Meilleur score = %d", scoreMax);
show_text(highScore, police_m, screen, tetris.board_width + tetris.grid_width, (tetris.next_bloc_preview_size_y + 1 + 4 + 5) * (tetris.case_unit + tetris.grid_width), 0, 0, 0);
update_surface(screen); // Mise à jour de l'écran
if ( !board.isMouvementValid( tetris.posX, tetris.posY, currentBloc ) && game == true ) // partie terminée
end_game(true);
if (userMode == quit) {
quit_game();
return 0;
}
}
// Fonction d'ajout de bloc : Si les taux des trois couleurs Rouge Vert Bleu ne sont pas spécifié, il y a génération aléatoire du taux de chaque couleur : voir le prototype de la fonction addBloc dans 'tetris.h' ----------------------------------------------------------------------------------------------------
void add_bloc(int blocMaxWidth, string blocShape, int redRate, int greenRate, int blueRate)
{
redRate = (redRate > 255) ? (rand() % 256) : redRate;
greenRate = (greenRate > 255) ? (rand() % 256) : greenRate;
blueRate = (blueRate > 255) ? (rand() % 256) : blueRate;
blocs.push_back( Bloc( tetris.bloc_number, blocMaxWidth, blocShape.c_str(), redRate, greenRate, blueRate ) ); // ajout du bloc avec dégradé vers le noir
tetris.bloc_number++;
}
void add_special_bloc(int blocMaxWidth, string blocShape, int redRate, int greenRate, int blueRate)
{
redRate = (redRate > 255) ? (rand() % 256) : redRate;
greenRate = (greenRate > 255) ? (rand() % 256) : greenRate;
blueRate = (blueRate > 255) ? (rand() % 256) : blueRate;
special_blocs.push_back( Bloc( tetris.special_bloc_number, blocMaxWidth, blocShape.c_str(), redRate, greenRate, blueRate ) ); // ajout du bloc avec dégradé vers le noir
tetris.special_bloc_number++;
}
bool get_blocs_by_file (bool get_special_blocs)
{
//* chargement des blocs à partir du fichier
ifstream blocs_file;
if (!get_special_blocs)
blocs_file.open("blocs.txt", ios::in);
else
blocs_file.open("special_blocs.txt", ios::in);
int len, redRate, greenRate, blueRate;
string shape;
vector <string> file_content; // variable qui contiendra le fichier (tableau avec une ligne par entrée du tableau)
string ligne, tmp;
int i = 0, j = 0, last_pos = 0, num = 0;
bool no_error = false;
if(blocs_file)
{
while(getline(blocs_file, ligne)) {
no_error = false;
file_content.push_back( ligne );
num = 0;
last_pos = 0;
if (file_content[i].substr( 0, 2) != "//") {
for (j = 0; j < file_content[i].size(); j++) {
if (file_content[i].substr( j, 1 ) == ";") {
tmp = file_content[i].substr( last_pos, j - last_pos );
last_pos = j + 1;
num++;
switch (num) {
case 1:
len = atoi(tmp.c_str());
break;
case 2:
shape = tmp.c_str();
break;
case 3:
redRate = atoi(tmp.c_str());
break;
case 4:
greenRate = atoi(tmp.c_str());
break;
case 5:
blueRate = atoi(tmp.c_str());
no_error = true;
break;
}
}
}
if (no_error)
if (!get_special_blocs)
add_bloc( len, shape, redRate, greenRate, blueRate );
else
add_special_bloc( len, shape, redRate, greenRate, blueRate );
}
i++;
}
}
else
{
return false;
}
blocs_file.close();
return true;
//*/
}
void update_surface (SDL_Surface* surface)
{
SDL_UpdateRect( surface, 0, 0, surface->w, surface->h );
SDL_Flip(surface);
}
// Fonction d'affichage de surface sur une surface de destination ----------------------------------------------------------------------------------------------------
void draw_surface (SDL_Surface* src, int X_ori, int Y_ori, int srcWidth, int srcHeight, SDL_Surface* dest, int posX_onDest, int posY_onDest, Uint32 color)
{
// Les coordonnées de la surface sur la surface de destination
SDL_Rect srcPositionOnDestination; // définition de la variable
srcPositionOnDestination.x = posX_onDest; // abscisse
srcPositionOnDestination.y = posY_onDest; // ordonnée
SDL_Rect srcPosition;
srcPosition.x = X_ori;
srcPosition.y = Y_ori;
srcPosition.w = srcWidth;
srcPosition.h = srcHeight;
if (color != 0) {
SDL_FillRect(src, NULL, color); // Remplissage de la surface avec la couleur (color) passée en paramètre
}
SDL_BlitSurface(src, &srcPosition, dest, &srcPositionOnDestination); // Collage de la surface (src) sur la destination (dest)
// SDL_Flip(dest);
}
void init_window_style ()
{
int i = 0; // variables pour les boucles
// Chargement du fond d'écran
SDL_Surface* random_background = generate_random_bmp_tuiles(); // génération aléatoire d'une image remplie de tuiles (special_blocs)
background = SDL_CreateRGBSurface(SDL_HWSURFACE, screen->w, screen->h, 32, 0, 0, 0, 0); // On créé une surface nommée background
SDL_FillRect(background, NULL, tetris.background_color); // Remplissage de la surface avec la couleur (color) passée en paramètre
draw_surface(random_background, 0, 0, random_background->w, random_background->h, background, 0, 0); // On dessine le background sur la fenêtre (screen)
//background = SDL_LoadBMP( "alea.bmp" ); // On charge une image de fond d'écran
draw_surface(background, 0, 0, background->w, background->h, screen, 0, 0); // On dessine le background sur la fenêtre (screen)
if ( !background ) // Si il y a une erreur sur la création du background... on envoie un runtime error (erreur d'éxécution)
throw runtime_error( SDL_GetError() );
// Chargement de la matrice (zone de jeu)
matrice = SDL_CreateRGBSurface(SDL_HWSURFACE, tetris.board_width - (2 * tetris.case_unit) - tetris.grid_width, tetris.board_height - tetris.case_unit, 32, 0, 0, 0, 0); // On créé une surface pour la matrice
draw_surface(matrice, 0, 0, matrice->w, matrice->h, background, tetris.case_unit + tetris.grid_width, tetris.case_unit + tetris.grid_width, tetris.matrice_color); // On dessine la matrice sur le fond d'écran
if ( !matrice )
throw runtime_error( SDL_GetError() );
//*/
//* Chargement du cadrillage
int numberLineY = tetris.board_size_y, numberLineX = tetris.board_size_y;
grid = SDL_CreateRGBSurface(SDL_HWSURFACE, matrice->w, matrice->h, 32, 0, 0, 0, 0); // On créé une surface pour la grille (grid)
SDL_FillRect(grid, NULL, tetris.matrice_color); // on remet la couleur de la matrice comme couleur de fond
SDL_Surface* gridX[numberLineX];
for (i = 0; i < numberLineX; i++) {
gridX[i] = SDL_CreateRGBSurface(SDL_HWSURFACE, numberLineX * (tetris.case_unit + tetris.grid_width), tetris.grid_width, 32, 0, 0, 0, 0); // On créé une surface pour la ligne
draw_surface(gridX[i], 0, 0, gridX[i]->w, gridX[i]->h, grid, 0, i*(tetris.case_unit + tetris.grid_width), tetris.grid_color); // On dessine la ligne (gridX[i]) sur la grille (grid)
if ( !gridX[i] )
throw runtime_error( SDL_GetError() );
}
SDL_Surface* gridY[numberLineY];
for (i = 0; i < numberLineY; i++) {
gridY[i] = SDL_CreateRGBSurface(SDL_HWSURFACE, tetris.grid_width, numberLineY * (tetris.case_unit + tetris.grid_width), 32, 0, 0, 0, 0); // On créé une surface pour la ligne
draw_surface(gridY[i], 0, 0, gridY[i]->w, gridY[i]->h, grid, i*(tetris.case_unit + tetris.grid_width), 0, tetris.grid_color); // On dessine la ligne (gridY[i]) sur la grille (grid)
if ( !gridY[i] )
throw runtime_error( SDL_GetError() );
}
draw_surface(grid, 0, 0, grid->w, grid->h, matrice, 0, 0);
//*/
//* Chargement du fond de la zone d'aperçu du bloc suivant
previewBloc = SDL_CreateRGBSurface(SDL_HWSURFACE, tetris.next_bloc_preview_width + tetris.grid_width, tetris.next_bloc_preview_height + tetris.grid_width, 32, 0, 0, 0, 0); // On créé une surface pour la grille (grid)
draw_surface(grid, 0, 0, grid->w, grid->h, previewBloc, 0, 0);
draw_surface(previewBloc, 0, 0, tetris.next_bloc_preview_width + tetris.grid_width, tetris.next_bloc_preview_height + tetris.grid_width, background, tetris.next_bloc_preview_x, tetris.next_bloc_preview_y + (tetris.case_unit + tetris.grid_width));
//*/
//* Chargement du tétrion (contour de la matrice)
for (i = 0; i < tetris.board_size_x; i++) {
draw_surface( special_blocs[0].get_tuile(), tetris.grid_width, tetris.grid_width, tetris.case_unit, tetris.case_unit, background, i * (tetris.case_unit + tetris.grid_width) + tetris.grid_width, tetris.grid_width);
draw_surface( special_blocs[0].get_tuile(), tetris.grid_width, tetris.grid_width, tetris.case_unit, tetris.case_unit, background, i * (tetris.case_unit + tetris.grid_width) + tetris.grid_width, tetris.board_height + tetris.grid_width);
}
for (i = 0; i < tetris.board_size_y; i++) {
draw_surface( special_blocs[0].get_tuile(), tetris.grid_width, tetris.grid_width, tetris.case_unit, tetris.case_unit, background, tetris.grid_width, i * (tetris.case_unit + tetris.grid_width) + tetris.grid_width);
draw_surface( special_blocs[0].get_tuile(), tetris.grid_width, tetris.grid_width, tetris.case_unit, tetris.case_unit, background, tetris.board_width - tetris.case_unit, i * (tetris.case_unit + tetris.grid_width) + tetris.grid_width);
}
//*/
//* Chargement du tétrion de la zone d'aperçu du bloc suivant
for (i = 0; i < tetris.next_bloc_preview_size_x; i++) {
draw_surface( special_blocs[0].get_tuile(), tetris.grid_width, tetris.grid_width, tetris.case_unit, tetris.case_unit, background, tetris.next_bloc_preview_x + i * (tetris.case_unit + tetris.grid_width) + tetris.grid_width, tetris.next_bloc_preview_y + tetris.grid_width);
draw_surface( special_blocs[0].get_tuile(), tetris.grid_width, tetris.grid_width, tetris.case_unit, tetris.case_unit, background, tetris.next_bloc_preview_x + i * (tetris.case_unit + tetris.grid_width) + tetris.grid_width, (tetris.next_bloc_preview_size_y + 1) * (tetris.case_unit + tetris.grid_width) + tetris.next_bloc_preview_y + tetris.grid_width);
}
for (i = 0; i < tetris.next_bloc_preview_size_y + 2; i++) { // + 2 pour le haut et le bas
draw_surface( special_blocs[0].get_tuile(), tetris.grid_width, tetris.grid_width, tetris.case_unit, tetris.case_unit, background, tetris.next_bloc_preview_x - tetris.case_unit, tetris.next_bloc_preview_y + i * (tetris.case_unit + tetris.grid_width) + tetris.grid_width);
draw_surface( special_blocs[0].get_tuile(), tetris.grid_width, tetris.grid_width, tetris.case_unit, tetris.case_unit, background, tetris.next_bloc_preview_x + tetris.next_bloc_preview_width + tetris.grid_width, tetris.next_bloc_preview_y + i * (tetris.case_unit + tetris.grid_width) + tetris.grid_width);
}
//*/
//* Chargement du tétrion de la zone d'affichage du score, des lignes et du niveau
for (i = 0; i < tetris.right_panel_width; i++) {
draw_surface( special_blocs[0].get_tuile(), tetris.grid_width, tetris.grid_width, tetris.case_unit, tetris.case_unit, background, i * (tetris.case_unit + tetris.grid_width) + tetris.grid_width + tetris.board_width, (tetris.next_bloc_preview_size_y + 1)*(tetris.case_unit + tetris.grid_width) + tetris.grid_width);
draw_surface( special_blocs[0].get_tuile(), tetris.grid_width, tetris.grid_width, tetris.case_unit, tetris.case_unit, background, i * (tetris.case_unit + tetris.grid_width) + tetris.grid_width + tetris.board_width, (tetris.next_bloc_preview_size_y + 1 + 4)*(tetris.case_unit + tetris.grid_width) + tetris.grid_width);
}
SDL_Surface* score_background = SDL_CreateRGBSurface(SDL_HWSURFACE, tetris.right_panel_width - tetris.grid_width, 3 * (tetris.case_unit + tetris.grid_width) - tetris.grid_width, 32, 0, 0, 0, 0); // On créé une surface pour la matrice
draw_surface( score_background, 0, 0, score_background->w, score_background->h, background, tetris.grid_width + tetris.board_width, (tetris.next_bloc_preview_size_y + 1 + 1)*(tetris.case_unit + tetris.grid_width) + tetris.grid_width, tetris.matrice_color);
//*/
//* Chargement du tétrion de la zone d'affichage des aides
for (i = 0; i < tetris.right_panel_width; i++) {
draw_surface( special_blocs[0].get_tuile(), tetris.grid_width, tetris.grid_width, tetris.case_unit, tetris.case_unit, background, i * (tetris.case_unit + tetris.grid_width) + tetris.grid_width + tetris.board_width, (tetris.next_bloc_preview_size_y + 1 + 4)*(tetris.case_unit + tetris.grid_width) + tetris.grid_width);
draw_surface( special_blocs[0].get_tuile(), tetris.grid_width, tetris.grid_width, tetris.case_unit, tetris.case_unit, background, i * (tetris.case_unit + tetris.grid_width) + tetris.grid_width + tetris.board_width, (tetris.next_bloc_preview_size_y + 1 + 4 + 6)*(tetris.case_unit + tetris.grid_width) + tetris.grid_width);
}
SDL_Surface* help_background = SDL_CreateRGBSurface(SDL_HWSURFACE, tetris.right_panel_width - tetris.grid_width, 5 * (tetris.case_unit + tetris.grid_width) - tetris.grid_width, 32, 0, 0, 0, 0); // On créé une surface pour la matrice
draw_surface( help_background, 0, 0, help_background->w, help_background->h, background, tetris.grid_width + tetris.board_width, (tetris.next_bloc_preview_size_y + 1 + 4 + 1)*(tetris.case_unit + tetris.grid_width) + tetris.grid_width, tetris.matrice_color);
//*/
}
void show_text (char* text, TTF_Font* font, SDL_Surface* dest, int posX, int posY, int redRate, int greenRate, int blueRate, int alpha)
{
SDL_Color color = {redRate, greenRate, blueRate};
SDL_Surface* text_surface = TTF_RenderText_Blended(font, text, color);
SDL_SetAlpha(text_surface, SDL_SRCALPHA, alpha); // Transparence Alpha
draw_surface(text_surface, 0, 0, text_surface->w, text_surface->h, dest, posX, posY);
}
SDL_Surface* generate_random_bmp_tuiles (bool saveBMP)
{
//* Génération d'un fond aléatoire pleins de tuiles avec les blocs spéciaux excepté le premier bloc spécial qui sert pour le tétrion
SDL_Surface* random_background = SDL_CreateRGBSurface(SDL_HWSURFACE, screen->w, screen->h, 32, 0, 0, 0, 0); // On créé une surface nommée background
int num_width = (screen->w / (tetris.case_unit + tetris.grid_width));
int num_height = (screen->h / (tetris.case_unit + tetris.grid_width));
Bloc bloc2;
for (int x = 0; x < num_width; x++) {
for (int y = 0; y < num_height; y++) {
bloc2 = special_blocs[ (rand() % (special_blocs.size() - 1)) + 1 ];
draw_surface( bloc2.get_tuile(), tetris.grid_width, tetris.grid_width, tetris.case_unit, tetris.case_unit, random_background, (x*(tetris.case_unit + tetris.grid_width)) + tetris.grid_width, (y*(tetris.case_unit + tetris.grid_width)) + tetris.grid_width);
}
}
if (saveBMP)
SDL_SaveBMP(random_background, "alea.bmp"); // on sauvegarde l'image créé pour le fun ;)
return random_background;
//*/
}
// Fonction d'arrêt du programme ----------------------------------------------------------------------------------------------------
void quit_game()
{
if (game == true) // Si il y a une partie en cours...
end_game(); // on termine la partie
// Libération des surfaces
SDL_FreeSurface( grid );
SDL_FreeSurface( matrice );
SDL_FreeSurface( background );
SDL_FreeSurface( screen );
FSOUND_Close(); // on arrête FMOD (librairie qui gère le son)
/*
TTF_CloseFont(police); // ferme la police chargée
TTF_CloseFont(police_m); // ferme la police chargée
TTF_Quit(); // arrêt de SDL_TTF
//*/
SDL_Quit(); // On arrête SDL (lib qui gère l'affichage)
}
Uint32 MoveBloc_auto( Uint32 intervalle, void *param )
{
if ( pause )
{
//SDL_BlitSurface( background, 0, screen, 0 ); // Effacement du plateau de jeu
//SDL_BlitSurface(grid, 0,
update_surface(screen); // Mise à jour de l'écran
return intervalle;
}
GAMES_MODE tmp = goDown;
MoveBloc(tmp);
update_game();
return intervalle;
}
void MoveBloc( GAMES_MODE& mode )
{
if (game == true) {
switch( mode )
{
case quit : break;
case goLeft:
FSOUND_PlaySound(FSOUND_FREE, tetris.sound_bloc_go_left_user); // on joue le son qui correspond au fait que le joueur souhaite déplacer le bloc à gauche
GoLeft();
break;
case goRight:
FSOUND_PlaySound(FSOUND_FREE, tetris.sound_bloc_go_right_user); // on joue le son qui correspond au fait que le joueur souhaite déplacer le bloc à droite
GoRight();
break;
case turnRight:
FSOUND_PlaySound(FSOUND_FREE, tetris.sound_bloc_rotate_right); // on joue le son qui correspond à la rotation du bloc
currentBloc.rotationRight();
break;
case turnLeft:
FSOUND_PlaySound(FSOUND_FREE, tetris.sound_bloc_rotate_right); // on joue le son qui correspond à la rotation du bloc
currentBloc.rotationLeft();
break;
case goDown:
FSOUND_PlaySound(FSOUND_FREE, tetris.sound_bloc_go_down_user); // on joue le son qui correspond au fait que le joueur souhaite faire descendre le bloc
GoDown();
break;
case goUp:
GoUp();
break;
}
if ( !board.isMouvementValid( tetris.posX, tetris.posY, currentBloc ) )
{
switch( mode )
{
case goLeft:
FSOUND_PlaySound(FSOUND_FREE, tetris.sound_bloc_go_left_user); // on joue le son qui correspond au fait que le joueur souhaite déplacer le bloc à gauche
GoRight();
break;
case goRight:
FSOUND_PlaySound(FSOUND_FREE, tetris.sound_bloc_go_right_user); // on joue le son qui correspond au fait que le joueur souhaite déplacer le bloc à droite
GoLeft();
break;
case turnRight:
FSOUND_PlaySound(FSOUND_FREE, tetris.sound_bloc_rotate_right); // on joue le son qui correspond à la rotation du bloc
currentBloc.rotationLeft();
userMode = none;
break;
case goDown:
GoUp();
board.addPiece( tetris.posX, tetris.posY, currentBloc );
currentBloc = nextBloc;
nextBloc = blocs[ rand() % blocs.size() ];
tetris.posY = tetris.init_posY;
tetris.posX = tetris.init_posX;
int result = board.reduce();
if (result == 2) {
SDL_RemoveTimer(timer_MoveBloc_auto); // Arrêt du Timer
GAMES_MODE tmp = goDown;
timer_MoveBloc_auto = SDL_AddTimer(1000 / tetris.level, MoveBloc_auto, &tmp); // Démarrage du Timer
FSOUND_PlaySound(FSOUND_FREE, tetris.sound_level_up); // on joue le son pour dire que le bloc à été posé
} else if (result == 1) {
FSOUND_PlaySound(FSOUND_FREE, tetris.sound_line_completed); // on joue le son pour dire que le bloc à été posé
} else if (result == 0 ) {
FSOUND_PlaySound(FSOUND_FREE, tetris.sound_bloc_is_fixed); // on joue le son pour dire que le bloc à été posé
}
userMode = none; // On arrête de descendre
// pour une nouvelle pièce
break;
}
}
}
if ( mode == turnRight ) userMode = none; // On évite de tourner en rond en continue
if ( mode == goLeft ) userMode = none;
if ( mode == goRight ) userMode = none;
if ( mode == goDown ) userMode = none;
}
########TETRIS.H########
#include <SDL/SDL.h> // librairie SDL qui gère l'affichage
#include <SDL/SDL_ttf.h> // librairie SDL_TTF qui gère l'affichage de texte
#include <FMOD/fmod.h> // librairie FMOD qui gère le son
#include <iostream>
#include <fstream>
#include <vector>
#include <stdexcept> // pour la gestion des erreurs
#include <stdlib.h>
#include <string>
using namespace std;
// ------------------- Déclarations des constantes (options du jeu)
struct options
{
int board_size_x;
int board_size_y;
int case_unit;
int board_width;
int board_height;
int grid_width;
int next_bloc_preview_x;
int next_bloc_preview_y;
int next_bloc_preview_size_x;
int next_bloc_preview_size_y;
int next_bloc_preview_width;
int next_bloc_preview_height;
int right_panel_width;
int bloc_border_width;
Uint32 bloc_border_color;
int bloc_number;
int special_bloc_number;
int window_width;
int window_height;
char* window_title;
int score;
int lines;
int line_number_to_level_up;
int level;
int init_posX;
int init_posY;
int posX;
int posY;
Uint32 background_color;
Uint32 matrice_color;
Uint32 tetrion_color;
Uint32 grid_color;
FSOUND_SAMPLE *sound_bloc_rotate_right;
FSOUND_SAMPLE *sound_bloc_rotate_left;
FSOUND_SAMPLE *sound_bloc_go_down;
FSOUND_SAMPLE *sound_bloc_go_down_user;
FSOUND_SAMPLE *sound_bloc_go_up_user;
FSOUND_SAMPLE *sound_bloc_go_up;
FSOUND_SAMPLE *sound_bloc_go_right_user;
FSOUND_SAMPLE *sound_bloc_go_left_user;
FSOUND_SAMPLE *sound_line_completed;
FSOUND_SAMPLE *sound_level_up;
FSOUND_SAMPLE *sound_loose_game;
FSOUND_SAMPLE *sound_new_game;
FSOUND_SAMPLE *sound_bloc_is_fixed;
FSOUND_SAMPLE *sound_three;
FSOUND_SAMPLE *sound_two;
FSOUND_SAMPLE *sound_one;
FSOUND_SAMPLE *sound_go;
FSOUND_STREAM *musique;
};
options tetris;
// -------------------
enum GAMES_MODE { none, quit, turnRight, turnLeft, goDown, goUp, goRight, goLeft };
GAMES_MODE userMode = none;
bool pause = false;
#include "bloc.h"
vector<Bloc> blocs;
vector<Bloc> special_blocs;
Bloc currentBloc; // défini la variable qui contient le bloc qui descend
Bloc nextBloc; // défini la variable qui contient le bloc suivant (afficher en aperçu)
#include "board.h"
Board board; // Initialise le tableau de jeu (objet voir 'board.h')
SDL_Surface* screen; // la fenêtre
SDL_Surface* background; // le fond de la fenêtre
SDL_Surface* matrice; // la matrice (zone de jeu)
SDL_Surface* grid; // la grille de la matrice
SDL_Surface* previewBloc; // la zone d'aperçu du bloc suivant
int scoreMax = 0, lineMax = 0;
SDL_TimerID timer_MoveBloc_auto; // Variable pour stocker le numéro du Timer pout bouger le bloc automatiquement
int game = false; // variable boolean qui détermine si une partie est en cours ou non
TTF_Font* police = NULL;
TTF_Font* police_m = NULL;
void GoDown() { ++tetris.posY; }
void GoUp() { --tetris.posY; }
void GoLeft() { --tetris.posX; }
void GoRight() { ++tetris.posX; }
//* Prototypes des fonction de tetris.cpp
void DisplayNumber( SDL_Surface* screen, SDL_Surface* tuiles, int x, int y, int s, int taille );
void MoveBloc( GAMES_MODE& mode );
Uint32 MoveBloc_auto( Uint32 intervalle, void *param ); // Timer pour le mouvement automatique du bloc
void draw_surface (SDL_Surface* src, int X_ori, int Y_ori, int srcWidth, int srcHeight, SDL_Surface* dest, int posX_onDest, int posY_onDest, Uint32 color = 0);
void update_surface (SDL_Surface* surface);
void init_blocs();
void init_colors(SDL_Surface* screen);
void init_options();
void add_bloc(int blocMaxWidth, string blocShape, int redRate = 256, int greenRate = 256, int blueRate = 256);
void add_special_bloc(int blocMaxWidth, string blocShape, int redRate = 256, int greenRate = 256, int blueRate = 256);
bool save_options(string filename);
int update_game();
void quit_game();
void new_game();
void end_game(bool loose_game = false);
void show_grid();
void show_text (char* text,TTF_Font* font, SDL_Surface* dest, int posX = 0, int posY = 0, int redRate = 0, int greenRate = 0, int blueRate = 0, int alpha = 255);
SDL_Surface* generate_random_bmp_tuiles (bool saveBMP = false);
void init_window_style();
bool get_blocs_by_file(bool get_special_blocs = false);
//*/
########BLOC.H########
// ----------------------------------------------------
class Bloc
{
public:
Bloc ();
Bloc( int, int, const char*, int redRate = (rand() % 256), int greenRate = (rand() % 256), int blueRate = (rand() % 256), const char* tuile_image = NULL );
void display( SDL_Surface*, int, int ) const;
void rotationRight();
void rotationLeft();
int index() const { return index_; }
int size() const { return size_; }
SDL_Surface* get_tuile() const { return tuile; }
int get( int x, int y ) const { return data_[ x * size() + y ]; }
private:
int index_;
int redRate_;
int greenRate_;
int blueRate_;
SDL_Surface* tuile;
int size_; // nb de lignes/colonne de la matrice du bloc
std::vector<int> data_;
};
Bloc::Bloc() {
}
// ----------------------------------------------------
Bloc::Bloc( int c, int s, const char* tab, int redRate, int greenRate, int blueRate, const char* tuile_image ) : index_( c ), size_( s ), redRate_( redRate ), greenRate_( greenRate ), blueRate_( blueRate )
{
for ( ; *tab; ++tab )
data_.push_back( (*tab=='1')?1:0 );
if (tuile_image == NULL) {
SDL_Surface* blocDegrade;
tuile = SDL_CreateRGBSurface(SDL_HWSURFACE, tetris.case_unit + 2*tetris.grid_width, tetris.case_unit + 2*tetris.grid_width, 32, 0, 0, 0, 0); // La bordure du bloc
// Fait un dégradé de la couleur vers le noir
for (int i = 0; i < (tetris.case_unit / 2); i++) { // On parcourt la tuile de l'extérieur vers l'intérieur, pixel par pixel et plus on va vers l'intérieur, plus on va ver le noir
blocDegrade = SDL_CreateRGBSurface(SDL_HWSURFACE, tetris.case_unit - (2 * i), tetris.case_unit - (2 * i), 32, 0, 0, 0, 0); // La bordure du bloc
// Les coordonnées de la surface sur la surface de destination
SDL_Rect srcPosition; // définition de la variable
srcPosition.x = i + tetris.grid_width; // abscisse
srcPosition.y = i + tetris.grid_width; // ordonnée
//Uint32 color = SDL_MapRGB(tuile->format, redRate_ - (i * (redRate_ / ((tetris.case_unit / 2) - 1))), greenRate_ - (i * (greenRate_ / ((tetris.case_unit / 2) - 1))), blueRate_ - (i * (blueRate_ / ((tetris.case_unit / 2) - 1)))); // dégradé vers le noir
Uint32 color = SDL_MapRGB(tuile->format, redRate_ + (i * ((255 - redRate_) / ((tetris.case_unit / 2) - 1))), greenRate_ + (i * ((255 - greenRate_) / ((tetris.case_unit / 2) - 1))), blueRate_ + (i * ((255 - blueRate_) / ((tetris.case_unit / 2) - 1)))); // dégradé vers le blanc
SDL_FillRect(blocDegrade, NULL, color); // Remplissage de la surface avec la couleur (color) passée en paramètre
SDL_BlitSurface(blocDegrade, NULL, tuile, &srcPosition); // Collage de la surface sur la destination (dest)
}
} else {
tuile = SDL_LoadBMP( tuile_image ); // chargement d'une image pour la tuiles
}
}
// ----------------------------------------------------
void Bloc::rotationRight()
{
for ( int i = 0; i < size() / 2 ; ++i )
for ( int j = 0; j < ( size() + 1 )/ 2; ++j )
{
int iAux = size() - 1 - i;
int jAux = size() - 1 - j;
swap( data_[i * size() + j], data_[jAux * size() + i] );
swap( data_[i * size() + j], data_[iAux * size() + jAux] );
swap( data_[i * size() + j], data_[j * size() + iAux] );
}
}
// ----------------------------------------------------
void Bloc::rotationLeft()
{
for ( int i = 0; i < size() / 2 ; ++i )
for ( int j = 0; j < ( size() + 1 )/ 2; ++j )
{
int iAux = size() - 1 - i;
int jAux = size() - 1 - j;
swap( data_[i * size() + j], data_[j * size() + iAux] );
swap( data_[i * size() + j], data_[iAux * size() + jAux] );
swap( data_[i * size() + j], data_[jAux * size() + i] );
}
}
// ----------------------------------------------------
void Bloc::display( SDL_Surface* screen, int x, int y ) const
{
for ( int i = 0; i < size(); ++i )
for ( int j = 0; j < size(); ++j )
if ( get( i, j ) )
{
SDL_Rect rectDest;
rectDest.x = i * (tetris.case_unit + tetris.grid_width) + x * (tetris.case_unit + tetris.grid_width) + tetris.grid_width;
rectDest.y = j * (tetris.case_unit + tetris.grid_width) + (y+1) * (tetris.case_unit + tetris.grid_width) + tetris.grid_width;
rectDest.w = rectDest.h = 0;
SDL_Rect rectSrc;
rectSrc.x = tetris.grid_width;
rectSrc.y = tetris.grid_width;
rectSrc.w = rectSrc.h = tetris.case_unit;
SDL_BlitSurface( tuile, &rectSrc, screen, &rectDest );
}
}
########BOARD.H########
//--------------------------------------------
//*
class Board
{
public:
Board()
{ // Initialisation des bordures
}
void display( SDL_Surface* ) const;
bool isMouvementValid( int, int, const Bloc& ) const;
void addPiece( int, int, const Bloc& );
void init_board()
{
_board.resize(tetris.board_size_x); // redimensionne le tableau à sa taille réelle calculée dans l'initialisation des options
for ( int x = 0; x < tetris.board_size_x; ++x ) {
_board[x].resize(tetris.board_size_y);
for ( int y = 0; y < tetris.board_size_y; ++y ) {
_board[x][y] = ( x == 0 || x == tetris.board_size_x - 1 || y == tetris.board_size_y - 1 );
}
}
}
void reduceLine( int );
int reduce();
private:
vector < vector<int> > _board; // utilisation d'un tableau multidimensionnel redimensionnable vector
};
// ----------------------------------------------------
void Board::display( SDL_Surface* screen ) const
{
for ( int x = 1; x < tetris.board_size_x-1; ++x )
for ( int y = 0; y < tetris.board_size_y-1; ++y )
if ( _board[x][y] )
{
SDL_Rect rectDest;
rectDest.x = x * (tetris.case_unit + tetris.grid_width);
rectDest.y = (y+1)* (tetris.case_unit + tetris.grid_width);
rectDest.w = rectDest.h = 0;
SDL_Rect rectSrc;
rectSrc.x = 0;
rectSrc.y = 0;
rectSrc.w = rectSrc.h = tetris.case_unit + (2*tetris.grid_width);
SDL_BlitSurface( blocs[_board[x][y] - 1].get_tuile(), &rectSrc, screen, &rectDest );
}
}
// ----------------------------------------------------
bool Board::isMouvementValid( int posX, int posY, const Bloc& bloc ) const
{
for ( int x = posX; x < posX + bloc.size(); ++x )
for ( int y = posY; y < posY + bloc.size(); ++y )
if ( bloc.get( x - posX, y - posY ) && _board[x][y] )
return false;
return true;
}
// ----------------------------------------------------
void Board::addPiece( int posX, int posY, const Bloc& bloc )
{
for ( int x = posX; x < posX + bloc.size(); ++x )
for ( int y = posY; y < posY + bloc.size(); ++y )
if ( bloc.get( x - posX, y - posY ) )
_board[x][y] = bloc.index() + 1;
}
// ----------------------------------------------------
int Board::reduce()
{
int addedLine = 0;
for ( int y = 1; y < tetris.board_size_y - 1 ; ++y )
{
bool lineFull = true;
for ( int x = 1; ( x < tetris.board_size_x - 1 ) && lineFull; ++x )
if ( !_board[x][y] ) lineFull = false;
if ( lineFull )
{
++addedLine; // Une ligne suplémentaire
for ( int z = y; z > 1 ; --z )
for ( int x = 1; x < tetris.board_size_x - 1; ++x )
_board[x][z] = _board[x][z-1];
for ( int x = 1; x < tetris.board_size_x - 1; ++x )
_board[x][0] = 0;
}
}
tetris.lines += addedLine;
if (tetris.level < ( tetris.lines / tetris.line_number_to_level_up ) + 1) {
tetris.level++; // Un niveau supplémentaire
tetris.score += (tetris.level * 100) + (tetris.level * min( 4, addedLine ) + addedLine) * 150; // Un point pour le niveau
return 2;
}
if (addedLine > 0) {
tetris.score += (tetris.level * min( 4, addedLine ) + addedLine) * 150; // Un point pour le niveau
return 1;
}
return 0;
}
Conclusion
Tout est dans le zip A CETTE ADRESSE parce que le package est trop lourd (2MO)
Version 1 (2MO) : http://dev.thierry.poinot.fr/TetrisV1.0 10-08-2007 16h35.zip
Version 2 (5MO) : http://dev.thierry.poinot.fr/TetrisV2.0 19-08-2007 15h45.zip
Il contient les DLL, les sources, le projet Dev-cpp et l'éxécutable.
Pour les dernières mise à jour : http://blog.thierry.poinot.fr/dc/?post/2007/08/14/ Tetris-V10
Bugs connus : le jeu ne se ferme qu'en appuyant sur ECHAP - l'action de fermer la fenêtre avec la croix de la fenêtre ne marche pas je ne sais pas pourquoi... - lorsque le jeu est en pause, il est impossible de fermer
Historique
- 20 août 2007 11:08:59 :
- Mise à jour vers la version 2 !
- 20 août 2007 11:44:41 :
- Mise à jour ver la version 2
Remaniement de l'interface
créations de fichiers de configuration
possibilité de jouer avec les blocs que vous souhaitez
Sources de la même categorie
Commentaires et avis
Discussions en rapport avec ce code source dans le forum
Fmod et dev-cpp 4.9.9.2 [ par kujad ]
Bonjour, je vais être clair : FMUSIC_StopSong(zik); SDL_Quit; return 0;quand je comp
Créer un jeu vidéo... [ par Crepuscule3 ]
Bonjour à tous, J'ai quelques compétences en C/C++ et je souhaiterai apprendre à créer un jeu vidéo. Je sais... certains ne vont pas pouvoir s'empêc
Tetris game [ par hindou11 ]
Bonjour, je viens de me lancer dans la SDL, mais il se trouve que je plante un peu......je suis entrain de programmer le jeu du tetris mais je m'emb
Qui veut de l'aide dans son projet de jeux vidéo 2d c++ SDL [ par evilblack ]
Slt tout le monde si quelqu'un cherche un programmeur c++ pour un jeu rpg ou de combat ou autre chose en 2d je suis là. Librairie SDL.
tetris en SDL [ par fahdovski ]
Bonjour, je code tetris en C avec la SDL voici mon problemevoid creerlachute(tab t){int i,j;for (i=0;i<li;i++) for(j=0;j<co;j++){ if (t[
[C&SDL]Tetris [ par bidji69 ]
Bonjour, Je suis étudiant en IUT et dans le cadre d'un projet, je dois réaliser un tetris en C. Or depuis le début, la seule chose que j'ai réussi à f
probléme avec sdl [ par manuellaolivia ]
Salut,j'ai intégré SDL dans codeblock mais lorsque je compile mon programme on m'affiche le message suivant "Debug" uses an invalid compiler. Skipping
jeux Morpion - puissances 4 [ par Lisandrelegrand ]
Salut, je cherche un jeux de Morpion ou de puissances 4 en langague C comprenant le chainage avant-arriere (systeme expert AI) Merci pour votre aide.
Installation de la SDL avec MVS standard 2005 [ par Hatchepsut ]
Bonjour. Comme l'indique le titre, je n'arrive pas à installer la SDL. J'ai lu, relu, et re-relu tous les tutoriaux de multiples forums, rien n'y fai
Tetris Alogrithme [ par fahdovski ]
Jai besoin d'aide.Je n'arrive pas a trouve une solution generale cad qui marche pour tout les blocs pour resoudre le probleme du bloc qui tombe et qui
|
Derniers Blogs
IMAGINE CUP 2012, MAKE A SIGN EN FINALEIMAGINE CUP 2012, MAKE A SIGN EN FINALE par junarnoalg
Voilà qui est fait, la nouvelle est officielle ! L'équipe belge "Make a Sign" va au pays des kangourous défendre son projet dans la catégorie Software Design. http://www.imaginecup.com/CompetitionsContent/Competition/WorldwideFinalists.aspx V...
Cliquez pour lire la suite de l'article par junarnoalg KINECT 1.5 IS OUT !KINECT 1.5 IS OUT ! par Vko
La version 1.5 du Kinect For Microsoft vient tout juste de sortir ! Plein de nouveautés: Tracking de squelette en Near Mode Détection en position assise Détection faciale avec un SDK dédié Documentation et des guideline (enfin) Un out...
Cliquez pour lire la suite de l'article par Vko LES ACTUALITéS DE LA SEMAINE SUR C2I.FR (14 MAI - 20 MAI) LES ACTUALITéS DE LA SEMAINE SUR C2I.FR (14 MAI - 20 MAI) par richardc
Mise à jour des Web API du 14 Mai
Réservez dès maintenant votre journée du 20 juin pour le Windows Azure Dev Camp 2012 à Paris
Mise à jour de Team Foundation Service
MechCommander 2 sur Windows 8
Entity Framework 5 Release Candidate e...
Cliquez pour lire la suite de l'article par richardc REACTIVE EXTENSIONS : CONSOMMER DES SERVICES AVEC RX PARTIE 3, LES PIèGES à éVITERREACTIVE EXTENSIONS : CONSOMMER DES SERVICES AVEC RX PARTIE 3, LES PIèGES à éVITER par Groc
Une mauvaise utilisation de rx lors de l'écriture d'une couche d'accès à des services peut conduire à des cas embarassants avec des erreurs mal gérées, des appels qui ne partent lorsqu'ils le devraient, et même des résultats incorrects . le tout nuis...
Cliquez pour lire la suite de l'article par Groc SHAREPOINT BLOG SITE, PROBLèME D'ARCHIVESSHAREPOINT BLOG SITE, PROBLèME D'ARCHIVES par junarnoalg
Dernièrement, nous avons migré le site
myTIC
vers un nouveau serveur SharePoint 2010. Dans les contenus que nous vouloins récupérer, nous avions un certain nombre de blogs.
Nous avons utilisé les commandes Power...
Cliquez pour lire la suite de l'article par junarnoalg
Forum
MATRICE TEMPLATEMATRICE TEMPLATE par hjr2610
Cliquez pour lire la suite par hjr2610 RE : SAC A DOS RE : SAC A DOS par hadjkaddour
Cliquez pour lire la suite par hadjkaddour
Logiciels
sDEVIS-FACTURES vlPRO (8.1.0.3)SDEVIS-FACTURES VLPRO (8.1.0.3)sDEVIS-FACTURES vlPRO a été mis au point pour les particuliers, créateurs, entrepreneurs, artisa... Cliquez pour télécharger sDEVIS-FACTURES vlPRO 974 Application Server (12.2.4.6)974 APPLICATION SERVER (12.2.4.6)Développez de puissantes applications dans un environnement de 'cloud computing', clusterisé, séc... Cliquez pour télécharger 974 Application Server vPicture (1.4.2.1)VPICTURE (1.4.2.1)Avec vPicture, hébergez vos images facilement et rapidement.
vPicture est un utilitaire simple, ... Cliquez pour télécharger vPicture Easy-Planning (2.2.1.6)EASY-PLANNING (2.2.1.6)Easy-Planning permet de créer des plannings sous la représentation de diagrammes et est adapté au... Cliquez pour télécharger Easy-Planning COM-BACKUP (2.0)COM-BACKUP (2.0)
COM-BACKUP est un logiciel de sauvegarde qui permet de planifier les sauvegardes de vos dossiers ...
Cliquez pour télécharger COM-BACKUP
|