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

C++ Discussion :

Test de collision


Sujet :

C++

  1. #1
    Membre chevronné
    Avatar de ZouBi
    Inscrit en
    Octobre 2007
    Messages
    508
    Détails du profil
    Informations professionnelles :
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Octobre 2007
    Messages : 508
    Par défaut Test de collision
    Bonjour,
    voilà dans un jeu de plate forme à la mario, je souhaite tester la collision entre par exemple le personnage, et un element.
    J'ai fait une fonction, qui renvoit la direction de la collision.
    C'est à dire, si le personnage le touche par le haut, le bas, la gauche ou la droite.
    Voici cette fonction :

    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
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
     
    if(
    			Perso.getVitesse()>0
    			&&
    			(
    				( (Perso.getX()+Perso.getW()) <= El.getX()
    				&&
    				(Perso.getX()+Perso.getW()+Perso.getVitesse()) > El.getX() )
    				||
    				( (Perso.getX()+Perso.getW()) >= El.getX()
    				&&
    				(Perso.getX()+Perso.getW()+Perso.getVitesse()) <= (El.getX()+El.getW()) )
    				||
    				( (Perso.getX()+Perso.getW()) < (El.getX()+El.getW())
    				&&
    				(Perso.getX()+Perso.getW()+Perso.getVitesse()) >= (El.getX()+El.getW()) )
    			)
    			&&
    			(
    				( Perso.getY() >= El.getY()
    				&&
    				Perso.getY() < (El.getY()+El.getH()) )
    				||
    				( Perso.getY()+Perso.getH() > El.getY()
    				&&
    				(Perso.getY()+Perso.getH())  <= (El.getY() + El.getH()) )
    				||
    				( Perso.getY() <= El.getY()
    				&&
    				(Perso.getY()+Perso.getH()) >= (El.getY()+El.getH()) )
    			)
    		)
    		{
    				col = D_DROITE;
    		}
    		else if(
    			Perso.getVitesse()<0
    			&&
    			(
    				( Perso.getX() >= (El.getX() + El.getW())
    				&&
    				(Perso.getX() + Perso.getVitesse()) < (El.getX() + El.getW()) )
    				||
    				( Perso.getX() <= (El.getX() + El.getW())
    				&&
    				(Perso.getX()+Perso.getVitesse()) >= El.getX() )
    				||
    				( Perso.getX() > El.getX()
    				&&
    				(Perso.getX()+Perso.getVitesse()) <= El.getX() )
    			)
    			&&
    			(
    				( Perso.getY() >= El.getY()
    				&&
    				Perso.getY() < (El.getY()+El.getH()) )
    				||
    				( Perso.getY()+Perso.getH() > El.getY()
    				&&
    				(Perso.getY()+Perso.getH())  <= (El.getY() + El.getH()) )
    				||
    				( Perso.getY() <= El.getY()
    				&&
    				(Perso.getY()+Perso.getH()) >= (El.getY()+El.getH()) )
    			)
    		)
    		{
    			col = D_GAUCHE;
    		}
    		else if(
    			Perso.getSaut()<=0
    			&&
    			(
    				( (Perso.getY()+Perso.getH()) <= El.getY()
    				&&
    				(Perso.getY()+Perso.getH()-Perso.getSaut()) > El.getY() )
    				||
    				( (Perso.getY()+Perso.getH()) >= El.getY()
    				&&
    				(Perso.getY()+Perso.getH()-Perso.getSaut()) <= (El.getY()+El.getH()) )
    				||
    				( (Perso.getY()+Perso.getH()) > (El.getY()+El.getH())
    				&&
    				(Perso.getY()+Perso.getH()-Perso.getSaut()) <= (El.getY()+El.getH()) )
    			)
    			&&
    			(
    				( Perso.getX() >= El.getX()
    				&&
    				Perso.getX() < (El.getX()+El.getW()) )
    				||
    				( Perso.getX()+Perso.getW() > El.getX()
    				&&
    				(Perso.getX()+Perso.getW())  <= (El.getX() + El.getW()) )
    				||
    				( Perso.getX() < El.getX()
    				&&
    				(Perso.getX()+Perso.getW()) >= (El.getX()+El.getW()) )
    			)
    		)
    		{
    				col = D_BAS;
    		}
    		else if(
    			Perso.getSaut()>0
    			&&
    			(
    				( Perso.getY() >= (El.getY() + El.getH())
    				&&
    				(Perso.getY()-Perso.getSaut()) < (El.getY() + El.getH()) )
    				||
    				( Perso.getY() <= (El.getY() + El.getH())
    				&&
    				(Perso.getY()-Perso.getSaut()) >= El.getY() )
    				||
    				( Perso.getY() > El.getY()
    				&&
    				(Perso.getY()-Perso.getSaut()) <= El.getY() )
    			)
    			&&
    			(
    				( Perso.getX() >= El.getX()
    				&&
    				Perso.getX() < (El.getX()+El.getW()) )
    				||
    				( Perso.getX()+Perso.getW() > El.getX()
    				&&
    				(Perso.getX()+Perso.getW())  <= (El.getX() + El.getW()) )
    				||
    				( Perso.getX() < El.getX()
    				&&
    				(Perso.getX()+Perso.getW()) >= (El.getX()+El.getW()) )
    			)
    		)
    		{
    			col = D_HAUT;
    		}
    		else
    		{
    			col = D_RIEN;
    		}
    C'est très lourd...
    Bon, getH(), getW(), getX(), et getY() renvoit respectiment la taille, et coordonnées des membres, comme vous l'avez surement deviné.

    getVitesse(), renvoit la vitesse en pixels du personnage à laquelle il se déplace. ( >0, il court sur la droite, <0, il court sur la gauche )

    getSaut(), renvoit la valeur du saut en pixels ( >0, il descend, <0 il monte ).

    Cette fonction a toujours fonctionné correctement jusqu'à aujourd'hui, où maintenant, dès que je veux me deplacer sur la gauche sur un element, le test de collision devrait seulement me renvoyer D_HAUT, mais renvoit aussi D_GAUCHE maintenant, alors qu'il devrait pas.

    De toute facon, je trouve cet algorithme assez lourd, et j'aimerai avoir le meme algorithme efficace, et n'ayant pas besoin de se servir de getSaut(), getVitesse().

    Donc ma question est, auriez vous dans vos sources, cet algorithme que je cherche tant?
    Qui me permet de detecter s'il y a collision, et dans quelle direction, de deux surface ( x, y, w, h ).

  2. #2
    Membre confirmé Avatar de babar63
    Homme Profil pro
    Développeur jeux vidéos/3d Temps réel
    Inscrit en
    Septembre 2005
    Messages
    241
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France

    Informations professionnelles :
    Activité : Développeur jeux vidéos/3d Temps réel

    Informations forums :
    Inscription : Septembre 2005
    Messages : 241
    Par défaut
    Je n'ai pas trop le courage de regarder ton code mais cela à plutôt l'air affreux
    Le principe de collision est de tester si il n'y as pas collision ce qui donne quatre tests au final voila un petit exemple de code dont je me suis servis pour créer un genre de jeu identique :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    for(std::vector<Rectangle>::iterator iter = collisionBoxes.begin(); iter < collisionBoxes.end(); ++iter )
    {
    	if( (entity.right <= (*iter).left) && (entity.left >= (*iter).right) && (entity.bottom >= (*iter).top) && (entity.top <= (*iter).bottom) )
    			  return false;
    }
    return true
    entity dans mon cas représente la boite de collision d'une entité du jeu (perso,enemy...)

  3. #3
    Membre chevronné
    Avatar de ZouBi
    Inscrit en
    Octobre 2007
    Messages
    508
    Détails du profil
    Informations professionnelles :
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Octobre 2007
    Messages : 508
    Par défaut
    Merci, mais je ne comprends pas vraiment bien ton code...

    Bon j'ai reussi à beaucoup alleger mon 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
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
            if( A.getY() <= B.getY() + B.getH() && A.getY() + A.getH() > B.getY() + B.getH() && A.getX() + 1 < B.getX() + B.getW() && A.getX() + A.getW() +1 > B.getX() )
            {
                col = D_HAUT;
            } else
            if( A.getY() + A.getH() >= B.getY() && A.getY() < B.getY() && A.getX() +1 < B.getX() + B.getW() && A.getX() + A.getW() + 1 > B.getX() )
            {
                col = D_BAS;
            } else
     
            if( A.getX() <= B.getX() + B.getW() && A.getX() + A.getW() > B.getX() + B.getW() && A.getY() - 1 < B.getY() + B.getH() && A.getY() + A.getH() - 1 > B.getY() )
            {
                col = D_GAUCHE;
            } else
            if( A.getX() + A.getW() >= B.getX() && A.getX() < B.getX() && A.getY() - 1 < B.getY() + B.getH() && A.getY() + A.getH() -1 > B.getY() )
            {
                col = D_DROITE;
            }
     
            if(col != D_RIEN)
    		{
    			A.collision(col, B.getType(), B.getSurface());
    			switch(col)
    			{
    				case D_HAUT:
    					B.collision(D_BAS, A.getType(), A.getSurface());
    					break;
    				case D_BAS:
    					B.collision(D_HAUT, A.getType(), A.getSurface());
    					break;
    				case D_GAUCHE:
    					B.collision(D_DROITE, A.getType(), A.getSurface());
    					break;
    				case D_DROITE:
    					B.collision(D_GAUCHE, A.getType(), A.getSurface());
    					break;
    			}
    		}
    Voilà, mais j'ai toujours un soucis, quand je cours vers la gauche ou la droite d'un bloc, trop vite, il va detecter la collision comme Haut, et mon bonhomme va se placer donc au dessus. : /

  4. #4
    Membre confirmé Avatar de babar63
    Homme Profil pro
    Développeur jeux vidéos/3d Temps réel
    Inscrit en
    Septembre 2005
    Messages
    241
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France

    Informations professionnelles :
    Activité : Développeur jeux vidéos/3d Temps réel

    Informations forums :
    Inscription : Septembre 2005
    Messages : 241
    Par défaut
    Je pensais que l'algo serait plus parlant ... enfin bon voila le principe de collision en français cette fois :
    Soit deux rectangle A et B contenant chacun des valeurs : Right-Left-Top-Bottom. Le but de l'algorithme est comme je l'ai dit de tester si il n'y a pas collision et comment le sait-on? Si le coté droit de A(A.Right) est inférieur au coté gauche de B(B.Left) alors il n'y as pas collision tu retournes false. Ainsi de suite Si A.Top < B.Bottom tu retournes false...
    Une fois les quatre tests effectué cela veut obligatoirement dire qu'il y a collision (tu retourne true)!

    Tu pourra t'occuper des tests d'intersections ensuite mais seulement si il y a collision...

    Est-ce que c'est mieux?

  5. #5
    Membre chevronné
    Avatar de ZouBi
    Inscrit en
    Octobre 2007
    Messages
    508
    Détails du profil
    Informations professionnelles :
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Octobre 2007
    Messages : 508
    Par défaut
    Oui, cette méthode est dans le tutorial de SDL de je sais plus quelle membre.
    Je l'ai testé, et dans mon cas, cette methode ne fonctionne pas

  6. #6
    Alp
    Alp est déconnecté
    Expert confirmé

    Avatar de Alp
    Homme Profil pro
    Inscrit en
    Juin 2005
    Messages
    8 575
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Juin 2005
    Messages : 8 575

  7. #7
    Membre confirmé Avatar de babar63
    Homme Profil pro
    Développeur jeux vidéos/3d Temps réel
    Inscrit en
    Septembre 2005
    Messages
    241
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France

    Informations professionnelles :
    Activité : Développeur jeux vidéos/3d Temps réel

    Informations forums :
    Inscription : Septembre 2005
    Messages : 241
    Par défaut
    Peut tu préciser ce que tu compte faire avec plus de détails? Si cette fonction ne marche pas dans ton cas c'est peut être un souci de conception du jeu (mais là c'est qu'une supposition!). Et surtout pourquoi cette fonction ne marche pas? De toute façon, en séparant les tests tu peux également définir quelle partie est en collision ce qui allégerait pas mal ce code qui fait mal aux crane
    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
    if( A.getY() <= B.getY() + B.getH() && A.getY() + A.getH() > B.getY() + B.getH() && A.getX() + 1 < B.getX() + B.getW() && A.getX() + A.getW() +1 > B.getX() )
            {
                col = D_HAUT;
            } else
            if( A.getY() + A.getH() >= B.getY() && A.getY() < B.getY() && A.getX() +1 < B.getX() + B.getW() && A.getX() + A.getW() + 1 > B.getX() )
            {
                col = D_BAS;
            } else
     
            if( A.getX() <= B.getX() + B.getW() && A.getX() + A.getW() > B.getX() + B.getW() && A.getY() - 1 < B.getY() + B.getH() && A.getY() + A.getH() - 1 > B.getY() )
            {
                col = D_GAUCHE;
            } else
            if( A.getX() + A.getW() >= B.getX() && A.getX() < B.getX() && A.getY() - 1 < B.getY() + B.getH() && A.getY() + A.getH() -1 > B.getY() )
            {
                col = D_DROITE;
            }

  8. #8
    Invité
    Invité(e)
    Par défaut
    ZouBi,

    Et si tu découpais un peu ton problème? La condition de ton if() gère trop de choses à la fois. En fait, tu peux déjà simplifier l'expression en constatant que ton personnage et ton obstacle sont deux rectangles, dont l'un a une direction et une vitesse. Plutôt que d'exprimer ta condition avec des coordonnées et des dimensions, commence par l'exprimer avec des rectangles, ce sera sans doute moins coûteux en aspirine.

    Bon courage!

    Carl

  9. #9
    Membre émérite Avatar de HanLee
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    738
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Mai 2004
    Messages : 738
    Par défaut
    En raisonnant sur des intervalles, c'est beaucoup plus concis au fait.

    Boost propose une bibliothèque : http://www.boost.org/libs/numeric/in...c/interval.htm

Discussions similaires

  1. algorithme de collision 3D
    Par chetropinchuste dans le forum Algorithmes et structures de données
    Réponses: 3
    Dernier message: 14/02/2010, 14h16
  2. [java3D][collision]
    Par geofun dans le forum 3D
    Réponses: 7
    Dernier message: 12/02/2007, 15h49
  3. Test de collision en 2D
    Par GLDavid dans le forum OpenGL
    Réponses: 5
    Dernier message: 12/02/2004, 11h12
  4. [XMLRAD] test de nullité
    Par Pm dans le forum XMLRAD
    Réponses: 5
    Dernier message: 29/11/2002, 11h57
  5. test collisions
    Par tatakinawa dans le forum OpenGL
    Réponses: 5
    Dernier message: 08/06/2002, 07h03

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