Partage
  • Partager sur Facebook
  • Partager sur Twitter

Collisions...

Sujet résolu
    7 juillet 2007 à 10:19:33

    Bonjour a tous!!

    Alors voila je fais une sorte de "miniminimario" en SDL :p histoire de toucher un peu aux collisions... parce que c'est la que sa ne passe pas chez moi :(...

    Dans le programme il y a un mario qui ce deplace sur une surface blanche (il est pas complet le jeu ^^ ) et il y a un objectif. Je voudrais que l'objectif ce deplace (par exemple de 50 pixel en diagonale...) quand Mario arrive dessus. (bon ya pas de plaisir a toucher un objectif et qu'il ce deplace mais c'est juste pour les collisions...)

    j'ai fais ceci :

    positionMario = c'est la position de mario
    position = c'est la position de l'objectif

            if((positionMario.x >= position.x) && (positionMario.x + positionMario.w <= position.x)
                && (positionMario.y <= position.y) && (positionMario.y + positionMario.h >= position.y))
                {
                    position.x += 50;
                    position.y += 50;
                }


    Malheuresement rien ne se passe, mon mario arrive sur l'objectif et... c'est tout... :(
    j'ai passé pas mal de temps a chercher sur google mais je n'arrive pas a trouver de renseignement clair, si quelqu'un peut m'aider...

    Merci d'avance!!
    • Partager sur Facebook
    • Partager sur Twitter
      7 juillet 2007 à 11:00:06

      Allez cadeau, le raisonnement qu'il faut faire :

      Si le coté gauche de mario est compris entre le coté gauche et droit de l'objectif
      OU
      Si le coté droit de mario est contenu entre le coté gauche et droit de l'objectif

      ET

      Si le coté bas de mario est contenu entre le coté bas et le coté haut de l'objectif
      OU
      Si le coté haut de mario est contenu entre le coté bas et le coté haut de l'objectif

      ALORS

      Les 2 surfaces sont en collision ! \o/

      Ca ne fonctionne que pour des surfaces rectangulaires...

      Dans ton code tu n'utilise que des &&, il doit y avoir un problème de ce coté là. ;)
      • Partager sur Facebook
      • Partager sur Twitter
        7 juillet 2007 à 11:30:09

        Oui Oui je vois bien le genre de raisonnement a avoir mais le probleme c'est pour le retranscrire en code... :o .

        comme,
        coté gauche = position.x
        coté droit = ???
        coté haut = position.y
        coté bas = ???

        il faudrait des x1, x2, y1, y2...
        mais c'est trop vague je ne sais pas comment m'y prendre...

        ou alors il y a quelque chose que j'ai mal compris au niveau des coordonnées... :euh:

        • Partager sur Facebook
        • Partager sur Twitter
          7 juillet 2007 à 11:33:37

          Niarf... La taille de mario te permet d'avoir le côté droit et le côté bas... Et n'oublie pas que dans la formule que t'a passé Kevin il n'y a pas que des ET mais aussi des OU...
          • Partager sur Facebook
          • Partager sur Twitter
            7 juillet 2007 à 11:47:27

            hum... j'en arrive a ca:
                    if((positionMario.x >= position.x && position.w) || (positionMario.w >= position.w && position.w)
                        && (positionMario.y >= position.h && position.y) || (positionMario.h >= position.h && position.y))
                        {
                            position.x += 50;
                            position.y += 50;
                        }


            mais rien ne ce passe pourtant on peut retrouver le raisonnement de Kevin Leonhart non?

            Si le coté gauche de Mario est compris entre le coté gauche et droit de l'objectif
            if((positionMario.x >= position.x && position.w)


            apres il ya a le ou || puis le et && et de nouveau le ou || mais rien ne ce passe...

            excusez moi de vous embeter avec sa mais je bloque dessus depuis pas mal de temps...
            • Partager sur Facebook
            • Partager sur Twitter
              7 juillet 2007 à 11:54:25

              c'est un bon début mais mario n'est pas reelement definit par positionMario.x et .y il est important de prendre en compte la larfeur et la hauteur de l'image (w et h) idem pour l'objectif.
              • Partager sur Facebook
              • Partager sur Twitter
                7 juillet 2007 à 11:55:42

                (positionMario.x >= position.x && position.w)

                Si tu essaie de retranscrire ça en français, ça donne quoi ?

                (positionMario.w >= position.w && position.w)

                Idem là il y a un truc qui m'échappe.
                Tu compare la largeur des surfaces entres elles, mais peut importe que l'une soit plus large que l'autre, ça n'a rien à voir...

                Tu étais bien partit dans ton premier code mais tu ne mettais que des &&.
                Si ta surface de mario est plus large que l'objectif par exemple, les 2 cotés de mario ne pourrons jamais être compris simultanément entre les 2 cotés de l'objectif.

                D'où le OU, un coté suffit. :)
                • Partager sur Facebook
                • Partager sur Twitter
                  7 juillet 2007 à 11:59:50

                  Oui l'objectif bouge!!
                  mais c'est pas encore sa... :euh:

                  l'objectif ce deplace dès que Mario bouge meme si il ne sont pas en contact...


                  la j'ai mis es ou et les et dans la premier code...
                  comprend rien...
                          if((positionMario.x >= position.x) || (positionMario.x + positionMario.w <= position.x)
                              && (positionMario.y <= position.y) || (positionMario.y + positionMario.h >= position.y))
                              {
                                  position.x += 50;
                                  position.y += 50;
                              }
                  • Partager sur Facebook
                  • Partager sur Twitter
                    7 juillet 2007 à 12:02:03

                    position.w !!! arg non pas comme ca!!!
                    mais plutot surfaceMario->h surfaceMario->w

                    quand on definit une surface il vaut mieux définir les quatres cotés ^^
                    (comme ca on prévoit toutes les possibilités ^^

                    EDIT: jamis essayé directement .h et .w :euh:
                    • Partager sur Facebook
                    • Partager sur Twitter
                      7 juillet 2007 à 12:33:35

                      Avec ton code actuel, le problème est que tu teste si le coté gauche du mario est compris entre le coté gauche de l'objectif et... rien !

                      Donc à partir du moment où ton mario est à droite de l'objectif la condition sera remplie.
                      (enfin pas toute la condition mais déjà la moitié)
                      • Partager sur Facebook
                      • Partager sur Twitter
                        7 juillet 2007 à 13:37:12

                        Je crois que je vais devenir fou!!

                                if((positionMario.x >= position.x) || (positionMario.x + positionMario.w >= position.x)&&
                                   (positionMario.x >= position.w) || (positionMario.x + positionMario.w >= position.w)
                                                                   &&
                                   (positionMario.y >= position.y) || (positionMario.y + positionMario.h >= position.y)&&
                                   (positionMario.y >= position.h) || (positionMario.y + positionMario.h >= position.h))
                                    {
                                        position.x += 1;
                                        position.y += 1;
                                    }


                        Ici j'ai rajouté les 2ème et 4ème lignes.

                        les 1ère et 3ème ligne disent "si mario est compris entre le coté gauche/haut de l'objectif"
                        les 2ème et 3ème ligne disent "et est compris entre le coté droite/bas de l'objectif"

                        enfin si sa veut pas dire ca c'est en tout cas ce que j'ai voulu dire.. mais rien ne change l'objectif bouge a chaque mouvement de mario ou qu'il soit...(Meme pendant les mouvements de souris.. :D )

                        je suis désolé mais je ne comprends vraiment pas...
                        • Partager sur Facebook
                        • Partager sur Twitter
                          7 juillet 2007 à 13:48:14

                          je te propose ca:
                          je te donnerais les fonctions apres ^^

                          //bla bla bla



                          if(xmin(mario)<=xmax(_objectif) && xmax(_mario)>=xmin(objectif)
                          //une securité au cas ou mario serait plus large que l'objectif
                          || xmin(mario)< xmin(objectif) && xmax(_mario)>xmax(_objectif)
                          //maintenant on definit l'ordonnée
                          ||ymin(mario)<=ymax(_objectif) && xmax(_mario)>=ymin(objectif)
                          //securité...
                          ||ymin(mario)<ymin(objectif) && ymax(_mario)>ymax(_objectif)
                          )//ca fait un grosse condition ^^

                          {
                          //si mario touche l'objectif...
                          }

                          else{
                          //sinon...
                          }
                          //bla bla bla
                           


                          je trouve que c'est plus lisible avec x/y min/max
                          mais je te les donnent ;)
                          //ceci sont les prototypes des fonction
                          #define _mario surface_mario,position_sdl_rect
                          //pour eviter de repeter a chaque fois les deux^^
                          #define _objectif nom_surface,position_sdl_rect

                          //remplace manuelement les defines car je connaissais pas les noms  des surfaces :-°
                          long xmin(SDL_Rect positSurface);
                          long xmax(SDL_Surface *surface,SDL_Rect posit);
                          long ymin(SDL_Rect positSurface);
                          long ymax(SDL_Surface *surface,SDL_Rect posit);
                           


                          et les fonctions


                          long xmin(SDL_Rect positSurface)
                          {return positSurface.x;)//on renvoie l'abcisse minimal
                           
                          long xmax(SDL_Surface *surface,SDL_Rect posit)
                          {return (posit.x+surface->h);}
                          //on renvoie la largeur j'espere que j'a pas inversé w et h lol

                          long ymin(SDL_Rect positSurface)
                          {return positSurface;}
                          //on retourne l'ordonnéminimal

                          long ymax(SDL_Surface *surface,SDL_Rect posit)
                          {return (posit.y+surface->w);
                          //on retourne la hauteur ^^
                           


                          j'ai fait ca en copiant ma class alor... il se peut qu'il y ait quelques fautes d'hortographe

                          mais la condition que je t'ai passé c'est comme ca que j'aurais fait ;)
                          • Partager sur Facebook
                          • Partager sur Twitter
                            7 juillet 2007 à 13:58:50

                            Oui je crois que tu as un problème avec les conditions ^^

                            if((positionMario.x >= position.x) || (positionMario.x + positionMario.w >= position.x)&&
                                       (positionMario.x >= position.w) || (positionMario.x + positionMario.w >= position.w)

                            Ce code signifie :

                            Si le coté gauche de mario est à droite ou sur le coté gauche de l'objectif
                            OU
                            si le coté droit de mario est à droite ou sur le coté gauche de l'objectif
                            ET
                            si le coté gauche de mario est supérieur ou égal à la largeur de l'objectif o_O
                            OU
                            si le coté droit de mario est supérieur ou égal à la largeur de l'objectif o_O


                            Je ne vois pas comment on pourrais comparer une largeur avec une position.

                            Ce n'est pas très dur à faire mais ça demande de la concentration.
                            Essaye d'identifier chaque variable avec un nom en français. (coté gauche, coté haut...)
                            A aucun moment tu n'auras besoin d'avoir une largeur ou hauteur seule, elles seront toujours additionnées avec une position. :)
                            • Partager sur Facebook
                            • Partager sur Twitter
                              7 juillet 2007 à 14:18:21

                              Bah en fait le problème, c'est que si tu dis que le côté gauche de mario est positionMario.x, tu ne définis seulement qu'un seul point ! Le point supérieur gauche !
                              Il faut donc dire "si UN des points appartenant au côté droit de l'objectif a la même ordonée que l'UN des points du côté gauche de Mario, alors tu ne blit pas". Je te laisse faire pareil pour les autres ^^ Mais il ne faut pas oublier l'abscisse :-° Sinon tu vas te retrouver avec des collisions, mais pas au bon endroit ^^

                              Personnellement, je n'ai jamais réellement fait cela, car je ne trouvais pas le moyen de coder une collision d'intervalle (ça doit être possible avec un tableau)


                              int gestCollision(positionMarion, position)
                              {
                                  for (int my = positionMario.y; my != ((positionMario.y + positionMario.h)+1); my++)
                                  {
                                      for (int py = position.y; py != ((position.y + position.h)+1); py++)
                                      {
                                          if ( my == py)
                                          {
                                              return 1; // Il y a une collision sur l'axe des ordonnées (pas sur Mario ! )
                                          }
                                 
                                          else
                                          {
                                              return 0; // Aucune collision, le blit est permis :)</code
                                          }
                                      }
                                  }
                              }


                              J'ai codé ce morceau à l'instant, donc s'il présente des erreurs signalez-le ^^
                              Je te laisse donc trouver la suite pour les abscisses, bonne chance :)
                              • Partager sur Facebook
                              • Partager sur Twitter
                                7 juillet 2007 à 14:51:30

                                Citation : -Skypers-

                                Bah en fait le problème, c'est que si tu dis que le côté gauche de mario est positionMario.x, tu ne définis seulement qu'un seul point ! Le point supérieur gauche !



                                Non ! n'importe quoi.
                                Il ne définit pas de point puisqu'il n'y a qu'une valeur sur l'axe des abscisses.

                                Cette valeur représente tout le coté gauche.


                                Citation : -Skypers-

                                Personnellement, je n'ai jamais réellement fait cela, car je ne trouvais pas le moyen de coder une collision d'intervalle (ça doit être possible avec un tableau)



                                C'est quoi une collision d'intervalle ?
                                • Partager sur Facebook
                                • Partager sur Twitter
                                  7 juillet 2007 à 15:03:05

                                  .........
                                  .........
                                  .........
                                  .........

                                  Il faut bien définir une collision pour chacun des points ? Non ? J'avoue que vérifier les points internes de sert strictement à rien... Mais j'ai quand même codé ça, je ne sais pas si ça marche :

                                  Secret (cliquez pour afficher)
                                  /// Fonction de gestion de collision

                                  int gestColl(posiMario, posi) // Renvoie un int si une collision est détectée entre Mario et l'objectif...
                                  {                                 
                                      for (int mX = posiMario.x, mY = posiMario.y; mX != ((posiMario.x + posiMario.w)1) && mY != ((posiMario.y + posiMario.h) + 1); mX++)
                                      {
                                          for (int pX = posi.x, pY = posi.y; pX != ((posi.x + posi.w) + 1) && pY != ((posi.y + posi.h) + 1); pX++)
                                          {
                                              if (pX == mX && pY == mY) // Si il y a collision
                                              {
                                                  return 1; // On retourne la collision vérifié vraie
                                              }

                                              else; // -0- Il ne faut rien retourner car on ne vérifierait pas tous les points

                                              if (pX == ((posi.x + posi.w) + 1)
                                              {
                                                  pX = posi.x;
                                                  pY += 1;
                                              }
                                          }

                                          if (mX == ((posiMario.x + posiMario.w) + 1)
                                          {
                                              mX = posiMario.x;
                                              mY += 1;
                                          }
                                      }
                                  }
                                  • Partager sur Facebook
                                  • Partager sur Twitter
                                    7 juillet 2007 à 15:28:02

                                    pfuuu... J'ai même pas le courage de regarder ta fonction tellement elle à l'air compliquée. :p

                                    On a absolument pas besoin de tester tous les points.
                                    Juste les cotés, donc juste 2 valeurs sur l'axe X et 2 valeurs sur l'axe Y.

                                    CF le 2eme message de ce post ou j'explique là marche à suivre. :)
                                    • Partager sur Facebook
                                    • Partager sur Twitter
                                      7 juillet 2007 à 21:17:43

                                      et pourquois position.x ne serait pas le coté gauche ???


                                      car si on travail sur une unique dimention (abcisse ou ordonnée)

                                      un point est une rupture...(vive l'abstrait :lol: )

                                      si on fait les dimentions séparemment (comme dans mon code...)
                                      les problemes sont résolus facilement :D

                                      toujours penser simple ^^
                                      • Partager sur Facebook
                                      • Partager sur Twitter
                                        8 juillet 2007 à 10:30:13

                                        Je me suis aidé du code de Neuneutrinos et sa donne sa :

                                                if((positionMario.x <= position.x) && (positionMario.x >= position.x) ||
                                                   (positionMario.x < position.x) && (positionMario.x > position.x) ||
                                                   (positionMario.y <= position.y) && (positionMario.x >= position.y) ||
                                                   (positionMario.y < position.y) && (positionMario.y > position.y))
                                                    {
                                                        position.x += 1;
                                                        position.y += 1;
                                                    }


                                        Avec ca, l'objectif se déplace seulement quand mario passe a droite de son ordonnée...

                                        C'est étrange parce que les 2 premieres ligne (avec les x) sont sur le même modèle que les 2 derrniere (avec les y), il y a juste les x et y de changés o_O
                                        Pourquoi Mario peut passer en dessous de l'objectif et pas a sa droite?? :'(
                                        • Partager sur Facebook
                                        • Partager sur Twitter
                                          8 juillet 2007 à 10:38:38

                                          ... heu, je voudrais pas paraître méchant mais là ça devient grave.
                                          Est-ce que tu as réfléchit un moment à ce code avant de le tester ?

                                          1ère ligne :
                                          (positionMario.x <= position.x) && (positionMario.x >= position.x)

                                          Signifie :

                                          Si le coté gauche de mario est à gauche ou sur le coté gauche de l'objectif
                                          ET
                                          si le coté gauche de mario est à droite ou sur le coté droit de l'objectif


                                          Comment pourrait il être des 2 cotés en même temps.
                                          • Partager sur Facebook
                                          • Partager sur Twitter
                                            8 juillet 2007 à 12:33:22

                                            mon code ne marche pas!!! (la boulette :euh: )

                                            je vais reprendre mon travail de reflection.

                                            d'abbord je définit les colision sur les abcisse.
                                            puis sur les ordonnées.

                                            if(xmin(mario)/*renvoi l'abcisse*/<=xmax(_objectif)
                                            //traduction si mario est "dans" ou "à gauche" de l'objectif
                                            && xmax(_mario)>=xmin(objectif)
                                            // ET que mario se trouve "dans" ou "à droite" de l'objectif
                                            && ymin(mario)<=ymax(_objectif)
                                            //et que mario se trouve en "dans" ou "au dessus" de l'objectif
                                            && ymax(_mario)>=ymin(objectif)
                                            //si mario se trouve "dans" ou "en dessous" de l'objectif

                                            // mais si mario est plus grand et large que l'objectif, il est possible qu'aucune de ces conditions soit vrai (si on deplace pas de 1 pixel en 1 pixel... il y a un risque,il faut penser à tout ^^
                                            ||xmin(mario)<xmin(objectif)&& xmax(_mario)>xmax(_objectif)
                                            //si mario se trouve "sur" l'objectif mais est trop large pour que les conditions du dessus soit respecter...
                                            && ymin(mario)<ymin(objectif) && ymax(_mario)>ymax(_objectif)
                                            //si mario est sur l'objectif mais est trop grand pour les conditions du dessus soit respecté...
                                            )
                                            {
                                            //alors
                                            }
                                            else{
                                            //sinon...
                                            }


                                            pour ne pas refaire deux fois la meme boulette, j'ai tester mon code et il marche ^^

                                            corrections des fautes de frappe
                                            long xmin(SDL_Rect positSurface)
                                            {return positSurface.x;}//on renvoie l'abcisse minimal
                                             
                                            long xmax(SDL_Surface *surface,SDL_Rect posit)
                                            {return (posit.x+surface->h);}
                                            //on renvoie la largeur j'espere que j'a pas inversé w et h lol

                                            long ymin(SDL_Rect positSurface)
                                            {return positSurface.y;}
                                            //on retourne l'ordonnéminimal

                                            long ymax(SDL_Surface *surface,SDL_Rect posit)
                                            {return (posit.y+surface->w);}
                                            //on retourne la hauteur ^^
                                             


                                            si zozor est ni lus large ni plus grand que l'objectif, le || est facultatif ^^

                                            désolé pour la premiere fois >_<
                                            • Partager sur Facebook
                                            • Partager sur Twitter
                                              9 juillet 2007 à 13:12:20

                                              J'ai enfin réussi !!! :lol:

                                              Merci beaucoup!! en fait il faut vraiment s'y prendre avec de la méthode... et point par point sa avance... ;)
                                              Kevin Leonhart, ton 2em post ma beaucoup aidé (je ny avais pas prété assé attention avnt...)

                                              merci je met le post comme résolu!!
                                              • Partager sur Facebook
                                              • Partager sur Twitter

                                              Collisions...

                                              × 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