IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Contribuez Discussion :

[Tuto][Source][SDL][Jeu]Apprendre en s'amusant : Tetris


Sujet :

Contribuez

  1. #1
    Membre confirmé
    Avatar de Mindiell
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    735
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 735
    Points : 546
    Points
    546
    Par défaut [Tuto en travaux]Apprendre à faire un jeu vidéo : Tetris
    Bonjour à tous,

    J'ai décidé d'apprendre à utiliser la SDL et pour cela, j'ai souhaité créer un petit jeu afin de bien apprendre à l'utiliser !
    Bien entendu, Tetris est un jeu moulte-fois recréé à tort et à travers, mais ce n'est pas grave : L'avantage de Tetris est de pouvoir manipuler pas mal de choses pour obtenir un résultat.

    Avant toute chose, pour finir ce tutorial je vais utiliser VS 6, MS Paint, un CD de musique et de l'huile de coude !

    Nous allons suivre toutes les étapes pour mener notre projet de jeu du début à la fin. Ensuite chaque post décrira une étape complète avec le code et/ou les dessins libres de droit. Pour la musique, vous pourrez utiliser un CD à vous.

    Pour toute question, ou autre, merci de m'envoyer directemetn un MP pour ne pas polluer le tutorial. Au pire je demanderais à un admin de les effacer une fois répondu !
    Mindiell
    "Souvent, femme barrit" - Elephant man

  2. #2
    Membre confirmé
    Avatar de Mindiell
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    735
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 735
    Points : 546
    Points
    546
    Par défaut
    Premièrement, il faut réfléchir à son jeu, à son ensemble, sa globalité, puis il faut affiner et approfondir. En choisissant de refaire un jeu, je me débarasse d'une bonne partie de création et de réflexion. Cependant, et afin de bien suivre les étapes, on va revoir le concept de Tetris afin de s'assurer d'avoir bien compris les mécanismes du jeu.

    En cas de question, on s'orientera toujours vers la solution la plus simple sans réfléchir.

    Le concept :
    Tetris est donc un jeu ou l'on peut diriger une piece qui tombe du haut d'une zone. Cette pièce stoppe son mouvement dès qu'elle ne peut plus descendre. Dans ce cas là, elle est bloquée et une autre pièce arrive. Si jamais une pièce ne peut plus entrer dans la zone, la partie est arretée. Il est possible, de faire tourner la pièce de 90 degrés dans le sens horaire ou non.

    Planning de création du jeu :
    Maintenant qu'on a vu à quoi le jeu allait ressembler, on peut essayer de se définir un petit planning de progression technique. Si on a un peu de temps pour y réfléchir, on pourra même insérer de nouvelles tâches ou inverser deux tâches pour correction. Ce planning représente uniquement les tâches manuelles à faire une fois que tout est prêt. J'ai essayé de séparer suffisamment les tâches pour qu'on puisse en faire au moins une par soir environ et si tout se passe bien :
    1. Installer la librairie SDL, puis créer un programme de base avec
    2. Dessiner un carré
    3. Définir l'aire de jeu et modifier le programme pour qu'il fasse la taille de l'aire de jeu
    4. Dessiner le carré sur l'aire de jeu, et le faire descendre en mode pas-à-pas
    5. Gérer les touches flechées pour le déplacement de la pièce
    6. Gérer la disparition d'une ligne quand le carré la complète
    7. Créer les vraies formes du jeu, toutes à partir du carré de base
    8. Gérer les touches flechées pour chaque forme créée
    9. Gérer le blocage de la forme quand elle arrive en bas
    10. Définir le concept de la chute, définir le logigramme de déroulement du processus
    11. Mise en route du mode réel
    12. Mise en place d'un système de points
    13. Affichage du futur bloc en option
    14. Créer des niveaux de difficulté jouant uniquement sur la vitesse de chute
    15. Mise en place d'une pause, mais en cachant la surface de jeu
    16. Mise en place d'un menu de départ
    17. Mise en place d'une page de crédits
    18. Sauvegarde des meilleurs scores et mise en place d'une page de highscores
    19. Mise en place d'une page d'options avec modification des touches de jeu et du niveau sonore


    Et voilà ! En moins de 20 étapes, on aura un vrai jeu, avec des options, de la musique et tout !
    Mindiell
    "Souvent, femme barrit" - Elephant man

  3. #3
    Membre confirmé
    Avatar de Mindiell
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    735
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 735
    Points : 546
    Points
    546
    Par défaut
    Me revoilà !

    Après une bonne journée de réflexion, j'en suis arrivé à la conclusion que mes étapes sont mal agencées ! En effet, j'avais bien précisé qu'il fallait avant tout réfléchir avant de se lancer dans les étapes, hors certaines étapes sont de la réflexion...

    On va donc s'occuper maintenant de l'étape 3 "Définir l'aire de jeu"

    Définir l'aire de jeu
    Je me suis décidé pour des carrés (la brique de base du jeu) de 8x8, ca reste simple et suffisamment petit. Sachant que la plus grande pièce du jeu fait 4 carrés de long, on va faire un tableau de 9 carrés de large. Cela permet de poser 2 fois la pièce la plus longue plus un trou, ca me semble pas mal.
    Pour la hauteur, on va partir sur une fois et demi la largeur : 13 carrés. On pourra affiner ca plus tard, on envisage donc de stocker ces mesures en constantes dans le programme. Idem pour la taille du carré de base, cette mesure est, en effet, celle qui va servir pour les déplacements des carrés.

    Bien, après avoir défini l'aire de jeu, il est temps de définir les pièces du jeu. On utilisera, comme dans le tetris de base, les 7 figures réalisables avec 4 carrés qui se touchent. Pour cela, je vais dessiner sur une feuille de papier les pièces. J'envisage de mettre une couleur différente par pièce.

    On peut maintenant s'attaquer à l'étape 10 "Définir le concept de la chute, définir le logigramme de déroulement du processus". En effet, il vaut mieux s'en occuper avant de se lancer dans la programmation !

    Définir le concept de la chute, définir le logigramme de déroulement du processus
    Bon, résumons ce que l'on sait :
    • Une aire de jeu de 9x13
    • Des carrés qui tombent s'ils font partie d'une pièce
    • Des carrés qui restent immobile sinon
    • Il existe 7 couleurs de carré
    • Les nouvelles pièces apparaissent par le haut
    • La plus grande fait 4 carrés de longueur
    • La nouvelle pièce apparait au milieu de l'aire, par le haut

    Avec ca, on peut réfléchir assez loin. On va prendre un tableau d'octets de 9x17. Les 4 lignes du haut sont simplement utilisés pour y placer la nouvelle pièce à faire tomber. Pour faire simple, dès que la pièce est transformée en carrés immobiles, on vérifie cette zone. Si elle contient un seul carré, la partie est perdue : on a pas réussi à mettre la nouvelle pièce.
    Les carrés d'une pièce vont être représentés par des valeurs de 1 à 7. Un trou dans l'aire de jeu sera représenté par un 0. Enfin, les carrés immobiles seront représentés en ajoutant 10 à la valeur du carré d'une pièce : 11 à 17.
    Reste l'organigramme ou la représentation de l'algorithme de la chute. On va séparer celui-ci en 2 phases distinctes : la chute d'une pièce, et le nettoyage de l'aire (chute de l'aire) :

    Eh ben voilà... C'est fini pour le moment, car mon algorithme de chute ne fonctionne pas ! Il faut que j'y réfléchisse encore un peu, comme quoi il faut bien réfléchir avant de se lancer !
    Mindiell
    "Souvent, femme barrit" - Elephant man

  4. #4
    Membre confirmé
    Avatar de Mindiell
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    735
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 735
    Points : 546
    Points
    546
    Par défaut
    Un dernier petit post ce jour pour rajouter ce que je viens à peine de dessiner rapidement avec MS paint :





    Ces images ne font que représenter les différentes pièces accessibles dans le jeu. Pour celui-ci, nous n'aurons besoin que des carrés comme la première image.
    Mindiell
    "Souvent, femme barrit" - Elephant man

  5. #5
    Membre confirmé
    Avatar de Mindiell
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    735
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 735
    Points : 546
    Points
    546
    Par défaut
    Bonsoir à tous ! (enfin, vu le nombre de retours, pas grand monde, mais bon )

    J'ai eu le temps de me pencher sur l'algorithme de base du déroulement du jeu ! Voilà donc la première partie. On va, en effet, se basé sur un algorithme général pour indiquer le déroulement du programme pendant le jeu :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    Si (deroulement = piece_tombe)
        piece_bloquee = VerifierProchainePosition ()
        Si (piece_bloquee)
            transformationpiece ()
            deroulement = tableau_tombe
        Sinon
            ChutePiece ()
        FinSi
    FinSi
    Si (deroulement = tableau_tombe)
        DisparitionLignesCompletes ()
        ChuteTableau ()
        NouvellePiece ()
        deroulement = piece_tombe
    FinSi
    Et voilà ! C'est aussi simple que ça. Lorsque la pièce tombe, on vérifie juste si elle est coincée ou pas par les carrés fixes. Sinon, on la fait simplement tombée d'une position. Si oui, on la transforme en carrés fixés et on résoud le nouveau tableau. Ensuite, on fait chuter les carrés fixes situés au-dessus des lignes qui ont disparu.

    Il ne reste plus qu'à coder cela !

    Enfin, après réflexion, toutes les pièces tiennent largement en longueur dans la largeur du tableau. Il peut donc être intéressant de les situer à plat sur seulement 2 lignes, réduisant ainsi le tableau à 9x15 lignes. Cependant, lorsqu'on fait chuter la première pièce, ou les carrés fixes ensuite, il faut bien les bloquer. Pour cela, on utilisera une ligne située sous le tableau toujours remplie de carrés fixes. Cela nous donne au final un tableau de 9x16 lignes.

    Comme on peut le voir, la réflexion que nous avons prise ces derniers jours nous a permis d'avancer sans coder une seule ligne et d'éviter des écueils qui auraient pu se révéler catastrophique ou pas. C'est pour cela qu'il est très important de réfléchir et de poser à plat ses idées tout en sachant les remettre en question.

    Notre algorithme semble bon, il nous donne l'occasion de programmer rapidement quelques fonctions simples. Bien entendu, le joueur devra avoir le loisir de déplacer et faire tourner la pièce, mais cela reste en deohrs de l'algorithme principal qui s'effectuera une fois de temps en temps au cours du jeu.
    Mindiell
    "Souvent, femme barrit" - Elephant man

  6. #6
    Expert éminent sénior

    Avatar de fearyourself
    Homme Profil pro
    Ingénieur Informaticien Senior
    Inscrit en
    Décembre 2005
    Messages
    5 121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Ingénieur Informaticien Senior
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2005
    Messages : 5 121
    Points : 11 877
    Points
    11 877
    Par défaut
    Bien le bonjour,

    Je viens de lire ce post et je le trouve très prometteur.

    Attention par contre :

    - Il est facile de se lancer dans une idée et écrire beaucoup de choses mais lorsque viendra le temps d'éditer et de remettre en place, on remarque que beaucoup de choses peuvent être enlevées.

    - Il est nettement mieux d'écrire tout le code du programme et lorsqu'il est fini, on le redivise pour les tutoriels.

    Ce n'est que mon avis bien sûr. Ensuite, attention aux algorithmes théoriques, lorsqu'on tente de les coder, on remarque qu'on était bien loin de ce qui est nécessaire.

    Jc

  7. #7
    Membre confirmé
    Avatar de Mindiell
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    735
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 735
    Points : 546
    Points
    546
    Par défaut
    Salut,

    Merci beaucoup pour tes critiques, ca fait chaud au coeur

    Pour les choses à enlever, je pense que ce qui est intéressant dans ce tutoriel, c'est de voir que je reviens en arrière sur certaines choses. Les lecteurs verront bien le processus complet de la création, non ?
    C'était mon souhait quand j'ai commencé ce tutoriel : Montrer aux débutants les étapes nécessaires de réflexion, et surtout que les premières idées ne sont pas toujours les bonnes, loin de là

    Pour l'algo, tu as remarqué un défaut ou c'est juste une remarque pour n'importe quel algorithme théorique ?
    Mindiell
    "Souvent, femme barrit" - Elephant man

  8. #8
    Membre confirmé
    Avatar de Mindiell
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    735
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 735
    Points : 546
    Points
    546
    Par défaut
    Bonjour à tous !

    Bien, voilà venu le temps de coder un peu. Avant tout, nous allons faire une dernière chose : éliminez les étapes déjà faites !

    1. Installer la librairie SDL, puis créer un programme de base avec
    2. [FAIT]Dessiner un carré
    3. Définir l'aire de jeu et modifier le programme pour qu'il fasse la taille de l'aire de jeu
    4. Dessiner le carré sur l'aire de jeu, et le faire descendre en mode pas-à-pas
    5. Gérer les touches flechées pour le déplacement de la pièce
    6. Gérer la disparition d'une ligne quand le carré la complète
    7. Créer les vraies formes du jeu, toutes à partir du carré de base
    8. Gérer les touches flechées pour chaque forme créée
    9. Gérer le blocage de la forme quand elle arrive en bas
    10. [FAIT]Définir le concept de la chute, définir le logigramme de déroulement du processus
    11. Mise en route du mode réel
    12. Mise en place d'un système de points
    13. Affichage du futur bloc en option
    14. Créer des niveaux de difficulté jouant uniquement sur la vitesse de chute
    15. Mise en place d'une pause, mais en cachant la surface de jeu
    16. Mise en place d'un menu de départ
    17. Mise en place d'une page de crédits
    18. Sauvegarde des meilleurs scores et mise en place d'une page de highscores
    19. Mise en place d'une page d'options avec modification des touches de jeu et du niveau sonore


    J'ai souligné les étapes nécessaires pour faire un moteur qui fonctionne. Le reste des étapes n'est qu'optionnel et ce sont ces étapes qui feront l'originalité du jeu ou pas.
    Mindiell
    "Souvent, femme barrit" - Elephant man

  9. #9
    Membre confirmé
    Avatar de Mindiell
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    735
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 735
    Points : 546
    Points
    546
    Par défaut
    Installer la librairie SDL, puis créer un programme de base avec

    Bon, pour cela, il va vous falloir un compilateur (dev C++, VS, gc++, etc...) et télécharger les librairies de développement de la SDL. Le site de la sdl s'appelle libsdl, et à l'heure où j'écris ces lignes, il semble mort !

    Il y a des tas de tutoriels pour installer la SDL ici et sur le net. Il suffit de copier les fichiers .lib dans le répertoire lib de votre compilateur, de copier la dll dans le bon chemin suivant votre systeme (winnt\system32 pour moi), et de copier tous les include dans le répertoire include de votre compilateur.

    Je rappelle ici que ce tutoriel est surtout orienté sur la manière de créer un jeu vidéo, et ces différentes étapes fonctionnelles. L'utilisation du langage C doit être acquis et la librairie SDL n'est qu'un outil sur lequel on ne cherchera pas à tout optimiser dès le départ, vu qu'on en fait ici l'apprentissage.

    Notre première source va constituer uniquement en la création d'un programme SDL qui attend bien gentiment qu'on le ferme :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    //Pour utiliser la SDL
    #include <SDL.h>
     
    //Utilisation des librairies de la SDL pour Windows
    #ifdef WIN32
      #pragma comment(lib, "SDL.lib")
      #pragma comment(lib, "SDLmain.lib")
    #endif
     
    //La mémoire vidéo contenant ce qui s'affiche
    SDL_Surface *ecran;
    //Les évènements du programme
    SDL_Event evenements;
     
    int main(int argc, char** argv)
    {
        //Initialisation de la SDL
        if( SDL_Init(SDL_INIT_VIDEO)<0 )
        {
            printf("Impossible d'initialiser la librairie SDL : %s\n", SDL_GetError());
            exit (1);
        }
     
        //Création de la surface principale
        //Avec surface créée dans la mémoire vidéo, et double buffer
        ecran = SDL_SetVideoMode ( 320, 200, 32, SDL_SWSURFACE|SDL_DOUBLEBUF);
        //On teste si cela s'est bien passé
        if ( ecran == NULL )
        {
            printf("Impossible de passer en mode 800x600 : %s\n", SDL_GetError());
            exit (1);
        }
     
        //Puis boucle du fichier principal
        while (true)
        {
            while ( SDL_PollEvent(&evenements) )
            {
                switch (evenements.type)
                {
                    case (SDL_KEYDOWN) :
                        switch (evenements.key.keysym.sym)
                        {
                            //Touche "escape" appuyée
                            case (SDLK_ESCAPE) :
                                //On quitte le programme
                                SDL_Quit();
                                exit (0);
                                break;
                        }
                        break;
                }
            }
        }
        //Fin du programme
        return 0;
    }
    Mindiell
    "Souvent, femme barrit" - Elephant man

  10. #10
    Expert éminent sénior

    Avatar de fearyourself
    Homme Profil pro
    Ingénieur Informaticien Senior
    Inscrit en
    Décembre 2005
    Messages
    5 121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Ingénieur Informaticien Senior
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2005
    Messages : 5 121
    Points : 11 877
    Points
    11 877
    Par défaut
    Citation Envoyé par Mindiell
    Pour les choses à enlever, je pense que ce qui est intéressant dans ce tutoriel, c'est de voir que je reviens en arrière sur certaines choses. Les lecteurs verront bien le processus complet de la création, non ?
    Pas sûr, cela risque de perdre plus d'un. De toute facon, ne serait-ce pas mieux de viser l'écriture d'une série de tutoriels avec ta propre page sur developpez.com qu'une série de posts dans un fil ?

    C'était mon souhait quand j'ai commencé ce tutoriel : Montrer aux débutants les étapes nécessaires de réflexion, et surtout que les premières idées ne sont pas toujours les bonnes, loin de là
    Ok je suis d'accord sur le principe mais généralement cela rend la lecture difficile parce qu'on explique quelque chose et après on dit "ah ben non c'est faux"...

    Pour l'algo, tu as remarqué un défaut ou c'est juste une remarque pour n'importe quel algorithme théorique ?
    Pour l'algorithme, je pense qu'avoir une variable qui dit dans quel état est un peu compliqué pour ce que tu veux faire...

    On pourrait simplifier le tout en faisant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
        piece_bloquee = VerifierProchainePosition ()
        Si (piece_bloquee)
           transformationpiece ()
           DisparitionLignesCompletes ()    
           ChuteTableau ()
          NouvellePiece ()
        Sinon
            ChutePiece ()
        FinSi
    Et encore, il faudrait ajouter la gestion de fin de partie, donc cela pourrait donner ceci:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
        piece_bloquee = VerifierProchainePosition ()
        Si (piece_bloquee)
           transformationpiece ()
           DisparitionLignesCompletes ()    
           ChuteTableau ()
           NouvellePiece ()
           fin = VerifierPositionCourante()
           Si (fin)
                FinDePartie()
           FSi
        Sinon
            ChutePiece ()
        FinSi
    Jc

  11. #11
    Membre confirmé
    Avatar de Mindiell
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    735
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 735
    Points : 546
    Points
    546
    Par défaut
    Petit passage pour souhaiter un Joyeux Noël à tout le monde
    Mindiell
    "Souvent, femme barrit" - Elephant man

  12. #12
    Membre confirmé
    Avatar de Mindiell
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    735
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 735
    Points : 546
    Points
    546
    Par défaut
    [Hors-tuto]
    J'ai viré le délestage, je ne sais pas s'il se met automatiquement ou si un admin l'a mis... Si c'est la seconde option, merci de me dire pourquoi
    [/Hors-tuto]

    Bonsoir à tous !

    Ce soir nous allons faire tomber notre carré !
    Pour cela, rien de plus simple, on va utiliser la SDL, et une fonction de chute toute simple.
    Avant tout, il faut créer le carré dans le tableau, et créer la ligne du bas du tableau (celle qui n'est pas affichée mais qui n'apparait jamais).
    Cette ligne devant tout bloquer, on va l'initialiser à 255. Ca permet de garder sous le coude suffisamment de valeurs pour les carrés fixes ou en chute.

    J'ai essayé d'implémenter l'algorithme de chute de la pièce. Algorithme retouché par fearyourself, merci à lui

    Le code source est accessible ici en pièce jointe, et je l'éspère suffisamment commenté pour que tout le monde puisse comprendre. Je viens de faire tout le code d'une traite, ca marche, mais j'ai peut-être fait quelques erreurs. Je relirais ca demain à tête reposée et je tâcherais d'expliquer en détail les points un peu obscurs.

    A ce point-là, on a fini les étapes 1, 3, 4, 9. Comme on peut le voir, les étapes même réfléchies ne se font pa stoujours dans l'ordre prévu. C'est un bon point à retenir pour les prochaines fois. On reviendra plus tard sur le pourquoi de ce décalage de quelques étapes.
    Fichiers attachés Fichiers attachés
    Mindiell
    "Souvent, femme barrit" - Elephant man

  13. #13
    Membre confirmé
    Avatar de Mindiell
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    735
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 735
    Points : 546
    Points
    546
    Par défaut
    Bonsoir à tous !

    Voilà la suite du programme ! J'ai décidé de ne pas expliquer mon source pour le moment, puisque personne ne semble me poser de questions dessus. Et vu que je passe du temps à coder tout cela, j'ai moins de temps pour expliquer... Et puis j'ai pas mal expliquer ci-dessus, non ?

    Voilà mon fichier source_2.cpp, et les nouveautés rajoutées :
    - Modification de creer_piece afin de créer les vraies pièces du jeu. Pour le moment, toutes les pièces sont en rouge. (étape 7)
    - Modification du tableau pour prendre en compte les déplacements latéraux. En effet, il faut bien bloquer la pièce sur la gauche et sur la droite du tableau. Celui-ci est donc passé à 15x11 comme quoi, on ne pense pas toujours à tout ! (début de l'étape 5)
    - Gestion des touches flechées droite et gauche pour le mouvement latéral des pièces (fin de l'étape 5)
    - Gestion de la touche flechée haut pour la rotation seulement sur certaines pièces (début de l'étape 8)

    On résume donc à nouveau les étapes :
    1. [FAIT]Installer la librairie SDL, puis créer un programme de base avec
    2. [FAIT]Dessiner un carré
    3. [FAIT]Définir l'aire de jeu et modifier le programme pour qu'il fasse la taille de l'aire de jeu
    4. [FAIT]Dessiner le carré sur l'aire de jeu, et le faire descendre en mode pas-à-pas
    5. [FAIT]Gérer les touches flechées pour le déplacement de la pièce
    6. Gérer la disparition d'une ligne quand le carré la complète
    7. [FAIT]Créer les vraies formes du jeu, toutes à partir du carré de base
    8. [FAIT]Gérer les touches flechées pour chaque forme créée
    9. [FAIT]Gérer le blocage de la forme quand elle arrive en bas
    10. [FAIT]Définir le concept de la chute, définir le logigramme de déroulement du processus
    11. Mise en route du mode réel
    12. Mise en place d'un système de points
    13. Affichage du futur bloc en option
    14. Créer des niveaux de difficulté jouant uniquement sur la vitesse de chute
    15. Mise en place d'une pause, mais en cachant la surface de jeu
    16. Mise en place d'un menu de départ
    17. Mise en place d'une page de crédits
    18. Sauvegarde des meilleurs scores et mise en place d'une page de highscores
    19. Mise en place d'une page d'options avec modification des touches de jeu et du niveau sonore


    Je considère l'étape 8 comme faite, ca n'est qu'une question de temps et de calculs pour rajouter les rotations des autres pièces et là, je dois aller dormir

    Il nous reste à faire "chuter le tableau" et à lancer le jeu en temps réel et non plus en pas-à-pas !
    Fichiers attachés Fichiers attachés
    Mindiell
    "Souvent, femme barrit" - Elephant man

  14. #14
    Membre confirmé
    Avatar de Mindiell
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    735
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 735
    Points : 546
    Points
    546
    Par défaut
    Bonsoir à tous !

    J'ai fini l'étape 8 comme prévu, et j'ai dessiné les pièces en couleur. Cela nous boucle l'étape 7 définitivement. J'ai donc rajouté une fonction "charger_images" qui gère le chargement des 7 carrés de couleurs. Ces derniers sont assez moches, le marron ressemble trop au rouge, et le gris est moche. Mais ce n'est qu'un exemple, vous pourrez surement faire mieux !

    J'en ai profiter pour implémenter le jeu en temps réel avec un simple timer SDL. Dès que celui-ci s'active, la pièce descend comme si l'on avait pressé la touche 'p' pour le pas-à-pas. Pour le moment, le timer appelle une fonction "forcer_chute" qui elle-même ne fait qu'un simple appel direct à la fonction "chute_piece", mais cette fonction pourra peut-être nous servir plus tard...

    Je m'attellerai bientôt à la chute du tableau qui devrait rester assez simple. Pour cela, nous reviendrons en mode pas-à-pas en désactivant simplement le timer. Pour le reste des modifications, j'ai modifié la taille du tableau en constantes afin de pouvoir retailler celui-ci simplement : En effet, je le trouvais finalement trop petit (en mode temps réel) et je l'ai allongé un peu

    Ci-joint donc, mon troisième source qui s'étoffe.
    Fichiers attachés Fichiers attachés
    Mindiell
    "Souvent, femme barrit" - Elephant man

  15. #15
    Rédacteur

    Avatar de millie
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    7 015
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 7 015
    Points : 9 818
    Points
    9 818
    Par défaut
    Le code est méchant et mal organisé Mais c'est un début

    Tu fais du C++, ce serait sympa si tu essayais de faire un peu de programmation objet (ou même de la POO à la C serait aussi mieux).

    En C++, il n'est pas obligatoire de mettre (void) comme paramètre pour indiquer qu'il n'y a pas de paramètre.

    Essaye de découper un minimum les prototypes publiques dans les .h (ou .hpp) du reste.

    Il faut également éviter les constantes globales dans le jeu. Pourquoi ne pas créer des structures (ou même des classes) qui contiennent les informations relatives : au niveau, au graphisme, au joueur...

    Evite de mettre des tabulations pour l'indentation, 2 3 espaces suffits.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    mouvement_piece(1);
    mouvement_piece(0);
    Pourquoi ne pas créer un type énumeré pour indiquer clairement ce que signifie 0 et 1.

    Uint8 tableau[tab_largeur][tab_hauteur];
    Comment tu feras le jour ou tu devras charger dynamiquement plein de niveau ?

    En effet, un tableau n'est qu'une implémentation de ton niveau, tu devrais créer une structure ou une classe.
    Un peu du genre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
     
    typedef Element...;
     
    class Niveau {
     private:
      size_t _longueur;
      size_t _largeur;
      Element* _tableau;
      Piece*    _piece; /*piece actuelle*/
      Joueur*  _joueur;
      void chutePiece();
      void forcerChute();
    ....
     public:
      Niveau(); /*allouera dynamiquement la place pour _tableau*/
      ~Niveau();
      charger(const char*);
      Element lire(int x, int y);
      size_t longueur();
      size_t largeur();
     
      void evoluer();
     ...  
    };
    Et une classe en relation direct avec le graphisme :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    class NiveauGraphique {
     private:
      chargerFonts();
      chargerSprite();
      Niveau* _niveau;
     public:
      NiveauGraphique(Niveau&);
      afficher();
      ~NiveauGraphique();
    };
    Comme tu travailles également sur des pièces, il te faudra penser à créer une class de pièce :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
     
    typedef enum {
     TRIANGLE, TRUC
    } TypePiece;
     
    class Piece {
     public:
      Piece(TypePiece);
      void tournerGauche();
      void tournerDroit();
      TypePiece getType() ;
      int getSens(); /*pour obtenir le sens actuel*/
    ...
     /*on pourrait même penser à ajouter une position à la pièce, mais 
    ça sera au niveau de gérer si il peut tourner ou non car c'est le seul
    à connaître la disposition des cases*/
     
    };
    Il faudra bien penser à définir une bonne relation entre le Niveau et la liste de pièces pour savoir quelles cases sont occupées. En gros, que le niveau n'est pas vraiment à s'occuper du type de la pièce, mais que la pièce puisse fournir au niveau les infos nécessaires pour qu'il connaisse les cases occupés par la pièce.

    Evite de donner des codes d'erreur un peu à ta manière. En général, on en utilise deux : exit(EXIT_SUCCESS) ou exit(EXIT_FAILURE).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    printf("Probleme de chargement du fichier : %s\n", SDL_GetError());
    Pour des messages d'erreurs, il faut toujours utiliser fprintf(stderr, ""); car le flux stderr n'est pas bufferisé et le message d'erreur arrivera au moment ou tu écriras le message. De plus, tu es en C++, autant utiliser std::cerr<<"Mon message";

    Enfin, continue comme ça
    Je ne répondrai à aucune question technique en privé

  16. #16
    Membre confirmé
    Avatar de Mindiell
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    735
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 735
    Points : 546
    Points
    546
    Par défaut
    Ough ! Ca c'est de la critique... J'essaye de pas tout prendre mal et de répondre...

    - Pourquoi le code est-il "méchant" ?
    - Mal organisé, je veux bien, mais je fais un tout petit programme que j'adapte au fur et à mesure pour le moment. Suivant les étapes du processus de création du jeu. Tu l'aurais organisé avec un fichier .h et tout ? Ca me parait bien compliqué pour un si petit tutorial.
    - Non, je ne fais pas de C++ dans ce tuto. Je t'accorde que mon fichier s'appelle .cpp mais c'est tout je crois. En tout cas ce n'est pas le but dans ce tutorial.
    - Encore une fois pour les .h (et donc .c normalement, je l'accorde ^^), j'ai voulu montrer qu'un jeu comme Tetris n'a pas besoin de 15 personnes pendant 3 ans, ni d'une structure très complexe. Mais avec les ajouts que l'on va faire ensuite, il faudra peut-être y songer.
    - Eviter les constantes globales ? Pourquoi cela ?
    - J'ai toujours fonctionner avec les tabulations, c'est un souci pour certains éditeurs de texte, je le sais. Je vais voir si mon editeur peut me les transformer en espace à la sauvegarde. Pour la taille, 4 est une taille que j'apprécie, désolé
    - un type énuméré serait, en effet, le bienvenu ! Je vais m'en occuper.
    - Charger des niveaux dans un Tetris basique ? Non, je m'occuperais de ça dans un autre tutorial, plus tard. L'avantage de Tetris c'est qu'il reste simple, et qu'on peut donc programmer simplement.
    - Encore une fois, pas de C++, pas d'objet, pour le moment. Implémenter toute une structure c'est se compliquer la vie pour une chose aussi simple. Faites comme Herta quoi !
    - Le exit(-6) m'a simplement servi à savoir quelle image n'était pas bien chargée. J'aurais du le virer, en effet.
    - Merci pour le stderr, je vais m'en servir, ca me parait bien plus pratique en effet
    - et merci pour ton dernier encouragement !

    PS : Il ne faut cependant pas se tromper, ce tutoriel est surtout là pour montrer, peut-être de manière trop caricaturale, les différentes étapes dans la conception d'un jeu vidéo. On s'aperçoit vite que même un Tetris basique n'échappe pas à la règle, et que, en suivant ces étapes (à peu près), on arrive plus rapidement à une ébauche qui fonctionne et que l'on peut améliorer. C'est d'ailleurs ce point là qui peut-être abordé dans un autre tutoriel par quelqu'un de plus doué que moi en C : l'optimisation et le codage propre.
    Mindiell
    "Souvent, femme barrit" - Elephant man

  17. #17
    Rédacteur

    Avatar de millie
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    7 015
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 7 015
    Points : 9 818
    Points
    9 818
    Par défaut
    Le code est "méchant" au sens où il est peu facile de le faire évoluer. En effet, chaque parties sont indépendantes les unes des autres et il serait difficile pour quelqu'un de reprendre le jeu (mais si ce n'est pas ton but). Mais c'est toujours bien de voir du code qui est bien codé.

    Pour l'histoire des classes, ce n'est pas un problème en C, on peut facilement faire de la programmation orientée objet en C :

    Le code suivant en C++ :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    typedef Element...;
     
    class Niveau {
     private:
      size_t _longueur;
      size_t _largeur;
      Element* _tableau;
      Piece*    _piece; /*piece actuelle*/
      Joueur*  _joueur;
      void chutePiece();
      void forcerChute();
    ....
     public:
      Niveau(); /*allouera dynamiquement la place pour _tableau*/
      ~Niveau();
      charger(const char*);
      Element lire(int x, int y);
      size_t longueur();
      size_t largeur();
     
      void evoluer();
     ...  
    };
    Devient ceci en C :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
     
    #ifndef NIVEAU_H
    #define NIVEAU_H
    /*Fichier .h*/
    typedef Element...;
     
    typedef struct {
     private:
      size_t _longueur;
      size_t _largeur;
      Element* _tableau;
      Piece*    _piece; /*piece actuelle*/
      Joueur*  _joueur;
    } Niveau;
     
    Niveau* niveauCreer(void);
    void      niveauDetruire(Niveau*);
    void      niveauCharger(Niveau*, const char*);
    Element niveauLire(Niveau*, int x, int y);
    size_t    niveauLongueur(Niveau*);
    size_t    niveauLargeur(Niveau*);
    void niveauEvoluer(Niveau* );
     
    #endif
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    #include "niveau.h"
     
    /*fonction privée*/
    static void niveauChutePiece(Niveau*);
    static void niveauForcerChute(Niveau*);
     
    + implémentation des fonctions définie dans le .c


    Attention, ne prends surtout pas mal mes remarques. Je sais qu'il n'est pas simple de programmer proprement au début et on a souvent tendance à tout mettre tout le "bazar" ensemble.

    Mais c'est bien de donner de bonne méthode de programmation dès le début je pense.


    Jette un oeil à cette page :
    http://emmanuel-delahaye.developpez....ques-codage-c/
    Je ne répondrai à aucune question technique en privé

  18. #18
    Membre confirmé
    Avatar de Mindiell
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    735
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 735
    Points : 546
    Points
    546
    Par défaut
    Citation Envoyé par millie
    Je sais qu'il n'est pas simple de programmer proprement au début et on a souvent tendance à tout mettre tout le "bazar" ensemble.
    Ca fait juste 20 que je code

    Mais ne t'inquiète pas, ca fait longtemps que je n'ai pas touché au C, et dans le cas d'un Tetris, je ne me voyais pas (surtout pour les lecteurs en fait) partir sur un code tout optimisé. Je préfère partir sur un code moins bon et leur faire comprendre le principe des étapes de la conception.

    J'ai eu un peu mal avec tes remarques, mais j'ai vu suffisamment de tes posts pour ne pas mal le prendre : ca serait idiot vu que tu critiques intelligemment

    Citation Envoyé par millie
    Le code est "méchant" au sens où il est peu facile de le faire évoluer. En effet, chaque parties sont indépendantes les unes des autres et il serait difficile pour quelqu'un de reprendre le jeu (mais si ce n'est pas ton but).
    Bon, là je comprends ... En effet, ce n'est pas fait pour être repris tel quel. Cependant, mon prochain tutorial (un shoot them up ?) sera orienté objet et surement plus "ré-utilisable". C'est aussi important en JV que dans d'autres domaines afin de ne pas avoir à ré-inventer la roue à chaque fois.

    Pour le reste, non, vraiment pas possible de faire des classes et de l'objet pour un simple tetris : ca dépasse mon entendement
    Mindiell
    "Souvent, femme barrit" - Elephant man

  19. #19
    Membre confirmé
    Avatar de Mindiell
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    735
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 735
    Points : 546
    Points
    546
    Par défaut
    Hop !
    Au passage de cette intéressante discussion, voici la dernière source avant l'année prochaine : La destruction des lignes complètes.

    J'en ai profité pour cacher le curseur de la souris au démarrage du programme.

    La prochaine fois je tâcherais d'ajouter le comptage des points et la fin de partie. D'ici là, je vais me tourner vers l'affichage de caractères en SDL

    PS millie : pas de fichiers .h me permet aussi de ne poster qu'un seul fichier ici. je l'avoue c'est pas une raison forcément suffisante, mais bon
    Fichiers attachés Fichiers attachés
    Mindiell
    "Souvent, femme barrit" - Elephant man

  20. #20
    Rédacteur

    Avatar de millie
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    7 015
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 7 015
    Points : 9 818
    Points
    9 818
    Par défaut
    Je ne sais pas si un tetris est forcement si simple que ça.

    Essayer de faire des choses modulaires me semble vraiment essentiel pour moi. Ne pas tout mélanger dans un fichier permet déjà de rendre plus compréhensible chaque partie du code. Rien qu'en regardant le nom des fichiers, on voit tout de suite (oki, ça, ça sert pour une pile, ça pour les niveaux, ça pour le graphisme, ça pour les ennemis). Quand on veut voir ce que les modules font, on regarde juste dans le .h le nom des fonctions et le commentaire qu'il y a. Et ça devient plus rapide de s'approprier du code sans regarder l'implémentation (les .c) proprement dit.

    Tu peux regarder un jeu que j'avais fait (Boulder Dash), qui n'est pas si compliqué que ça, mais que j'ai rendu fortement modulaire :
    http://humbert-florent.developpez.co.../jeux/boulder/

    Il y a des modules pour tout : liste, ennemis, diamants, pierre, joueur, graphisme.

    Jette un oeil par exemple au niveau (dans src/niveau/niveau.h) je crois. J'ai défini le niveau de manière très simpliste (c'est à dire les opérations minimales que l'on souhaite faire dessus). Ca rend plus simple l'utilisation de cet "objet" car son implémentation est totalement détachée.

    Par exemple avec les opérations suivantes :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    /* fait évoluer le temps du niveau*/
    void niveauEvoluerTemps(Niveau* niveau);
     
    /* lit le temps restant en int (en seconde)*/
    int niveauLireTempsRestant(Niveau* niveau);
     
    int niveauChargement(Niveau* niveau, const char*); 
     
    ...

    De plus, ça rend beaucoup plus simple les tests et le débogage. Pour chaque module, on réalise un fichier qui teste uniquement ce module. Une fois que les tests sont passés, on est "presque" sûr que le module est valide.

    PS millie : pas de fichiers .h me permet aussi de ne poster qu'un seul fichier ici. je l'avoue c'est pas une raison forcément suffisante, mais bon
    Tu peux les zipper

    les différentes étapes dans la conception d'un jeu vidéo.
    Et justement, une partie de la conception, c'est vraiment de définir les .h (les modules et les objets) que l'on aura à utiliser.
    Je ne répondrai à aucune question technique en privé

Discussions similaires

  1. [Projets]apprendre en s'amusant
    Par Ar-t dans le forum Général Java
    Réponses: 5
    Dernier message: 04/11/2008, 15h14
  2. [SOURCE][SDL][JEU] Le Pendu
    Par Franck.H dans le forum Contribuez
    Réponses: 6
    Dernier message: 16/04/2008, 17h49
  3. [Source][SDL] jeu type Zelda 3
    Par kor6k dans le forum Contribuez
    Réponses: 29
    Dernier message: 27/07/2007, 09h03
  4. [Source] [SDL] Commencement d'un casse brique
    Par grincheux01 dans le forum Contribuez
    Réponses: 8
    Dernier message: 29/06/2006, 12h27

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo