Partage
  • Partager sur Facebook
  • Partager sur Twitter

Bug (seulement si vous avez le temps)

Beaucoup de temps...

    7 octobre 2007 à 18:19:58

    Bonjour.
    J'ai fais un programme en C++/SDL assez long qui s'intitule Quadra Pong.
    C'est censé être un mix de Pong avec 4 pads et des briques à casser. Jusqu'à maintenant, j'ai fait le moteur principal avec les pads, la balle mais quand j'ai codé les briques (ouverture de fichier .lvl, tableau de SDL_Surface, etc.) et que j'essaie d'ouvrir (pas de compiler, d'ouvrir) le programme, rien ne s'affiche et je dois arrêter le programe directement depuis le gestionnaire des tâches section processus).

    Alors: j'ai le fichier arial.ttf, ball.bmp, SDL.dll, SDL_image.dll, SDL_ttf.dll et mon fichier 1.lvl qui se trouve dans un sous-dossier Levels. Celui-ci contient
    1. 375 375
    2. -1 -1


    Le fichier main.cpp contient:
    1. #include <SDL/SDL.h>
    2. #include <stdio.h>
    3. #include <stdlib.h>
    4. #include <SDL/SDL_image.h>
    5. #include <time.h>
    6. #include <SDL/SDL_ttf.h>
    7. int main(int argc, char *argv[])
    8. {
    9.     int horSpeed = 4, verSpeed = 4, random = 0, maxSpeed = 2, brickNumber = 0;
    10.     int bricksRemaining = 0, level = 0, i = 0;
    11.     const int minSpeed = 2;
    12.     long nScore = 0, nowTime = 0, lastTime = 0;
    13.     char tScore[15], levelFile[30];
    14.     bool left = false, right = false, up = false, down = false, brickBroken[200] = {true};
    15.     FILE* flevel = NULL;
    16.     SDL_Surface *screen = NULL, *leftPad = NULL, *rightPad = NULL,
    17.       *upPad = NULL, *downPad = NULL, *ball = NULL, *sScore = NULL, *brick[200] = {NULL};
    18.     SDL_Rect posLeftPad, posRightPad, posUpPad, posDownPad, posBall, initPos, posScore;
    19.       posLeftPad.x = 10;
    20.       posLeftPad.y = 360;
    21.       posRightPad.x = 780;
    22.       posRightPad.y = 360;
    23.       posUpPad.x = 360;
    24.       posUpPad.y = 10;
    25.       posDownPad.x = 360;
    26.       posDownPad.y = 780;
    27.       posBall.x = 400;
    28.       posBall.y = 600;
    29.       initPos.x = 400;
    30.       initPos.y = 600;
    31.       posScore.x = 0;
    32.       posScore.y = 250;
    33.     SDL_Rect posBrick[200] = {0};
    34.     SDL_Event event;
    35.     TTF_Font *arial = NULL;
    36.     SDL_Color grey = {128, 128, 128};
    37.     flevel = fopen("Levels/1.lvl", "r"); // J'ouvre mon fichier de niveau
    38.     if (flevel == NULL)
    39.       exit(0);
    40.     level = 1;
    41.     do
    42.     {
    43.         fscanf(flevel, "%ld %ld\n", &posBrick[brickNumber].x, &posBrick[brickNumber].y);
    44.         brickBroken[brickNumber] = false;
    45.         brickNumber++;
    46.         bricksRemaining++;
    47.     } while (posBrick[brickNumber].x != -1);
    48.     SDL_Init(SDL_INIT_VIDEO);
    49.     atexit(SDL_Quit);
    50.     TTF_Init();
    51.     arial = TTF_OpenFont("arial.ttf", 300);
    52.     SDL_WM_SetCaption("Quadra Pong", NULL);
    53.     SDL_WM_SetIcon(SDL_LoadBMP("ball.bmp"), NULL);
    54.     screen = SDL_SetVideoMode(800, 800, 32, SDL_HWSURFACE | SDL_DOUBLEBUF);
    55.     SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 0, 0, 0));
    56.     leftPad = SDL_CreateRGBSurface(SDL_HWSURFACE, 10, 115, 32, 0, 0, 0, 0); //Je crée les surfaces
    57.     SDL_FillRect(leftPad, NULL, SDL_MapRGB(screen->format, 128, 128, 128));
    58.     rightPad = SDL_CreateRGBSurface(SDL_HWSURFACE, 10, 115, 32, 0, 0, 0, 0);
    59.     SDL_FillRect(rightPad, NULL, SDL_MapRGB(screen->format, 128, 128, 128));
    60.     upPad = SDL_CreateRGBSurface(SDL_HWSURFACE, 115, 10, 32, 0, 0, 0, 0);
    61.     SDL_FillRect(upPad, NULL, SDL_MapRGB(screen->format, 128, 128, 128));
    62.     downPad = SDL_CreateRGBSurface(SDL_HWSURFACE, 115, 10, 32, 0, 0, 0, 0);
    63.     SDL_FillRect(downPad, NULL, SDL_MapRGB(screen->format, 128, 128, 128));
    64.     ball = SDL_LoadBMP("ball.bmp");
    65.     SDL_SetColorKey(ball, SDL_SRCCOLORKEY, SDL_MapRGB(ball->format, 0, 0, 0));
    66.     for(i = 0; i < brickNumber; i++) //puis celles des briques
    67.     {
    68.         brick[i] = SDL_CreateRGBSurface(SDL_HWSURFACE, 50, 50, 32, 0, 0, 0, 0);
    69.         SDL_FillRect(brick[i], NULL, SDL_MapRGB(screen->format, 200, 200, 200));
    70.     }
    71.     while (1)
    72.     {
    73.         if(bricksRemaining == 0) //Au cas ou je changerais de niveau
    74.           {
    75.               fclose(flevel);
    76.               level++;
    77.               sprintf(levelFile, "Levels\%ld.lvl", level);
    78.               flevel = fopen(levelFile, "r");
    79.               if (flevel == NULL)
    80.                 exit(0);
    81.               brickNumber = 0;
    82.               do
    83.               {
    84.                   fscanf(flevel, "%ld %ld\n", &posBrick[brickNumber].x, &posBrick[brickNumber].y);
    85.                   brickBroken[brickNumber] = false;
    86.                   brickNumber++;
    87.                   bricksRemaining++;
    88.               } while (posBrick[brickNumber].x != -1);
    89.               for(i = 0; i < brickNumber; i++)
    90.               {
    91.                   brick[i] = SDL_CreateRGBSurface(SDL_HWSURFACE, 50, 50, 32, 0, 0, 0, 0);
    92.                   SDL_FillRect(brick[i], NULL, SDL_MapRGB(screen->format, 200, 200, 200));
    93.               }
    94.           }
    95.         SDL_PollEvent(&event);  // Gestion des évènements
    96.         switch(event.type)
    97.         {
    98.             case SDL_QUIT:
    99.             exit(0);
    100.             break;
    101.             case SDL_KEYDOWN:
    102.             switch(event.key.keysym.sym)
    103.             {
    104.                 case SDLK_UP:
    105.                 up = true;
    106.                 break;
    107.                 case SDLK_DOWN:
    108.                 down = true;
    109.                 break;
    110.                 case SDLK_LEFT:
    111.                 left = true;
    112.                 break;
    113.                 case SDLK_RIGHT:
    114.                 right = true;
    115.                 break;
    116.                 case SDLK_KP1:
    117.                 maxSpeed = 1;
    118.                 break;
    119.                 case SDLK_KP2:
    120.                 maxSpeed = 2;
    121.                 break;
    122.                 case SDLK_KP3:
    123.                 maxSpeed = 3;
    124.                 break;
    125.             }
    126.             break;
    127.             case SDL_KEYUP:
    128.             switch(event.key.keysym.sym)
    129.             {
    130.                 case SDLK_UP:
    131.                 up = false;
    132.                 break;
    133.                 case SDLK_DOWN:
    134.                 down = false;
    135.                 break;
    136.                 case SDLK_LEFT:
    137.                 left = false;
    138.                 break;
    139.                 case SDLK_RIGHT:
    140.                 right = false;
    141.                 break;
    142.             }
    143.         }
    144.         if (up && posLeftPad.y != 0)          // Je bouge les pads
    145.         {
    146.             posLeftPad.y -= maxSpeed * 4;
    147.             posRightPad.y -= maxSpeed * 4;
    148.         }
    149.         if (down && posLeftPad.y <= 685)
    150.         {
    151.             posLeftPad.y += maxSpeed * 4;
    152.             posRightPad.y += maxSpeed * 4;
    153.         }
    154.         if (left && posUpPad.x != 0)
    155.         {
    156.             posUpPad.x -= maxSpeed * 4;
    157.             posDownPad.x -= maxSpeed * 4;
    158.         }
    159.         if (right && posUpPad.x <= 685)
    160.         {
    161.             posUpPad.x += maxSpeed * 4;
    162.             posDownPad.x += maxSpeed * 4;
    163.         }
    164.         if (posBall.x <= 20 || posBall.x >= 748)
    165.         {
    166.             if ((posLeftPad.y - 32) <= posBall.y && (posLeftPad.y + 115) >= posBall.y)    //J'envoie la balle à diffrentes places dépendant de ou elle frappe le pad
    167.             {
    168.                      if (posBall.y >= posLeftPad.y - 32 && posBall.y < posLeftPad.y - 11)
    169.                   verSpeed = maxSpeed * (-3);
    170.                 else if (posBall.y >= posLeftPad.y - 11 && posBall.y < posLeftPad.y + 10)
    171.                   verSpeed = maxSpeed * (-2);
    172.                 else if (posBall.y >= posLeftPad.y + 10 && posBall.y < posLeftPad.y + 31)
    173.                   verSpeed = maxSpeed * (-1);
    174.                 else if (posBall.y >= posLeftPad.y + 31 && posBall.y < posLeftPad.y + 52)
    175.                   verSpeed = 0;
    176.                 else if (posBall.y >= posLeftPad.y + 52 && posBall.y < posLeftPad.y + 73)
    177.                   verSpeed = maxSpeed;
    178.                 else if (posBall.y >= posLeftPad.y + 73 && posBall.y < posLeftPad.y + 94)
    179.                   verSpeed = maxSpeed * 2;
    180.                 else if (posBall.y >= posLeftPad.y + 94 && posBall.y < posLeftPad.y +115)
    181.                   verSpeed = maxSpeed * 3;
    182.                 horSpeed *= -1;
    183.                 nScore++;
    184.             }
    185.             else
    186.             {
    187.                 posBall.x = initPos.x;
    188.                 posBall.y = initPos.y;
    189.                 nScore = 0;
    190.             }
    191.         }
    192.         if (posBall.y <= 20 || posBall.y >= 748)                                          //Même chose
    193.         {
    194.             if ((posUpPad.x - 32) <= posBall.x && (posUpPad.x + 115) >= posBall.x)
    195.             {
    196.                      if (posBall.x >= posUpPad.x - 32 && posBall.x < posUpPad.x - 11)
    197.                   horSpeed = maxSpeed * (-3);
    198.                 else if (posBall.x >= posUpPad.x - 11 && posBall.x < posUpPad.x + 10)
    199.                   horSpeed = maxSpeed * (-2);
    200.                 else if (posBall.x >= posUpPad.x + 10 && posBall.x < posUpPad.x + 31)
    201.                   horSpeed = maxSpeed * (-1);
    202.                 else if (posBall.x >= posUpPad.x + 31 && posBall.x < posUpPad.x + 52)
    203.                   horSpeed = 0;
    204.                 else if (posBall.x >= posUpPad.x + 52 && posBall.x < posUpPad.x + 73)
    205.                   horSpeed = maxSpeed;
    206.                 else if (posBall.x >= posUpPad.x + 73 && posBall.x < posUpPad.x + 94)
    207.                   horSpeed = maxSpeed * 2;
    208.                 else if (posBall.x >= posUpPad.x + 94 && posBall.x < posUpPad.x +115)
    209.                   horSpeed = maxSpeed * 3;
    210.                 verSpeed *= -1;
    211.                 nScore++;
    212.             }
    213.             else  //Si je manque la balle
    214.             {
    215.                 posBall.x = initPos.x;
    216.                 posBall.y = initPos.y;
    217.                 nScore = 0;
    218.             }
    219.         }
    220.         posBall.x += horSpeed;  //Je bouge la balle
    221.         posBall.y += verSpeed;
    222.         sprintf(tScore, "%ld", nScore);                        //le score
    223.         sScore = TTF_RenderText_Solid(arial, tScore, grey);
    224.         posScore.x = 400 - (sScore->w / 2);
    225.         SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 0, 0, 0)); //Blittage des surfaces
    226.         SDL_BlitSurface(leftPad, NULL, screen, &posLeftPad);
    227.         SDL_BlitSurface(rightPad, NULL, screen, &posRightPad);
    228.         SDL_BlitSurface(upPad, NULL, screen, &posUpPad);
    229.         SDL_BlitSurface(downPad, NULL, screen, &posDownPad);
    230.         SDL_BlitSurface(sScore, NULL, screen, &posScore);
    231.         SDL_BlitSurface(ball, NULL, screen, &posBall);
    232.         for(i = 0; i < brickNumber; i++)       //Blittage des briques
    233.         {
    234.             if (!brickBroken[i])
    235.               SDL_BlitSurface(brick[i], NULL, screen, &posBrick[i]);
    236.         }
    237.         SDL_Flip(screen);
    238.         nowTime = SDL_GetTicks();               //Un frame tous les 40ms
    239.         if (nowTime < lastTime + 40)
    240.           SDL_Delay((lastTime + 40) - nowTime);
    241.         lastTime = nowTime;
    242.     }
    243.     return 0;
    244. }

    Le score était pour la "version beta" (sans briques)

    Merci d'avoir lu jusqu'ici et encore plus si vous avez commencé à bosser sur le bug.
    • Partager sur Facebook
    • Partager sur Twitter
    Anonyme
      7 octobre 2007 à 18:35:55

      Je vais tenter de lire ton code (mais je te garantis rien). Mais je peux dors et déjà te dire que ce n'est absolument pas du C++! (pas de string mais des char* avec sprintf et des FILE et pas de [o/i]fstream, après pas d'OO , et j'en passe...)
      T'auras p'têtre plus de monde pour t'aider dans la rubrique C du forum.

      (Si tu veux te forcer à passer au C++, prends une biblio C++)

      EDIT : désolé mais j'abandonne, j'ai trop oublié comment fonctionnait les fonction de stdio et stdlib pour t'aider. Si tu le refais en C+, peut-être que.... ;)
      • Partager sur Facebook
      • Partager sur Twitter
        7 octobre 2007 à 18:42:10

        tu ne fais pas du tout de programation modulaire (et tu t'en mords les doigts maintenant :( )

        et tu n'as crées aucune fonction!!

        (pour de petit programme,ce n'est pas grave mais la...)

        je vais jeter un oeil à ton code mais...

        • Partager sur Facebook
        • Partager sur Twitter
          7 octobre 2007 à 20:26:28

          C'est qu'il y a certaines choses que je maitrise en C++ mais certaines choses me sont plus familières en C. Puisque le C ne prends pas les choses de C++, j'ai préféré faire du C++ pour avoir toutes les options possibles. Essaie de le compiler en C, tu verras.

          Quoique c'est vrai que j'aurais pu m'en tenir au C.

          Pour la programmation modulaire, euh, oui c'est vrai mais bon, ça m'aurait servi à quoi? Tant qu'à changer de fichier, je préfère tout avoir au meme endroit. Et le code n'aurait pas été plus court. Je n'ai pas créé de fonction mais je ne vois pas à quoi ça aurait servi... Je ne vois rien qui est répété dans le code (donc qui aurait vallu la peine d'être mis en fonction) mais si tu as des idées, n'hésites pas à me les proposer, ça améliorerait ma programmation. :D
          • Partager sur Facebook
          • Partager sur Twitter
          Anonyme
            7 octobre 2007 à 20:38:34

            -> Il n'y a rien de ++ dans ton code.

            -> (Modularité : ) C'est très utile pour la lisibilité : rien que pour nous si on doit lire ton code. On peut ainsi mieux comprendre le fonctionnement. Ca permet aussi de trouver rapidement d'où vient le problème (une ligne par partie à commenter).

            -> Tu veux profiter des avantages du C++ en faisant du C+- c'est bête : que du gachi; même aucun avantage dans ton code. Si tu utilisais au moins la STL pour te simplifier la vie...
            • Partager sur Facebook
            • Partager sur Twitter
              7 octobre 2007 à 20:41:53

              en fait c'est pas le fait de retrecire ton code mais de le rendre plus lisible. comme l'a dit hiura ;)

              petite chose exit(0); ne quite pas le programme
              il faut ecrire exit(EXIT_FAILURE) ou exit(1) ^^

              derniere chose tu ne libere pas la memoire alloué à tes surface en fin de programe??

              • Partager sur Facebook
              • Partager sur Twitter
                7 octobre 2007 à 21:31:34

                Oh mon Dieu!! C'est vraiment atroce comme code! (désole d'être aussi cru...).
                • Partager sur Facebook
                • Partager sur Twitter
                  8 octobre 2007 à 18:04:16

                  Citation : bogoss

                  Oh mon Dieu!! C'est vraiment atroce comme code! (désole d'être aussi cru...).



                  Ok, merci de ta critique "constructive"

                  Et merci pour le truc de EXIT_FAILURE.

                  Et je croyait que SDL_Quit() libérait toutes les surfaces...
                  • Partager sur Facebook
                  • Partager sur Twitter
                    8 octobre 2007 à 18:24:55

                    Pour ton problème en tant que tel, je crois que tu as une boucle infini à quelque part.

                    sachant que tu as seulement deux boucles qui "pourrais" poser problème (la boucle while(1) est exclu, ainsi que les boucle for), vérifie si la condition est possible à réaliser, d'une manière ou d'une autre.
                    • Partager sur Facebook
                    • Partager sur Twitter
                    Altarapp.com - Applications, Code Snippets, API Wrappers et etc, le tout en C# le plus clair du temps!
                      8 octobre 2007 à 20:15:02

                      ...pour ton switch pour les evenement SDL j'ai un petit probleme pour te suivre...

                      tu souhaites combiner plusieurs touches???
                      • Partager sur Facebook
                      • Partager sur Twitter
                        8 octobre 2007 à 22:36:01

                        euh ... j'ai pas eu le courage de tout lire mais je confirme ce qui a déjà été dis si tu veux faire quelque chose de correct refais tout ton code ou modifie le grandement

                        Par exemple : creer une classe pour ta balle de pong ! ensuite une méthode pour gérer ses déplacements et hop 50 lignes en moins dans le corps du programme

                        tu peux toujours créer une classe joueurs comme ça taque tu mécanises les entrés en matières des joueurs (vuet rien dire mais je me compreds ;-) )

                        si ça a pu t'aider

                        icare
                        • Partager sur Facebook
                        • Partager sur Twitter
                          8 octobre 2007 à 23:48:19

                          Oui effectivement le fait de créer une classe pour la balle qui contient en attributs ses coordonnées et des méthodes pour les déplacements, ça reduirait pas mal le code et surtout ça serait plus C++ déjà... Mais le problème c'est que ton code, c'est que du C pour le moment!

                          Et sinon, pour le côté modulaire je confirme également que c'est pour une question de lisibilité et de compréhension du code, pas dans un but d'avoir moins de ligne. Tout comme les fonctions, elles sont en effet pratiques pour des opérations répétées plusieurs fois mais rien n'empêche de faire une fonction que t'apelle qu'une seule fois mais qui aura pour but d'éclaicir le code!

                          Exemple: une fonction chargerNiveau(), même si t'as qu'un seul niveau dans ton jeu par exemple, et qu'elle ne te servira qu'une fois, c'est quand même plus clair de passer par une fonction que de balancer 200 lignes de code juste pour ça en plein milieu du main (après c'est mon avis personnel)
                          • Partager sur Facebook
                          • Partager sur Twitter
                            9 octobre 2007 à 17:52:37

                            Merci, toutes vos suggestions m'aident beaucoup.
                            Il faut dire que je ne suis pas très doué en programmation.
                            Mon avantage à moi d'avoir moins de fonctions et tout dans main.cpp c'est que apres je le balance à mes amis en disant

                            "Vous comprenez rien, hein?, hein? C'est parce que c'est de la programmation en C++, pas du RPG-Maker déjà tout fait, non, non. Même que les membres du Site du Zéro aussi, ils comprennent rien. Y a juste le compilateur qui comprend, et encore..."


                            Mais c'est vrai que pour quand j'ai des bugs et que je le montre à des gens qui s'y connaissent, ça m'aiderait qu'ils comprennent. Et ça a l'air tout aussi savant si c'est organisé...

                            Pour mes prochains programmes je vais utiliser vos conseils en tous cas. Merci!

                            Ca règle toujours pas mon problème de chargement de niveau, ça... :-°
                            • Partager sur Facebook
                            • Partager sur Twitter
                              9 octobre 2007 à 19:02:24

                              Citation : Pas de titre

                              Ca règle toujours pas mon problème de chargement de niveau, ça...


                              j'ai donné un indice pour ton problème, regarde mon post plus haut ;)
                              • Partager sur Facebook
                              • Partager sur Twitter
                              Altarapp.com - Applications, Code Snippets, API Wrappers et etc, le tout en C# le plus clair du temps!

                              Bug (seulement si vous avez le temps)

                              × 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