IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Algorithmes et structures de données Discussion :

Rebond simple d'une balle


Sujet :

Algorithmes et structures de données

  1. #1
    Membre éprouvé

    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2005
    Messages
    634
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Suisse

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2005
    Messages : 634
    Points : 1 205
    Points
    1 205
    Par défaut Rebond simple d'une balle
    Dans un jeu que je crée, je dois gérer le rebond d'une balle sur une surface rectangulaire. Je fait une simple collision (suffisante pour le moment) avec le contour carré de la balle.

    Pour les collision j'ai cet algorithme tout simple suivant:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    SI balle.x1 < objet.x2 ET balle.x2 > objet.x1
      SI balle.y1 < objet.y2 et que balley2 > objet.y1
        collision!
      FIN SI
    FIN SI
    Cepandant avec cet algo je sais uniquement lorsque j'ai une collision mais je ne sais pas si la collision est sur une face verticale ou horizontale du rectangle. Car après ce que je voudrais faire c'est simplement que si la collision est sur une face horizontal, on inverse la vitesse Y et si la collision est sur une face verticale, on inverse la vitesse X.

    Ya-t-il un moyen de déterminer ceci? Merci d'avance!
    Fiquet
    - FAQ SDL
    - FAQ C++

  2. #2
    Expert éminent

    Profil pro
    Fabricant et casseur d'avions
    Inscrit en
    Avril 2004
    Messages
    3 813
    Détails du profil
    Informations personnelles :
    Localisation : France, Tarn (Midi Pyrénées)

    Informations professionnelles :
    Activité : Fabricant et casseur d'avions
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Avril 2004
    Messages : 3 813
    Points : 7 638
    Points
    7 638
    Par défaut
    Salut,

    Si tu veux savoir quelle face ta balle a frappé, il va te falloir gérer sa trajectoire. C'est-à-dire voir d'où elle vient, où elle est, et en fonction de ces deux points, déterminer qu'elle face coupe la trajectoire.
    "Errare humanum est, sed perseverare diabolicum"

    Ma page sur DVP.com

  3. #3
    Expert éminent
    Avatar de djo.mos
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    4 666
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2004
    Messages : 4 666
    Points : 7 679
    Points
    7 679
    Par défaut
    Bonjour.
    Il va falloir que tu nous aide a t'aider l'ami, en nous donnant plus de details sur tes objets.

    Sinon, voici une solution :
    je suppose que j'ai une balle défini comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    BALLE=structure
     PX, PY : entier;  // position x, y
     VX, VY: entier;  // vitesse horizontale et verticale
     LX, LY : entier;  // largeur et longueur de la balle (rectangulaire)
    fin
    et que tu as un terrain comme cceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    TERRAIN=structure
     X1, Y1 : entier;  //position du coin supérieur gauche
     X2, Y2 : entier;  //position du coin inférieur droit
    fin
    à chaque itération, tu déplaces la balle :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    BALLE.PX = BALLE.PX + BALLE.VX;
    BALLE.PY = BALLE.PY + BALLE.VY;
    et tu testes les collisions :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
     
    SI (BALLE.XP+BALLE.LX) > TERRAIN.X2
     ALORS // collision avec le bord vertical à droite
      BALLE.VX = -BALLE.VX
     
    SI (BALLE.XP) < TERRAIN.X1
     ALORS // collision avec le bord vertical à gauche
      BALLE.VX = -BALLE.VX
     
    SI (BALLE.YP+BALLE.LY) > TERRAIN.Y2
     ALORS // collision avec le bord horizontal en bas
      BALLE.VY = -BALLE.VY
     
    SI (BALLE.YP) < TERRAIN.Y1
     ALORS // collision avec le bord horizontal en haut
      BALLE.VY = -BALLE.VY
    J'espère que j'etais clair.

  4. #4
    Membre éprouvé

    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2005
    Messages
    634
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Suisse

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2005
    Messages : 634
    Points : 1 205
    Points
    1 205
    Par défaut
    Bonjour,

    Merci à vous deux pour vos réponses et désolé pour le retard.
    Si tu veux savoir quelle face ta balle a frappé, il va te falloir gérer sa trajectoire. C'est-à-dire voir d'où elle vient, où elle est, et en fonction de ces deux points, déterminer qu'elle face coupe la trajectoire.
    Ok mais aurais-tu plus de précision? Une formule pour voir ceci? Le problème c'est que je travaille sur une simple lib 2d (SDL avec C++) et je ne travaille pas avec les angles, etc.
    Il va falloir que tu nous aide a t'aider l'ami, en nous donnant plus de details sur tes objets.
    J'ai un objet CBall dérivé d'un objet CSprite qui contient ces infos (code en C++ mais c'est compréhensible):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SDL_Surface m_Source;  // Texture du sprite
    SDL_Rect m_Position;        // Position
    int m_deplX;                     // Déplacement en X
    int m_deplY;                     // Déplacement en Y
    m_Position est une structure qui contient simplement x, y, largeur, hauteur du rectangle. Et en plus, dans l'objet CBall, j'ai ma fonction GetCollision() qui est censée retourner 1 en cas de collision verticale et 2 en cas de collision horizontale.

    Merci pour votre aide
    Fiquet
    - FAQ SDL
    - FAQ C++

  5. #5
    Expert éminent

    Profil pro
    Fabricant et casseur d'avions
    Inscrit en
    Avril 2004
    Messages
    3 813
    Détails du profil
    Informations personnelles :
    Localisation : France, Tarn (Midi Pyrénées)

    Informations professionnelles :
    Activité : Fabricant et casseur d'avions
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Avril 2004
    Messages : 3 813
    Points : 7 638
    Points
    7 638
    Par défaut
    Citation Envoyé par Fiquet
    Ok mais aurais-tu plus de précision? Une formule pour voir ceci? Le problème c'est que je travaille sur une simple lib 2d (SDL avec C++) et je ne travaille pas avec les angles, etc.
    Modjo t'a donné les formules pour gérer une balle qui se déplace à l'intérieur d'un rectangle.

    Petite question... elle est où la tienne, de balle? A l'intérieur d'un rectangle ou à l'extérieur?
    "Errare humanum est, sed perseverare diabolicum"

    Ma page sur DVP.com

  6. #6
    Membre éprouvé

    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2005
    Messages
    634
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Suisse

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2005
    Messages : 634
    Points : 1 205
    Points
    1 205
    Par défaut
    Oui j'allais justement précisé désolé . Elle est à l'extérieur du rectangle. Pour les collision sur les bords de la fenêtre je l'ai déjà fait et exactement avec la méthode qu'à mis Modjo.
    Fiquet
    - FAQ SDL
    - FAQ C++

  7. #7
    Expert éminent

    Profil pro
    Fabricant et casseur d'avions
    Inscrit en
    Avril 2004
    Messages
    3 813
    Détails du profil
    Informations personnelles :
    Localisation : France, Tarn (Midi Pyrénées)

    Informations professionnelles :
    Activité : Fabricant et casseur d'avions
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Avril 2004
    Messages : 3 813
    Points : 7 638
    Points
    7 638
    Par défaut
    Utilise le même principe que pour la balle à l'intérieur du rectangle alors (en inversant les conditions vu que tu es à l'extérieur maintenant...). Sauf que pour chaque test sur une coordonnée, tu rajoutes également un test sur l'autre.
    Exemple, pour tester la collision avec le mur vertical gauche, tu fais:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    SI (BALLE.XP) > TERRAIN.X1
     ALORS // collision avec le bord vertical à gauche
        SI (BALLE.YP)<Y1 ET (BALLE.YP)>Y2 // balle entre bord sup et bord inf du rectangle
          ALORS
            BALLE.VX = -BALLE.VX
    enfin... tu adaptes pour que ça soit un peu optimisé quand même, c'est juste l'idée là...
    "Errare humanum est, sed perseverare diabolicum"

    Ma page sur DVP.com

  8. #8
    Membre éprouvé

    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2005
    Messages
    634
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Suisse

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2005
    Messages : 634
    Points : 1 205
    Points
    1 205
    Par défaut
    Oui c'est la solution que j'avais envisagée mais il me semble qu'il manque quelque chose dans cet alogrithme car je retombe toujours sur mes pattes, si je fait 4 tests pour les 4 côtés en tous les cas j'ai 2 tests qui peuvent se vérifier deux fois donc la balle rebondit dans le vide à un moment.

    Ou alors j'ai vraiment pas tout compris mais comme ceci à mon avis ça ne marche pas, pour l'intérieur d'un rectangle ceci est plus simple car on a des données en moins mais en extérieur c'est autre chose...
    Fiquet
    - FAQ SDL
    - FAQ C++

  9. #9
    Expert éminent

    Profil pro
    Fabricant et casseur d'avions
    Inscrit en
    Avril 2004
    Messages
    3 813
    Détails du profil
    Informations personnelles :
    Localisation : France, Tarn (Midi Pyrénées)

    Informations professionnelles :
    Activité : Fabricant et casseur d'avions
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Avril 2004
    Messages : 3 813
    Points : 7 638
    Points
    7 638
    Par défaut
    Citation Envoyé par Fiquet
    Oui c'est la solution que j'avais envisagée mais il me semble qu'il manque quelque chose dans cet alogrithme car je retombe toujours sur mes pattes, si je fait 4 tests pour les 4 côtés en tous les cas j'ai 2 tests qui peuvent se vérifier deux fois donc la balle rebondit dans le vide à un moment.
    Euh... tu pourrais montrer ton algo complet, parce que je comprends pas toute ta phrase là...
    "Errare humanum est, sed perseverare diabolicum"

    Ma page sur DVP.com

  10. #10
    Membre éprouvé

    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2005
    Messages
    634
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Suisse

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2005
    Messages : 634
    Points : 1 205
    Points
    1 205
    Par défaut
    Ouais je veux bien croire que c'est difficile à comprendre lol. Voilà le code que j'ai en C++ si je reprends ta façon de faire:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
     
    	// Collision verticale gauche
    	if( (m_Position->x + m_Position->w) > RectObj->x)
    	{
    		if( (m_Position->y + m_Position->h) > RectObj->y && m_Position->y < (RectObj->y + RectObj->h) )
    			return 1;
    	}
     
    	// Collision verticale droite
    	if(m_Position->x < (m_Position->x + m_Position->w) )
    	{
    		if( (m_Position->y + m_Position->h) > RectObj->y && m_Position->y < (RectObj->y + RectObj->h) )
    			return 1;
    	}
     
    	// Collision horizontale supérieure
    	if( (m_Position->y + m_Position->h) > RectObj->y)
    	{
    		if( (m_Position->x + m_Position->w) > RectObj->x && m_Position->x < (m_Position->x + m_Position->w) )
    			return 2;
    	}
     
    	// Collision horizontale inférieur
    	if(m_Position->y < (RectObj->y + RectObj->h) )
    	{
    		if( (m_Position->x + m_Position->w) > RectObj->x && m_Position->x < (m_Position->x + m_Position->w) )
    			return 2;
    	}
    m_Position est une structure qui contiente la position de la balle (x, y, width, height) et RectObj la même structure mais pour le rectangle sur lequel on teste la collision. Ce code est censé retourner 1 en cas de collision horizontale et 2 en verticale. Bien entendu que ce code est faux si on regarde la logique mais franchement je vois pas comment on peut le modifier pour que ça marche, il me semble qu'il me manque des informations.. Enfin si c'était possible d'avoir un bout de code

    Merci bien en tout cas.
    Fiquet
    - FAQ SDL
    - FAQ C++

  11. #11
    Expert éminent

    Profil pro
    Fabricant et casseur d'avions
    Inscrit en
    Avril 2004
    Messages
    3 813
    Détails du profil
    Informations personnelles :
    Localisation : France, Tarn (Midi Pyrénées)

    Informations professionnelles :
    Activité : Fabricant et casseur d'avions
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Avril 2004
    Messages : 3 813
    Points : 7 638
    Points
    7 638
    Par défaut
    Citation Envoyé par Fiquet
    Enfin si c'était possible d'avoir un bout de code
    NON!
    Tu es dans le forum algo ici... va sur le forum C++ pour le code!

    Commence déjà par corriger le tien...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    	// Collision verticale droite
    	if(m_Position->x < (m_Position->x + m_Position->w) )
    le membre de droite devrait concerner le rectangle... là elle ne va jamais être vraie ta condition...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    	// Collision horizontale supérieure
    	... && m_Position->x < (m_Position->x + m_Position->w) )
    Même chose ici

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    	// Collision horizontale inférieur
    	... && m_Position->x < (m_Position->x + m_Position->w) )
    Et là aussi.
    "Errare humanum est, sed perseverare diabolicum"

    Ma page sur DVP.com

  12. #12
    Membre éprouvé

    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2005
    Messages
    634
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Suisse

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2005
    Messages : 634
    Points : 1 205
    Points
    1 205
    Par défaut
    Oui enfin désolé je voulais dire de pseudo-code quoi de logique parce que pour un je veux bien être d'accord avec ta logique mais voilà ce que j'ai en corrigeant en pseudo-code:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    	// Collision verticale gauche
    	SI( (m_Position.x + m_Position.w) > RectObj->x ET m_Position.x < (RectObj.x + RectObj.w))
    		SI( (m_Position.y + m_Position.h) > RectObj->y ET m_Position.y < (RectObj.y + RectObj.h) )
    			collision verticale!
     
    	// Collision verticale droite
    	SI( (m_Position.x + m_Position.w) > RectObj.x ET m_Position.x < (RectObj.x + RectObj.w))
    		SI( (m_Position.y + m_Position.h) > RectObj.y ET m_Position.y < (RectObj.y + RectObj.h) )
    			collision verticale!
     
    	// Collision horizontale supérieure
    	SI( (m_Position.y + m_Position.h) > RectObj.y ET m_Position.y < (RectObj.y + RectObj.h))
    		SI( (m_Position.x + m_Position.w) > RectObj.x ET m_Position.x < (RectObj.x + RectObj.w) )
    			collision horizontale!
     
    	// Collision horizontale inférieur
    	SI( (m_Position.y + m_Position.h) > RectObj.y ET m_Position.y < (RectObj.y + RectObj.h))
    		SI( (m_Position.x + m_Position.w) > RectObj.x ET m_Position.x < (RectObj.x + RectObj.w) )
    			collision horizontale!
    On voit que pour finir pour une collision droite ou gauche/supérieure ou inférieure j'ai le même code! Comment faut-il faire pour les différencier les deux??

    [edit]Et en plus entre vertical et horizontal il n'y a que la position des SI qui changent donc aucune différence, je pourrais reprendre seulement un des blocs qui m'indique s'il y a collision c'est tout donc pas de différenciation...

    Merci d'avance.
    Fiquet
    - FAQ SDL
    - FAQ C++

  13. #13
    Expert éminent

    Profil pro
    Fabricant et casseur d'avions
    Inscrit en
    Avril 2004
    Messages
    3 813
    Détails du profil
    Informations personnelles :
    Localisation : France, Tarn (Midi Pyrénées)

    Informations professionnelles :
    Activité : Fabricant et casseur d'avions
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Avril 2004
    Messages : 3 813
    Points : 7 638
    Points
    7 638
    Par défaut
    Citation Envoyé par Fiquet
    On voit que pour finir pour une collision droite ou gauche/supérieure ou inférieure j'ai le même code! Comment faut-il faire pour les différencier les deux??
    Ben éviter le copier-coller bête...
    Dans ton post précédent, les conditions n'étaient pas les mêmes. Maintenant elles le sont. Pourquoi? Je te montre que tu as une erreur dans le second membre de ta condition dans ton code précédent, et là tu me réécris tout de la même manière... y'a un soucis quand même... Fais juste les corrections, ne change pas tout!

    Je reprends:

    Citation Envoyé par moi
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
       // Collision verticale droite
       if(m_Position->x < (m_Position->x + m_Position->w) )
    le membre de droite devrait concerner le rectangle... là elle ne va jamais être vraie ta condition...
    Ce qui donne après correction (je remets tout le paragraphe, histoire que ce soit clair):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
       // Collision verticale droite
       if(m_Position->x < (RectObj->x + RectObj->w) )
       {
          if( (m_Position->y + m_Position->h) > RectObj->y && m_Position->y < (RectObj->y + RectObj->h) )
             return 1;
       }
    Je veux bien corriger les deux autres points que j'ai souligné précédemment, mais je viens de me taper un aller-retour à Toulouse en vtt (ça sentait bon la saucisse grillé du côté d'Ernest Wallon en passant! ), faudrait que je passe à la douche avant. Alors je te laisse faire!
    "Errare humanum est, sed perseverare diabolicum"

    Ma page sur DVP.com

  14. #14
    Membre éprouvé

    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2005
    Messages
    634
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Suisse

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2005
    Messages : 634
    Points : 1 205
    Points
    1 205
    Par défaut
    Citation Envoyé par plegat
    Ben éviter le copier-coller bête...
    Non ce n'est pas du bête copier-coller mais si j'ai modifié c'est que l'on a des tests manquants, si je reprends ton dernier code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
       // Collision verticale droite 
       if(m_Position->x < (RectObj->x + RectObj->w) ) 
       { 
          if( (m_Position->y + m_Position->h) > RectObj->y && m_Position->y < (RectObj->y + RectObj->h) ) 
             return 1; 
       }
    Ca veut dire que si la balle est à hauteur du rectangle et qu'elle est à sa gauche, la balle va rebondire dans le vide, et ce même si elle est à 300 px du rectangle! Tu vois le problème? Ou alors c'est moi qui voit rien et qui est vraiment drogué (lol je n'ai pourtant rien fumé)...
    Fiquet
    - FAQ SDL
    - FAQ C++

  15. #15
    Expert éminent

    Profil pro
    Fabricant et casseur d'avions
    Inscrit en
    Avril 2004
    Messages
    3 813
    Détails du profil
    Informations personnelles :
    Localisation : France, Tarn (Midi Pyrénées)

    Informations professionnelles :
    Activité : Fabricant et casseur d'avions
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Avril 2004
    Messages : 3 813
    Points : 7 638
    Points
    7 638
    Par défaut
    Citation Envoyé par Fiquet
    Tu vois le problème?
    Maintenant, oui!
    "Errare humanum est, sed perseverare diabolicum"

    Ma page sur DVP.com

  16. #16
    Membre éprouvé

    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2005
    Messages
    634
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Suisse

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2005
    Messages : 634
    Points : 1 205
    Points
    1 205
    Par défaut
    Citation Envoyé par plegat
    Citation Envoyé par Fiquet
    Tu vois le problème?
    Maintenant, oui!
    Je suis soulagé alors et aurait tu une idée? Ou il faudrait que je revoie complètement mon système de rebonds
    Fiquet
    - FAQ SDL
    - FAQ C++

  17. #17
    Expert éminent

    Profil pro
    Fabricant et casseur d'avions
    Inscrit en
    Avril 2004
    Messages
    3 813
    Détails du profil
    Informations personnelles :
    Localisation : France, Tarn (Midi Pyrénées)

    Informations professionnelles :
    Activité : Fabricant et casseur d'avions
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Avril 2004
    Messages : 3 813
    Points : 7 638
    Points
    7 638
    Par défaut
    A part rajouter des variables pour garder en mémoire la position précédente de la balle, et faire des tests en fonction de tout ça.
    Du style, pour la collision horizontale supérieure, tester si le y_avant de la balle est au-dessus du y_bord de la boite, et que le y_après est en-dessous...
    "Errare humanum est, sed perseverare diabolicum"

    Ma page sur DVP.com

  18. #18
    Membre éprouvé

    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2005
    Messages
    634
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Suisse

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2005
    Messages : 634
    Points : 1 205
    Points
    1 205
    Par défaut
    Ouais... Aïe moi qui trouvait déjà tous ces if bien moche...

    Sinon pour info ya-t-il une formule plus généraliste avec des angles, trajectoires, etc? Au pire je pourrais revoir ma façon de placer et déplacer les objets dans mon programme...

    Mais je me demande comment celà est fait en général? Car je n'ai trouvé aucun exemple concret (c'est pour un simple jeu de casse-brique... ).

    Sinon si quelqu'un aurait une quelconque idée.

    Merci quand même!
    Fiquet
    - FAQ SDL
    - FAQ C++

  19. #19
    Membre à l'essai
    Inscrit en
    Mars 2005
    Messages
    16
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 16
    Points : 19
    Points
    19
    Par défaut
    Citation Envoyé par plegat
    A part rajouter des variables pour garder en mémoire la position précédente de la balle, et faire des tests en fonction de tout ça.
    Du style, pour la collision horizontale supérieure, tester si le y_avant de la balle est au-dessus du y_bord de la boite, et que le y_après est en-dessous...
    Tu n'en as pas besoin. Avec la position actuelle et la vitesse tu peut calculer ta position précédente.

    Citation Envoyé par plegat
    (c'est pour un simple jeu de casse-brique... Crying or Very sad ).
    Cela c'est une indication importante mon ami! C'est à dire que les rectangles ne se déplacent pas. On peut aussi dire que la hauteur et la largeur de la balle sont toujous inférieur à ceux d'un rectangle. Cela simplifie les choses énormément.

    Les collisions ne sont pas simples cela je peux t'assurer. D'aboord il ne suffit pas d'inverser tous simplement une coordonée. Si il y a une intersection c'est déja une faute. C'est à dire tu dois corriger la position de la balle juste après l'avoir déplacer. Tu dois aussi faire attention à ce que la balle ne saute pas audessus d'un rectangle, c'est à dire ce déplace plus vite que le rectangle est grand.

    Je commence par la détection des différents point de collision.

    La balle est une rectangle qui a 4 coins comme il n'y a pas d'autre rectangle qui peut se placer entre un de ces points il y a toujours au moins un de ces points qui participe à une collision. Comme la balle ne se déplace pas plus vite que les rectangles sont grands il y a au plus 2.

    S'il y a deux points qui participent alors la direction du mouvement est claire. Si ce sont par exemple les deux points d'en bas alors c'est la composante vertical du mouvement qui doit être modifier.

    S'il y a uniquement un point les choses se compliquent. Dans le rectangle il y a aussi un point qui entre en collision. Il est facile de déterminer leurs coordonnées. De leures différence on peut lire quelle composante doit être inversée. Si |x1-x2|<|y1-y2| alors c'est la horizentale. Si |x1-x2|>|y1-y2| alors la vertical. Une situation compliquée est |x1-x2|=|y1-y2|. Ce si ce passe alors est une chose de définition car c'est un cas qui ne se produit pas en réalité (deux distances ne sont jamais exactement égal en physique).

    Le plus simple est de faire en sorte qu'il ne se produit pas. On donne a tous les rectangles des coordonnées paires et à la balle une paire et une non paire. Les composantes de la vitesse sont aussi paires donc conserve la parité. Comme pour il faut que le cas |x1-x2|=|y1-y2| puisse se montrer les coordonées correspondantes doivent soit être tous les deux de la même parité soit tous les deux de parité différentes ce cas est exclu.

    Maintenant nous avons déterminer par quelle axe il faut que la balle rebondit. Il reste à déterminer la position de la balle après qu'elle a rebondie. La procédure est similaire à la reflexion de la lumière en physique si cela te dit quelque chose. On prend le symétrique d'un point qui est entré en collision par l'axe de collision. Sur ce point on contruit alors à nouveau le rectangle de la balle. Ceci est possible car en sait de quelle coin il s'agit et on sait les dimensions de la balle.

    Puis on refait le tous de nouveau car rebondir peut entraîner une nouvelle collision.

    Écrire une implementation élégantes de cet algorithmes est non trivial. Veille à éviter la dublication de code et utilise des fonctions. Ici cela ne rend pas seulement le code plus élégant mais est même vital pour pouvoir le rédigier sans faute.

  20. #20
    Membre éprouvé

    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2005
    Messages
    634
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Suisse

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2005
    Messages : 634
    Points : 1 205
    Points
    1 205
    Par défaut
    Citation Envoyé par ben04
    Citation Envoyé par Fiquet
    (c'est pour un simple jeu de casse-brique... Crying or Very sad ).
    Cela c'est une indication importante mon ami! C'est à dire que les rectangles ne se déplacent pas.
    Pas forcément parce que là je fais la collision pour la balle et la raquette, donc celle si se déplace en Y. Mais j'aurais pensé employé le même algo pour la raquette et les briques ce n'est pas possible?
    Citation Envoyé par ben04
    On peut aussi dire que la hauteur et la largeur de la balle sont toujous inférieur à ceux d'un rectangle.
    Pour quelle raison? Dans mon programme par exemple, la balle fait 40x40 px, la raquette 20x120 et les briques 40x20.
    Fiquet
    - FAQ SDL
    - FAQ C++

Discussions similaires

  1. Effet 3D : Rebond d'une balle
    Par arnolem dans le forum Téléchargez
    Réponses: 0
    Dernier message: 30/09/2011, 16h37
  2. Simuler rebond d'une balle
    Par Coco4486 dans le forum Ogre
    Réponses: 2
    Dernier message: 09/05/2008, 19h26
  3. Réponses: 1
    Dernier message: 02/05/2008, 02h19
  4. rebond d'une balle aux bords de l'écran
    Par The_Duck dans le forum Algorithmes et structures de données
    Réponses: 5
    Dernier message: 11/05/2006, 22h47
  5. Rebond d'une balle sur un sol incliné
    Par franco01 dans le forum Algorithmes et structures de données
    Réponses: 18
    Dernier message: 05/02/2006, 01h20

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo