Partage
  • Partager sur Facebook
  • Partager sur Twitter

gestion de plusieurs niveaux en SDL

sur le TP Sokoban

    29 avril 2006 à 15:42:23

    Bonjour tous les zéros; ;)

    ayant réussi à coder une partie du sokoban tout seul (à vrai dire que le main.c et le jeu.c, et aussi une petite partie de l'éditeur :p ),j'ai commencé à améliorer ce jeu, en affichant une image de félicitations lorsqu'on avait gagné ou encore un mode d'emploi sur le menu. En revanche, j'ai du mal à faire en sorte qu'il y ait plusieurs niveaux dans mon jeu. Je suis donc aller relire le tuto "lire et écrire dans des fichiers" par M@théo21 (je l'ai relus 3 fois). Il me semble l'avoir assez bien compris, et pourtant je ne vois toujours pas comment réussir à coder plusieurs niveaux (je pense qu'il me faudrait créer un fichier .txt ou .cequejeveux avec une suite de 104 chiffres allant de 0 à 4), mais je ne vois pas comment faire en sorte que à chaque fois que je finisse un niveau, le fichier suivant s'ouvre s'ouvre.

    Alors pourriez-vous m'expliquez comment faire, ou encore me montrer la partie du code qui m'intéresse (si vous ne souhaitez pas me montrer une partie de votre code source, au moins expliquez moi s'il vous plait :( )?

    Voilà, j'espère que vous pourrez m'aider. :)

    Merci d'avance.
    • Partager sur Facebook
    • Partager sur Twitter
    Anonyme
      30 avril 2006 à 2:54:34

      Salut,

      Tu créer un fichier niveaux.lvl (par exemple) et tu met un niveau par ligne dedans.
      Quand t'es au premier niveau tu lis la première ligne, quand t'es deuxième niveau tu lis la 2eme ligne etc...
      Dans le fichier a la fin de chaque niveau il y a le caractère de retour à la ligne "\n".

      Pour te positionner au bon endroit dans le fichier, il te sufit de faire une boucle qui regarde tout les caractères et qui compte combien de fois apparait '\n'. Si il apparait 0 foi c'est que soit le fichier est vide soit que tu as 1 niveau. Si il apparait 1 foi c'est que tu as 2 niveau. ansi de suite.

      une fois que t'es placer t'as plus qu'à lire la ligne et à l'afficher

      M'enfin j'ai pas tout dit hein ^^
      Normalement si ta bien comprit ce que j'ai écrit tu ne devrait pas avoir trop de mal à faire ce que tu veux.
      • Partager sur Facebook
      • Partager sur Twitter
        30 avril 2006 à 11:36:03

        Au lieu de lire tous les caractères jusqu'au '\n', fais un fseek, smieux :p
        • Partager sur Facebook
        • Partager sur Twitter
          30 avril 2006 à 11:44:53

          fseek ne te permettra pas de détecter des fins de lignes et aussi
          fseek est illégal avec un flux ouvert en mode texte sauf si c'est pour
          restaurer une position récupérée avec ftell précédemment, aller au
          début ou à la fin du fichier.

          Ceci dit, utiliser fseek /et/ un fichier binaire est une bonne idée
          mais un poil plus complexe à mettre en ½uvre. Mais plus simplement, tu
          peux nommer tes fichiers dans l'ordre 1, 2, etc. et tu tentes d'ouvrir
          le prochain avec fopen et si ça foire tu en déduis que soit il
          n'existe pas, soit tu n'y as pas accès, ce qui au final revient au
          même puisque le joueur ne pourra pas le jouer. :p
          • Partager sur Facebook
          • Partager sur Twitter
            30 avril 2006 à 20:42:29

            Merci pour vos réponses. :)
            mais... ne serait-ce pas mieux (ou plutôt plus simple :p ) de recréer une fonction chargerNiveau pour chaque niveau? (chargerNiveau1, chargerNiveau2...)

            Merci encore :)
            • Partager sur Facebook
            • Partager sur Twitter
              30 avril 2006 à 21:38:04

              t'encombrerais la memoire vive
              mais pour un petit jeu comme ca ca va
              • Partager sur Facebook
              • Partager sur Twitter
              Anonyme
                30 avril 2006 à 21:57:29

                Le problème c'est que si tu veut rajouter un niveau il faut que tu edite les sources et que tu recompiles tout. Pi si t'as 100 niveaux sa te fera 100 fonctions o_O
                Que si tu te débrouille bien, avec une seule fonction tu peut metre autant de niveau que tu veut dans le fichier texte sans éditer une seule source ;)
                • Partager sur Facebook
                • Partager sur Twitter
                  1 mai 2006 à 19:45:21

                  non que je ne te crois pas, TheDead Master, (loin de la rassures-toi ;) ), j'ai tout de même préféré essayer de refaire une fonction pour chaque niveaux... mais il y a un problème : impossible d'éditer le niveau 2... je vous passe mon code source (il s'agit de celui de mathéo21, car j'avoue ne pas avoir réussi à faire le fichier.c tout seul :-° ):

                  /*
                  fichiers.c
                  ----------

                  Par Orüme (avec la très vive coopération de Mathéo21), le 29/04/2006.

                  Rôle : fonctions de lecture / écriture de fichiers de niveau.
                  */


                  #include <stdlib.h>
                  #include <stdio.h>
                  #include <SDL/SDL.h>
                  #include <SDL/SDL_image.h>

                  #include "constantes.h"
                  #include "fichiers.h"

                  int chargerNiveau(int niveau[][NB_BLOCS_HAUTEUR])
                  {
                      FILE* fichier = NULL;
                      char ligneFichier[NB_BLOCS_LARGEUR * NB_BLOCS_HAUTEUR + 1] = {0};
                      int i = 0, j = 0;

                      fichier = fopen("niveau1.lvl", "r");
                      if (fichier == NULL)
                          return 0;

                      fgets(ligneFichier, NB_BLOCS_LARGEUR * NB_BLOCS_HAUTEUR + 1, fichier);

                      for (i = 0 ; i < NB_BLOCS_HAUTEUR ; i++)
                      {
                          for (j = 0 ; j < NB_BLOCS_LARGEUR ; j++)
                          {
                              switch (ligneFichier[(i * NB_BLOCS_LARGEUR) + j])
                              {
                                  case '0':
                                      niveau[j][i] = 0;
                                      break;
                                  case '1':
                                      niveau[j][i] = 1;
                                      break;
                                  case '2':
                                      niveau[j][i] = 2;
                                      break;
                                  case '3':
                                      niveau[j][i] = 3;
                                      break;
                                  case '4':
                                      niveau[j][i] = 4;
                                      break;
                              }
                          }
                      }

                      fclose(fichier);
                      return 1;
                  }

                  int sauvegarderNiveau(int niveau[][NB_BLOCS_HAUTEUR])
                  {
                      FILE* fichier = NULL;
                      int i = 0, j = 0;

                      fichier = fopen("niveau2.lvl", "w+");
                      if (fichier == NULL)
                          return 0;

                      for (i = 0 ; i < NB_BLOCS_HAUTEUR ; i++)
                      {
                          for (j = 0 ; j < NB_BLOCS_LARGEUR ; j++)
                          {
                              fprintf(fichier, "%d", niveau[j][i]);
                          }
                      }

                      fclose(fichier);
                      return 1;
                  }


                  int chargerNiveau2(int niveau[][NB_BLOCS_HAUTEUR])
                  {
                      FILE* fichier = NULL;
                      char ligneFichier[NB_BLOCS_LARGEUR * NB_BLOCS_HAUTEUR + 1] = {0};
                      int i = 0, j = 0;

                      fichier = fopen("niveau2.lvl", "r");
                      if (fichier == NULL)
                          return 0;

                      fgets(ligneFichier, NB_BLOCS_LARGEUR * NB_BLOCS_HAUTEUR + 1, fichier);

                      for (i = 0 ; i < NB_BLOCS_HAUTEUR ; i++)
                      {
                          for (j = 0 ; j < NB_BLOCS_LARGEUR ; j++)
                          {
                              switch (ligneFichier[(i * NB_BLOCS_LARGEUR) + j])
                              {
                                  case '0':
                                      niveau[j][i] = 0;
                                      break;
                                  case '1':
                                      niveau[j][i] = 1;
                                      break;
                                  case '2':
                                      niveau[j][i] = 2;
                                      break;
                                  case '3':
                                      niveau[j][i] = 3;
                                      break;
                                  case '4':
                                      niveau[j][i] = 4;
                                      break;
                              }
                          }
                      }

                      fclose(fichier);
                      return 1;
                  }

                  int chargerNiveau3(int niveau[][NB_BLOCS_HAUTEUR])
                  {
                      FILE* fichier = NULL;
                      char ligneFichier[NB_BLOCS_LARGEUR * NB_BLOCS_HAUTEUR + 1] = {0};
                      int i = 0, j = 0;

                      fichier = fopen("niveau3.lvl", "r");
                      if (fichier == NULL)
                          return 0;

                      fgets(ligneFichier, NB_BLOCS_LARGEUR * NB_BLOCS_HAUTEUR + 1, fichier);

                      for (i = 0 ; i < NB_BLOCS_HAUTEUR ; i++)
                      {
                          for (j = 0 ; j < NB_BLOCS_LARGEUR ; j++)
                          {
                              switch (ligneFichier[(i * NB_BLOCS_LARGEUR) + j])
                              {
                                  case '0':
                                      niveau[j][i] = 0;
                                      break;
                                  case '1':
                                      niveau[j][i] = 1;
                                      break;
                                  case '2':
                                      niveau[j][i] = 2;
                                      break;
                                  case '3':
                                      niveau[j][i] = 3;
                                      break;
                                  case '4':
                                      niveau[j][i] = 4;
                                      break;
                              }
                          }
                      }

                      fclose(fichier);
                      return 1;
                  }




                  Il me semble qu'il n'y a aucune erreur qui provoque ce problème (j'ai bien dit il me semble :-° ), mais n'hésitez pas à en trouver :D (je ous en serait même reconnaissant car je commence à en avoir marre :colere2: ).
                  • Partager sur Facebook
                  • Partager sur Twitter
                    1 mai 2006 à 19:50:33

                    ca sert a quoi de poser une question si tecoutes pas nos reponses !
                    montres nous tous les fichiers de ton code meme les headers !
                    et pour chaques conditions met un else qui inscrit une erreur dans un fichier texte pour localiser le probleme
                    • Partager sur Facebook
                    • Partager sur Twitter
                    Anonyme
                      1 mai 2006 à 20:12:36

                      J'ai regardé vite fait et je vois pas d'erreur. Mais tu dit que sa ne sauvgarde pas le niveau 2 donc sa sauvgarde le niveau 1?

                      PS: Si tu compte rester avec toute tes fonctions j'te conseil d'en faire une qui s'occupera du switch. Sa allégera ton code ;)
                      • Partager sur Facebook
                      • Partager sur Twitter
                        2 mai 2006 à 12:15:14

                        Mite-Moisie t'énerves pas : j'ai écouté vos réponses, mais avant de les appliquer j'expérimente un moyen plus simple de gérer les niveaux ;).

                        TheDead Master, merci de m'avoir fait penser à faire une seule fonction pour le switch : ça ne m'avait même pas effleurer l'esprit... Sinon pour l'éditeur, il sauvegarde sur le niveau 3 quasiment tout le temps (mais parfois il sauvegarde sur le niveau 1).

                        P.S : je ne suis pas chez moi actuellement, dnc je ne peux pas vous passer la totalité de mon code... toutefois j'essaierai de le faire le plus tôt possible ;)
                        • Partager sur Facebook
                        • Partager sur Twitter
                          2 mai 2006 à 12:42:07

                          personelement je ne croi pas qu'il y est plus simple que de faire une seul fonction qui puisse charger tout les niveaux...
                          parce que une fois que tu auras code tes 15 fonction (ou 15 case de ton switch, si tu as 15 niveau...) tu te rendra compte que tu a exactement 15 fois le meme code a l'exeption de 1 chiffre a quelque endroit...

                          donc tu remplace se chiffre (qui soit dit en passant est le nomuro du niveau que tu veut charger) par une variable qui sera initialiser dans ton apelle de fonction.

                          donc en resume au lieu de:
                          ChargNiv(int NumNiv)
                          {
                              switch(NumNiv)
                              {
                                  case 1:
                                      //charger le niveau 1
                                  break;
                                  case 2:
                                      //charger le niveau 2
                                  break;
                                  case 3:
                                      //charger le niveau 3
                                  break;
                                  case 4:
                                      //charger le niveau 4
                                  break;
                              }
                          }


                          tu auras:
                          ChargNiv(int NumNiv)
                          {
                              //charger le niveau NumNiv
                          }



                          je sait pas pour toi mais juste a regarde sa je sait se que j'aime mieu programe (je suis un programmeur normale donc tres paresseux... :p )
                          • Partager sur Facebook
                          • Partager sur Twitter
                            2 mai 2006 à 18:30:40

                            c'est sûr que ton code est mieux, djo0012. Je vais essayer de le reproduire quand je serai chez moi, même si je préférais ma méthode pour sa simplicité.

                            Merci bcp ;)
                            • Partager sur Facebook
                            • Partager sur Twitter
                              3 mai 2006 à 0:39:59

                              bha c'est toi qui voie mais si tu veut tu peu ecrire ton code avec un switch et arrete apres 3 ou 4 niveau et regarde ton code... ensuite remplace ton switch par le for ou la boucle que tu veut pour que tout les autre niveau fontionne.

                              de cette maniere tu verra reelement se que tu doit remplace pour que sa puisse fonctionne avec une boucle.

                              personellement moi je suis rendu a l'autre extreme, soit faire des boucle pour des code qui sont trop different, resultat je me retrouve avec plus de code que nescessaire pour gere tout les cas mais bon
                              • Partager sur Facebook
                              • Partager sur Twitter
                                3 mai 2006 à 1:03:33

                                C'est n'importe quoi une fonction par niveau. Ce n'est pas une solution, arrête ça de suite.

                                En fait, tu te demandes comment changer le nom du fichier à charger.
                                Pour ça, il faut utiliser une fonction comme sprintf :

                                sprintf(chaine, "niveau%ld.txt", niveau);

                                En fait, sprintf écrira dans la variable chaine le message que tu indiques (ça fonctionne comme printf mais ça écrit pas à l'écran, c'est dans une variable cette fois).

                                Ensuite t'as plus qu'à faire :

                                fopen(chaine, "r");

                                Et le tour est joué !
                                • Partager sur Facebook
                                • Partager sur Twitter

                                If you'd like to join us, read "How do we work at OpenClassrooms"! :)

                                  3 mai 2006 à 18:55:56

                                  Merci bien M@théo21.

                                  Je vais essayer sprintf dès ce soir. Enfin je vais pouvoir commercialiser mon sokoban!!!... si y a quelqu'un d'assez fou pour me l'acheter bien sur...
                                  Non sérieux je suis content que ce problème soit résolu : je savais que je ne pourrai commencer aucun autre projet de jeu tant que j'aurai pas résolu ça (un jeu ou il n'y a qu'un seul niveau c'est pas très amusant).

                                  Merci pour votre aide.

                                  (peut-être j'upperai mon sokoban pour des améliorations supplémenteaires quand j'aurai codé les niveaux... si j'ai le tps)
                                  • Partager sur Facebook
                                  • Partager sur Twitter

                                  gestion de plusieurs niveaux en SDL

                                  × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                                  × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                                  • Editeur
                                  • Markdown