⇨ MENU ⇨ BIBLIOTHEQUE ⇨ box2dlib.bbc
FN_b2ContactListWorld()
⇨ MENU ⇨ BIBLIOTHEQUE ⇨ box2dlib.bbc
FN_b2ContactListWorld()
DESCRIPTION.
La fonction FN_b2ContactListWorld() retourne la première élément de la liste des collisions actuellement présents dans un monde physique Box2d.
SYNTAXE.
kcollision = FN_b2ContactListWorld( monde )
REMARQUES.
monde doit être l'identifiant de la variable ayant reçu la valeur retournée par l'appel de la fonction FN_b2CreateWorld() et qui indique donc le monde physique dans lequel on crée le corps.
La fonction FN_b2ContactListWorld() retourne une valeur numérique identifiant un pointeur, où se trouve la première collision dans monde. Toutes les collisions présentes actuellement sont stockées, les unes à la suite des autres, dans une liste qui devra être parcourue avec d’autres fonctions du module box2dlib, telle que FN_b2ContactGetNext(), FN_b2ContactGetFixtureA(), FN_b2ContactGetFixtureB().
Il est important de mémoriser la valeur retournée par la fonction FN_b2ContactListWorld() dans une variable, car elle devra être fournie à la fonction FN_b2NextContact() pour accéder à la collision suivante dans la liste des collisions actuellement actives dans monde.
Note : si aucune collision n'est actuellement active dans monde, la fonction FN_b2ContactListWorld() retourne 0.
Voir la fonction FN_b2IsTouching() qui sert à savoir si deux corps sont réellement en train de se toucher à cet l’instant. Car parcourir la liste des collisions sans vérifier si les corps se touchent physiquement peut donner de faux positifs.
Chaque collision contient deux formes, fixtures, notées A et B, et chacune de ces formes est associée à un corps. Pour obtenir et analyser toutes les collisions actuellement actives dans monde, il faudra, par exemple, procéder de la façon suivante :
REM --- Localisation de la première collision ---
kcollision = FN_b2ContactListWorld( monde )
kindex = 1
REM --- A faire tant qu'il y a des collisions actives non traitées ---
WHILE kcollision <> 0
REM --- Traitement de la collision ---
kforme_A = FN_b2ContactGetFixtureA( kcollision ) : REM - identification et mémorisation la forme A
kforme_B = FN_b2ContactGetFixtureB( kcollision ) : REM - identification et mémorisation la forme B
kcorps_A = FN_b2FixtureGetBody( kforme_A ) : REM - identification et mémorisation du corps associé a la forme A
kcorps_B = FN_b2FixtureGetBody( kforme_B ) : REM - identification et mémorisation du corps associé a la forme B
PRINT "Collision " ; kindex ; " (Id : " ; kcollision ; " ) contact entre " ; kcorps_A ; " et " ; kcorps_B ; ". "
REM --- Collision suivante ---
kcollision = FN_b2ContactGetNext( kcollision )
kindex += 1
ENDWHILE
Voir la procédure procédure PROC_b2GetContact() qui, le plus souvent, remplacera avantageusement les appels aux fonctions FN_b2ContactGetFixtureA() et FN_b2ContactGetFixtureB().
ATTENTION : la liste des collisions, n’est pas un tableau de données BBC BASIC, mais une structure C interne à Box2D. Donc le pointeur retourné par la fonction FN_b2ContactListWorld() n’est pas un objet BBC BASIC, mais un pointeur C encapsulé, stocké sous forme d’un entier par la bibliothèque.
L'appel de la fonction FN_b2ContactListWorld() permet d'accéder au premier élément de la liste de toutes les collisions actuellement actives dans monde. Il faut ensuite filtrer cette liste, élément par élément, c'est-à-dire répondre à des questions comme : Est-ce que cet objet précis est en collision ? Est-ce que deux types d’objets se touchent ? Quelles collisions faut-il ignorer (capteurs, décor, etc.) ? Pour cela, il ne faut filtrer pas les collisions directement, mais via les formes ou les corps impliqués dans chaque collision.
1. Filtrer par corps.
Par exemple si on souhaite détecter si un corps identifié par kjoueur est un collision avec un autre corps quelconque :
REM --- Localisation de la première collision ---
kcollision = FN_b2ContactListWorld( monde )
REM --- A faire tant qu'il y a des collisions actives non traitées ---
WHILE kcollision <> 0
REM --- Traitement de la collision ---
kcollision = FN_b2ContactListWorld( monde ) : REM - ou avec kcollision = FN_b2ContactGetNext( kcollision )
kforme_A = FN_b2ContactGetFixtureA( kcollision ) : REM - identification et mémorisation la forme A
kforme_B = FN_b2ContactGetFixtureB( kcollision ) : REM - identification et mémorisation la forme B
kcorps_A = FN_b2FixtureGetBody( kforme_A ) : REM - identification et mémorisation du corps associé a la forme A
kcorps_B = FN_b2FixtureGetBody( kforme_B ) : REM - identification et mémorisation du corps associé a la forme B
REM --- recherche si kjoueur est en collision ---
IF kcorps_A = kjoueur OR kcorps_B = kjoueur THEN PROC_Choc : REM - Traitement des collisions avec kjoueur
REM --- Collision suivante ---
kcollision = FN_b2ContactGetNext( kcollision )
ENDWHILE
Cette méthode de filtrage est simple, mais ne fonctionne que pour de petits cas, car il deviendrait inefficace, problématique et lent quand monde contient un nombre de corps élevé. La quantité de calculs demandée à chaque frame solliciterait une grande quantité de ressources de la machine hote.
2. Filtrer par données personnalisées (UserData) méthode recommandée.
Box2D permet d’attacher une donnée utilisateur à un corps avec la procédure PROC_b2UserDataBody() et à une forme avec la procédure PROC_b2UserDataFixture(). On pourra utiliser ces données personnalisées pour ne tester que certains corps et/ou collisions entre deux familles de corps.
Par exemple, si la forme du joueur (kjoueur) est identifié par la donnée 1 et que les formes des projectiles sont identifiés par la donnée 4 :
REM --- Localisation de la première collision ---
kcollision = FN_b2ContactListWorld( monde )
REM --- A faire tant qu'il y a des collisions actives non traitées ---
WHILE kcollision <> 0
REM --- Traitement de la collision ---
kcollision = FN_b2ContactListWorld( monde ) : REM - ou avec kcollision = FN_b2ContactGetNext( kcollision )
kforme_A = FN_b2ContactGetFixtureA( kcollision ) : REM - identification et mémorisation la forme A
kforme_B = FN_b2ContactGetFixtureB( kcollision ) : REM - identification et mémorisation la forme B
REM --- Teste si un des corps est celui du joueur (kjoueur) ---
IF FN_b2UserDataFixture( kforme_A ) = 1 OR FN_b2UserDataFixture( kforme_B ) = 1 THEN
REM --- Si l'un des corps est le joueur, test si l'autre corps et un projectile ---
IF FN_b2UserDataFixture( kforme_A ) = 4 OR FN_b2UserDataFixture( kforme_B ) = 4 THEN
REM --- Identification du projectile ---
IF FN_b2UserDataFixture( kforme_A ) = 1 THEN
kprojectile = FN_b2FixtureGetBody( kforme_B )
ELSE
kprojectile = FN_b2FixtureGetBody( kforme_A )
END IF
REM - Traitement des collisions de kjoueur avec un projectile ---
PROC_Touche( kprojectile )
END IF
END IF
REM --- Collision suivante ---
kcollision = FN_b2ContactGetNext( kcollision )
ENDWHILE
Rappel : la procédure PROC_b2Init devra toujours être appelée avant tout autre fonction ou procédure de box2dlib.bbc.
La procédure FN_b2ContactListWorld() est importée depuis le module box2dlib.bbc.
RUBRIQUES.
Les dessins et les graphismes pour plus de détails sur la création de dessins et de graphismes.
La gestion des couleurs pour plus de détails sur la gestion des couleurs logiques et physiques.
EXEMPLE.
REM --- Importation des modules ---
REM --- Module de la bibliothèque BBC BASIC ---
INSTALL @lib$ + "box2dlib.bbc"
REM --- Initialisation et création du monde ---
PROC_b2Init
kmonde = FN_b2CreateWorld( 0 , -9.81 )
REM --- Creation d'es corps et de leur forme ---
kpetit = FN_b2DynamicBody( kmonde , 2 , 2 , 0 , 0 , 0 , 0 , 0 , 0 )
kgrand = FN_b2DynamicBody( kmonde , 6 , 6 , 0 , 0 , 0 , 0 , 0 , 0 )
kforme_petit = FN_b2BoxFixture( kpetit , 0 , 0 , 0 , 1 , 1 , 0 , 0 , 1 )
kforme_grand = FN_b2BoxFixture( kgrand , 0 , 0 , 0 , 1 , 1 , 0 , 0 , 1 )
REM --- Localisation de la collision ---
kcollision = FN_b2ContactListWorld( monde )
REM --- Traitement de la collision ---
kforme_A = FN_b2ContactGetFixtureA( kcollision ) : REM - identification et mémorisation la forme A
kforme_B = FN_b2ContactGetFixtureB( kcollision ) : REM - identification et mémorisation la forme B
kcorps_A = FN_b2FixtureGetBody( kforme_A ) : REM - identification et mémorisation du corps associé a la forme A
kcorps_B = FN_b2FixtureGetBody( kforme_B ) : REM - identification et mémorisation du corps associé a la forme B
IF ( kcorps_A = kpetit AND kcorps_B = kgrand ) OR ( kcorps_A = kgrand AND kcorps_B = kpetit ) THEN
PRINT "Les deux corps se touchent."
ELSE
PRINT "Les deux corps ne se touchent pas."
END IF
REM --- Fin du programme ---
END
Votre aide est précieuse pour améliorer ce site, alors n'hésitez pas à faire part de
Dans la RETROGICIEL vous trouvez des suggestions simples et classiques pour
TESTER - DÉCOUVRIR - PRATIQUER - APPROFONDIR - EXPLORER
avec un exemple de résolution à télécharger pour vous inspirer.