Partage
  • Partager sur Facebook
  • Partager sur Twitter

[SDL] Deux problèmes avec mon jeu

Collision laser/monstre et victoire

Sujet résolu
    19 avril 2006 à 18:21:32

    Salut à tous
    Je suis en train de programmer un ptti jeu genre Space Invaders (mais différent quand même) et je rencontre deux problèmes.

    Le premier : quand j'appuie sur Espace, ça active le blittage des lasers. Si un laser touche un monstre (appelés petes dans mon jeu), il doit disparaitre. Dans mon code, je tire une fois puis à chaque fois qu'ils touchent l'endroit ou j'ai tiré ils disparaissent au lieu de disparaitre quand je tire.

    Le deuxième : J'ai une fonction blittage et jouer. Lorsqu'un monste disparait, il incrémente un compteur de victoire et lorsque qu'il arrive à 10 (le nombre de monstres) on doit gagner. Evidemment, ça marche pas.
    Le code concerné :
    // blit.c


    // Blittage des lasers
        if(laserok)
        {
            while(i != nbrei)
            {
                nbrei++;
                while(positionLaser[nbrei].y > 0)
                {
                    positionLaser[nbrei].y-=5;
                    if(positionLaser[nbrei].y > 0)
                    {
                        SDL_BlitSurface(laser, NULL, ecran, &positionLaser[nbrei]);
                    }
                }
            }

            // Si un laser touche un pete
            for(y = 0; y < 10; y++)
            {
                positionPete2 = positionPete[y].x + 39;
                if(positionLaser->x > positionPete[y].x && positionLaser->x < positionPete2)
                {
                    peteEnVie[y] = 0;
                }
            }

            nbrei = 0;
            laserok = 0;
        }

        // On blitte les petes
        for(y = 0; y < 10; y++)
        {
            // Si le pete n°y est en vie, on le blitte
            if(peteEnVie[y] == 1)
            {
                positionPete[y].x+= direction_x[y] * 5;
                positionPete[y].y+= direction_y[y] * 5;
                SDL_BlitSurface(pete, NULL, ecran, &positionPete[y]);
            }

            // Sinon compteurVictoire augmente de 1
            if(peteEnVie[y] == 0)
            {
                *cv++;
            }
        }



    // jeu.c (juste après le code du dessus)

    // Si tous les petes sont morts, on gagne !
            if(cv == 10)
            {
                sleep(2000);
                continuer = 0;
            }

    dans la déclaration de fonction (blit), j'ai bien mit "long *cv" et dans l'appel de la fonction blit j'ai bien mit "&cv".

    Merci d'avance pour votre aide
    • Partager sur Facebook
    • Partager sur Twitter
      19 avril 2006 à 18:43:44

                while(positionLaser[nbrei].y > 0)
                  {
                      positionLaser[nbrei].y-=5;
                      if(positionLaser[nbrei].y > 0)
                      {
                          SDL_BlitSurface(laser, NULL, ecran, &positionLaser[nbrei]);
                      }
                  }


      A ta place pour économiser un teste j'aurais plutot fait :

                while(positionLaser[nbrei].y > 0)
                  {
                      SDL_BlitSurface(laser, NULL, ecran, &positionLaser[nbrei]);
                      positionLaser[nbrei].y-=5;
                  }


      Sinon d'après ce que je vois tu vérifies bien si un laser est sur la trajectoire d'un monstre (tu vérifies l'abscisse du laser par rapport à celle du monstre) mais tu ne vérifies pas si le laser se trouve à la même hauteur (si il a la même ordonnée que le monstre) avant de tuer le monstre.. :)

      EDIT : je viens de me rendre compte que ton code pour les lasers ne risque pas de marcher... attend je regarde ca plus en détail ^^
      • Partager sur Facebook
      • Partager sur Twitter
      Inkamath on GitHub - Interpréteur d'expressions mathématiques. Reprise du développement en cours.
        19 avril 2006 à 19:11:26

        juste un chose évite les mot abrégé pour t'est variable sa complique a mon avis le code
        • Partager sur Facebook
        • Partager sur Twitter
          19 avril 2006 à 19:45:21

          Si si pour les lasers ça marche parce que à chaque fois qu'on clique sur Espace ça fait
          i++;
          .
          Donc normalement c'est bon.

          Pour les noms abrégés, je sais parfaitement que ça rent le code moins compréhensible, mais je suis un programmeur plus flemmard que la moyenne ^^ .
          • Partager sur Facebook
          • Partager sur Twitter
            19 avril 2006 à 21:03:46

                        while(positionLaser[nbrei].y > 0)
                        {
                            positionLaser[nbrei].y-=5;
                            if(positionLaser[nbrei].y > 0)
                            {
                                SDL_BlitSurface(laser, NULL, ecran, &positionLaser[nbrei]);
                            }
                        }


            Cette partie du code fait descendre les lasers à toute vitesse sans effacer le laser précèdent... enfin, comme j'ai pas tout le code, je me trompe peut-être.
            • Partager sur Facebook
            • Partager sur Twitter
            Inkamath on GitHub - Interpréteur d'expressions mathématiques. Reprise du développement en cours.
              19 avril 2006 à 21:10:11

              Nan, cette partie les fait monter sans effacer le précédent, c'est vrai. Mais bon, là ne sont pas mes priorités, ce que je veux résoudre, c'est la suite du code, lorsqu'un laser touche un monstre. Là, je tire une fois et à chaque fois que le monstre touche l'endroit où j'ai tirer la première fois, il disparait, et ce n'est point normal.
              • Partager sur Facebook
              • Partager sur Twitter
                19 avril 2006 à 21:22:58

                Ca c'est parce que ton laser est resté bloqué en haut de l'écran, en effet, ton code fait en sorte que le laser ne dépasse pas la limite supérieur de l'écran. Il faut supprimer les lasers qui sortent de l'écran. Enfin comme j'ai pas tout le code encore une fois je me trompe peut-être..
                En tout cas, la remarque que je t'ai faite dans le message précédant tient toujours, je ne pense pas que tu veuilles faire monter les lasers instantanément..
                • Partager sur Facebook
                • Partager sur Twitter
                Inkamath on GitHub - Interpréteur d'expressions mathématiques. Reprise du développement en cours.
                  19 avril 2006 à 21:28:35

                  Bah y'a le
                  while(positionLaser[nbrei].y > 0)
                  Lorsque positionLaser atteint 0 (le haut de l'écran), ça ne se blitte plus ! Donc le problème ne vient (je crois) pas de là.
                  M'enfin, je met le code entier de jeu.c et blit.c, qui pourra certaineemnt mieux t'aider à m'aider.

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

                  long jouer(SDL_Surface* ecran)
                  {
                      SDL_Surface *ship = NULL, *espace = NULL, *laser = NULL, *pete = NULL, *score = NULL;
                      int continuer = 1, lasergd = 0, laserok = 0, i = -1, y = 0, direction_x[10] = {1, -1, -1, 1, -1, 1, -1, 1, -1, 1}, direction_y[10] = {-1, -1, 1, -1, 1, -1, 1, 1, -1, -1};
                      long collisionShip, cv = 0;
                      SDL_Event event;
                          SDL_Rect positionShip, positionEspace, positionScore, positionLaser[100], positionPete[10];

                      SDL_Init(SDL_INIT_VIDEO);

                          positionShip.x = 600/2-39/2;
                          positionShip.y = 720;
                          positionEspace.x = 0;
                      positionEspace.y = 0;
                      positionScore.x = 600;
                      positionScore.y = 0;
                          positionPete[0].x = 100;
                          positionPete[0].y = 50;
                          positionPete[1].x = 200;
                          positionPete[1].y = 50;
                          positionPete[2].x = 300;
                          positionPete[2].y = 50;
                          positionPete[3].x = 400;
                          positionPete[3].y = 50;
                          positionPete[4].x = 500;
                          positionPete[4].y = 50;
                          positionPete[5].x = 100;
                          positionPete[5].y = 200;
                          positionPete[6].x = 200;
                          positionPete[6].y = 200;
                          positionPete[7].x = 300;
                          positionPete[7].y = 200;
                          positionPete[8].x = 400;
                          positionPete[8].y = 200;
                          positionPete[9].x = 500;
                          positionPete[9].y = 200;

                          ecran = SDL_SetVideoMode(1024, 768, 32, SDL_HWSURFACE | SDL_FULLSCREEN | SDL_DOUBLEBUF);
                      SDL_WM_SetCaption("Astéropete", NULL);

                          espace = IMG_Load("Etoiles.jpg");

                      score = IMG_Load("score.bmp");

                      ship = IMG_Load("Vaisseau.png");
                          SDL_SetColorKey(ship, SDL_SRCCOLORKEY, SDL_MapRGB(ship->format, 255, 255, 255));

                          laser = IMG_Load("laser.png");

                          pete = IMG_Load("pete.jpg");
                          SDL_SetColorKey(pete, SDL_SRCCOLORKEY, SDL_MapRGB(pete->format, 0, 0, 0));

                          SDL_EnableKeyRepeat(1, 1);
                          SDL_ShowCursor(SDL_DISABLE);

                      while (continuer)
                      {
                          // Evènements
                          SDL_PollEvent(&event);
                          switch(event.type)
                          {
                              // Clavier
                              case SDL_KEYDOWN:
                                  switch(event.key.keysym.sym)
                                  {
                                  // Echap => Quitter
                                  case SDLK_ESCAPE:
                                      continuer = 0;
                                      break;

                                  // Flèche Droite => bouger à droite
                                  case SDLK_RIGHT:
                                      positionShip.x+=4;
                                      collisionShip = positionShip.x + 39;

                                      if(collisionShip >= 600)
                                      {
                                          positionShip.x-=4;
                                      }
                                      break;

                                  // Flèche Gauche => Bouger à gauche
                                  case SDLK_LEFT:
                                      positionShip.x-=4;

                                      if(positionShip.x <= 0)
                                      {
                                          positionShip.x+=4;
                                      }
                                      break;

                                  // Espace => Activer le blittage des lasers
                                  case SDLK_SPACE:
                                      laserok = 1;
                                      i++;

                                      if(lasergd)
                                      {
                                          positionLaser[i].x = positionShip.x;
                                          positionLaser[i].y = 710;
                                          lasergd--;
                                      }

                                      else
                                      {
                                          positionLaser[i].x = positionShip.x+39;
                                          positionLaser[i].y = 710;
                                          lasergd++;
                                      }
                                      break;

                                  // Espace + Flèche Droite
                                  case SDLK_SPACE + SDLK_RIGHT:
                                      positionShip.x+=4;
                                      laserok = 1;
                                      i++;

                                      collisionShip = positionShip.x + 39;

                                      if(collisionShip >= 600)
                                      {
                                          positionShip.x-=4;
                                      }

                                      if(lasergd)
                                      {
                                          positionLaser[i].x = positionShip.x;
                                          positionLaser[i].y = 710;
                                          lasergd--;
                                      }

                                      else
                                      {
                                          positionLaser[i].x = positionShip.x+39;
                                          positionLaser[i].y = 710;
                                          lasergd++;
                                      }
                                      break;

                                  // Espace + Flèche Gauche
                                  case SDLK_SPACE + SDLK_LEFT:
                                      positionShip.x-=4;

                                      if(positionShip.x <= 0)
                                      {
                                          positionShip.x+=4;
                                      }

                                      laserok = 1;
                                      i++;

                                      if(lasergd)
                                      {
                                          positionLaser[i].x = positionShip.x;
                                          positionLaser[i].y = 710;
                                          lasergd--;
                                      }

                                      else
                                      {
                                          positionLaser[i].x = positionShip.x+39;
                                          positionLaser[i].y = 710;
                                          lasergd++;
                                      }
                                      break;
                              }
                              break;
                          }

                          blittage(ecran, ship, espace, score, laser, pete, laserok, lasergd, i, direction_x, direction_y, &cv, positionShip, positionEspace, positionScore, positionLaser, positionPete);

                          if(i == 98)
                              i = 0;

                          // Si tous les petes sont morts, on gagne !
                          if(cv == 10)
                          {
                              sleep(2000);
                              continuer = 0;
                          }

                          // On met à jour l'affichage
                          SDL_Flip(ecran);
                      }

                      // Libérations des surfaces
                      SDL_FreeSurface(ship);
                      SDL_FreeSurface(laser);
                      SDL_FreeSurface(espace);
                      SDL_FreeSurface(pete);
                  }


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

                  void blittage(SDL_Surface* ecran, SDL_Surface* ship, SDL_Surface* espace, SDL_Surface* score, SDL_Surface* laser, SDL_Surface* pete, int laserok, int lasergd, int i, int direction_x[], int direction_y[], long* cv, SDL_Rect positionShip, SDL_Rect positionEspace, SDL_Rect positionScore, SDL_Rect positionLaser[], SDL_Rect positionPete[])
                  {
                      int nbrei = -1, y = 0, positionPete2, peteEnVie[10] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1};

                      // On efface l'écran
                      SDL_FillRect(ecran, NULL, SDL_MapRGB(ecran->format, 0, 0, 0));
                      // On reblitte l'espace
                      SDL_BlitSurface(espace, NULL, ecran, &positionEspace);
                      SDL_BlitSurface(score, NULL, ecran, &positionScore);

                      // Collisions des petes

                      for(y = 0; y < 10; y++)
                      {
                          // Collision mur du haut
                          if(positionPete[y].y <= 0)
                          {
                              direction_y[y] = 1;
                          }

                          // Collision mur de droite
                          if(positionPete[y].x >= 555)
                          {
                              direction_x[y] = -1;
                          }

                          // Collision mur de gauche
                          if(positionPete[y].x <= 0)
                          {
                              direction_x[y] = 1;
                          }

                          // Collision mur du bas
                          if(positionPete[y].y >= 713)
                          {
                              direction_y[y] = -1;
                          }
                      }

                      // Blittage des lasers
                      if(laserok)
                      {
                          while(i != nbrei)
                          {
                              nbrei++;
                              while(positionLaser[nbrei].y > 0)
                              {
                                  SDL_BlitSurface(laser, NULL, ecran, &positionLaser[nbrei]);
                                  positionLaser[nbrei].y-=5;
                              }
                          }

                          // Si un laser touche un pete
                          for(y = 0; y < 10; y++)
                          {
                              positionPete2 = positionPete[y].x + 39;
                              if(positionLaser->x > positionPete[y].x && positionLaser->x < positionPete2)
                              {
                                  peteEnVie[y] = 0;
                              }
                          }

                          nbrei = 0;
                          laserok = 0;
                      }

                      // On blitte les petes
                      for(y = 0; y < 10; y++)
                      {
                          // Si le pete n°y est en vie, on le blitte
                          if(peteEnVie[y] == 1)
                          {
                              positionPete[y].x+= direction_x[y] * 5;
                              positionPete[y].y+= direction_y[y] * 5;
                              SDL_BlitSurface(pete, NULL, ecran, &positionPete[y]);
                          }

                          // Sinon compteurVictoire augmente de 1
                          if(peteEnVie[y] == 0)
                          {
                              *cv++;
                          }
                      }

                      // On blitte le vaisseau
                      SDL_BlitSurface(ship, NULL, ecran, &positionShip);
                  }


                  Voilà, ça devrait mieux t'aider

                  PS : En passant, si tu as un script mieux pour mes lasers, n'hésite pas ^^
                  • Partager sur Facebook
                  • Partager sur Twitter
                    19 avril 2006 à 23:35:42

                    Ce n'est pas parce que tu ne blit plus le laser que tu l'efface complètement de la mémoire... Même s'il n'apparaît pas, le laser est toujours là... il faut que tu trouves un moyen de le supprimer, ou de le désactiver...
                    A ta place, je ferais une liste chaînée avec tes lasers et j'effacerais les lasers du bas de la liste qui touchent le haut de l'écran. :)
                    • Partager sur Facebook
                    • Partager sur Twitter
                    Inkamath on GitHub - Interpréteur d'expressions mathématiques. Reprise du développement en cours.
                      20 avril 2006 à 11:10:30

                      Hein ? Je pige pas ce que tu veux dire...
                      Une liste chainée ?
                      Sinon, pour le problème t'as raison, je ne le blite plus mais la position est tujours la même. J'ai une idée, après la boucle des lasers, si je remets toutes les positionsLaser à par exemple y2000, ça va peut être marcher, nan ? J'essaie en tt cas.

                      Edit : Nan, ça marche pas ^^

                      Code :
                      if(laserok)
                          {
                              while(i != nbrei)
                              {
                                  nbrei++;
                                  while(positionLaser[nbrei].y > 0)
                                  {
                                      SDL_BlitSurface(laser, NULL, ecran, &positionLaser[nbrei]);
                                      positionLaser[nbrei].y-=5;
                                  }
                              }
                             
                              nbrei = -1;

                              // Si un laser touche un pete
                              for(y = 0; y < 10; y++)
                              {
                                  positionPete2 = positionPete[y].x + 39;
                                  if(positionLaser->x > positionPete[y].x && positionLaser->x < positionPete2)
                                  {
                                      peteEnVie[y] = 0;
                                  }
                              }

                              while(i != nbrei)
                              {
                                  nbrei++;
                                  positionLaser[nbrei].x = 700;
                              }

                              nbrei = -1;
                              laserok = 0;
                          }


                      Avec ça, les monstres ne disparaissent plus du tout.


                      Aussi, pour mon problème de victoire, j'ai trouvé comment faire, mais il me reste un problème. Ce que je veux faire, c'est quand les objectifs sont atteints, on blitte la surface victoire, on attend 2 sec et on quitte. Sauf que j'y arrive pas. Mon code :
                      // Si tous les petes sont morts, on gagne !
                              if(cv == 10)
                              {
                                  SDL_BlitSurface(victoire, NULL, ecran, &posVic);
                                  SDL_Delay(2000);
                                  *continuer = 0;
                              }
                      }
                      • Partager sur Facebook
                      • Partager sur Twitter
                        20 avril 2006 à 14:07:20

                        Pour ton premier problème, je ne comprends pas pourquoi ça ne marche pas, ça devrait pourtant. Pour ton second problème, c'est l'une des contraintes de la fonction SDL_Delay. La solution est plus complexe que ça. Désolé de ne pas pouvoir t'aider plus, je dois y aller.
                        A bientôt
                        • Partager sur Facebook
                        • Partager sur Twitter
                          20 avril 2006 à 14:40:34

                          Bon ok, pas grave si tu ne peux pas m'aider, mais quelqu'un d'autre le pourrait ?

                          Edit : Finalement, j'ai fait autre chose pour la victoire te c'est bon, mais pour la collision laser/monstre, c'ets toujours pas ça.

                          Edit 2 : Que je suis c*n ! J'avais oublié que positionLaser était un tableau ! Donc maintenant mon code est bien mieux mais il reste un problème : à chaque fois q'un monstre se fait touché, il disparait puis réapparait instantanément une fois le laser parti !
                          Mon code actuel
                              // Blittage des lasers
                              if(laserok)
                              {
                                  while(i != nbrei)
                                  {
                                      nbrei++;
                                      while(positionLaser[nbrei].y > 0)
                                      {
                                          SDL_BlitSurface(laser, NULL, ecran, &positionLaser[nbrei]);
                                          positionLaser[nbrei].y-=5;
                                      }
                                  }

                                  nbrei = -1;

                                  // Si un laser touche un pete
                                  while(i != nbrei)
                                  {
                                      nbrei++;
                                      for(y = 0; y < 10; y++)
                                      {
                                          positionPete2 = positionPete[y].x + 39;
                                          if(positionLaser[nbrei].x > positionPete[y].x && positionLaser[nbrei].x < positionPete2)
                                          {
                                              peteEnVie[y] = 0;
                                          }
                                      }

                                      positionLaser[nbrei].x = 700;
                                  }

                                  nbrei = -1;
                                  laserok = 0;
                              }
                          • Partager sur Facebook
                          • Partager sur Twitter
                            20 avril 2006 à 18:25:13

                            re-salut,
                            Attend je crois que j'ai une idée pour le premier problème.
                            Ta variable peteEnVie[y] tu ne la déclare pas dans une fonction qui se trouve dans une boucle par hasard ?
                            Ce qui reviendrait à la rédéfinire à chaque tour :D.

                            Allez bonne chance.
                            • Partager sur Facebook
                            • Partager sur Twitter
                              20 avril 2006 à 18:34:02

                              YOUPI ! Ca marche maintenant ! Que je suis bête ^^
                              • Partager sur Facebook
                              • Partager sur Twitter

                              [SDL] Deux problèmes avec mon jeu

                              × 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