Partage
  • Partager sur Facebook
  • Partager sur Twitter

[Pygame] Stopper un objet en collision

Comment empêcher un vaisseau spatial de s'écraser sur une météorite ?

    16 février 2016 à 19:05:45

    Bonjour tout le monde !

    J'ai un petit problème assez gênant pour mon projet de petit jeu spatial que je développe sous Python avec Pygame. En effet, mon vaisseau spatial doit se déplacer à travers un champ d’astéroïde. Pour réaliser cela, j'ai placé sur le niveau 5 astéroïdes avec des sprites, répartis de manière régulière pour faire le niveau que je voulais.
    Malheureusement, j'ai un assez gros problème que je n'arrive pas à surmonter : mon vaisseau, logiquement, ne dois pas pouvoir traverser les astéroïdes. Je me suis donc dit que j'allais chercher un moyen de vérifier si mon vaisseau était en collision avec un astéroïde. Pour cela, j'ai trouvé la propriété rect, que j'ai mis un peu de temps à prendre en main, mais maintenant c'est bon, elle fonctionne bien, du moins en partie.

    Le problème est stupide, et en même temps je ne comprend pas comment je pourrais faire...

    Voici mon code :

    if event.key == K_DOWN and position_perso.y<=654:
        if position_perso.colliderect(position_asteroide1) :
            position_perso = position_perso.move(0,0)
    • Le premier if teste si la touche directionnelle est enfoncée et si le vaisseau ne sort pas de la fenêtre.
    • Le second if teste si la position du personnage (le rect de mon vaisseau) est en collision avec la position de l'astéroïde 1 (rect de l'astéroïde 1).
    • Si c'est le cas...

    C'est là que j'ai un problème. Concrètement, je voudrais que le vaisseau s'arrête, et ne puisse pas continuer dans la direction où se situe l'astéroïde. Mais là, le "position_perso.move(0,0)" immobilise purement et simplement le vaisseau. J'ai beau chercher sur internet, aucune méthode en accord avec ce que j'ai fait ne propose ce que je veux...

    Autre problème : la propriété rect permettrait théoriquement de regrouper plusieurs rect dans une variable, afin de permettre à un élément de tester s'il est en collision avec au moins un rect de cette variable, ce qui serait très pratique dans mon cas, car ça m'éviterai de tester 5 fois pour chaque astéroïde si mon vaisseau est en collision...

    Voilà, merci encore pour votre aide !

    Cordialement,

    Lyro

    • Partager sur Facebook
    • Partager sur Twitter

    🚀 Software Engineer | https://lyro.fr

      16 février 2016 à 19:20:07

      Une astuce à utiliser à outrance: la fonction dir, qui permet de lister les méthodes/attribut d'un objet ;). Donc pour un Rect:

      import pygame
      
      dir(pygame.Rect)


      Ainsi tu vois quelles sont les méthodes dont tu disposes. En l'occurrence, ce qui peut t'intéresser c'est la méthode collidelist (à confirmer, j'y connais pas grand chose en pygame :p). Pour voir ce qu'elle permet de faire utilise la fonction help.

      Pour ton problème de stopper l'action, je suppose qu'il faudrait (si le vaisseau touche un astéroïde) sortir de la boucle des événements (avec un break peut-être ou une condition spécifique). Car le fait de déplacer le vaisseau en (0, 0) ne stoppe pas le jeu ;). Et j'ai pas compris ton histoire d'immobilisation (Le jeu freeze? Le vaisseau ne bouge plus? Il reste en position (0, 0) ou à l'endroit où il a percuté l'astéroïde?)

      • Partager sur Facebook
      • Partager sur Twitter
      Précepte: Le mieux est l'ennemi du bien
        16 février 2016 à 19:29:01

        @Olygrim : Merci pour ton conseil :)

        Concernant le stop, en fait je voudrais que mon vaisseau ne puisse pas avancer vers l'astéroïde, mais qu'il puisse reculer, ou aller à droit ou à gauche. Je voudrais juste que l'obstacle soit infranchissable, mais que mon vaisseau reste malgré tout mobile autour de cet obstacle.

        • Partager sur Facebook
        • Partager sur Twitter

        🚀 Software Engineer | https://lyro.fr

          16 février 2016 à 19:34:17

          Ok, je vois. Et bien il suffit de faire le test et si collision il y a, le vaisseau garde sa position. Autrement dit, il ne bouge pas et donc pas besoin d'effectuer un quelconque déplacement du Rect ;)
          • Partager sur Facebook
          • Partager sur Twitter
          Précepte: Le mieux est l'ennemi du bien
            16 février 2016 à 20:27:54

            Oui, mais le problème c'est que tant qu'il y aura collision, le vaisseau ne bougera plus... Or, s'il ne bouge plus, il reste en collision tout le temps :/ C'est là que ça me pose un gros problème...
            • Partager sur Facebook
            • Partager sur Twitter

            🚀 Software Engineer | https://lyro.fr

              16 février 2016 à 20:41:44

              Je ne sais pas s'il y a une manière propre de faire ça, mais une alternative serait de créer une étape intermédiaire:

              rect_intermediaire = deplacement_du_rectangle
              if not rect_intermediaire.colliderect(position_asteroide1):
                      position_perso = rect_intermediaire


              Un truc du style ^^

              • Partager sur Facebook
              • Partager sur Twitter
              Précepte: Le mieux est l'ennemi du bien
                16 février 2016 à 20:54:02

                Je comprend pas trop ce que tu veux faire, mais je vais te tenir au courant :)
                • Partager sur Facebook
                • Partager sur Twitter

                🚀 Software Engineer | https://lyro.fr

                  16 février 2016 à 21:07:31

                  Sinon, une autre manière de faire serait de créer une liste, ou un dictionnaire plutôt, des mouvements disponibles pour le vaisseau. Et si tu rentre en collision, alors tu enlève le mouvement vers l'astéroïde, et tu le remet dès que tu n'es plus en collision. Ainsi, à chaque instant, tu peux gérer la façon dont ton vaisseau peut bouger.

                  Sinon, ça fait un bout de temps que je n'ai pas touché à ça mais il existe dans pygame un module sprite, qui permet de faire énormément de choses, tu devrait jeter un oeil ;) (par exemple des groupes de sprites qui pourraient représenter tes astéroïdes, etc...)

                  http://www.pygame.org/docs/ref/sprite.html

                  Une petite aide ici: (tout le site est intéressant d'ailleurs):

                  https://fr.wikibooks.org/wiki/Pygame/Introduction_au_module_Sprite

                  • Partager sur Facebook
                  • Partager sur Twitter

                  [Pygame] Stopper un objet en collision

                  × 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