Collision 2d rapide et précise

17

Je travaille sur un jeu de tir top-down 2D et je dois maintenant aller au-delà de mon système de collision de boîte de délimitation rectangle de base.

J'ai de grands niveaux avec de nombreux sprites différents, tous de formes et de tailles différentes. Les textures pour les sprites sont tous des fichiers png carrés avec des arrière-plans transparents, j'ai donc également besoin d'un moyen d'avoir une collision uniquement lorsque le joueur entre dans la partie colorée de la texture, et non l'arrière-plan transparent.

Je prévois de gérer la collision comme suit:

  1. Vérifiez si des sprites sont à portée du joueur
  2. Faire un test de collision rectangle englobant
  3. Faire une collision précise (là où j'ai besoin d'aide)

Cela ne me dérange pas des techniques avancées, car je veux bien faire les choses avec toutes mes exigences à l'esprit, mais je ne sais pas comment aborder cela. Quelles techniques ou même bibliothèques à essayer. Je sais que je devrai probablement créer et stocker une sorte de forme qui représente avec précision chaque image-objet moins l'arrière-plan transparent.

J'ai lu que par pixel est lent, donc étant donné mes grands niveaux et le nombre d'objets, je ne pense pas que cela conviendrait. J'ai également regardé Box2d, mais je n'ai pas pu trouver beaucoup de documentation, ni aucun exemple de comment le mettre en service avec SFML.

Néophyte
la source

Réponses:

18
  1. Première étape, créez une grille et mettez-la à jour pour chaque objet qui se déplace.
  2. Vérifiez uniquement les collisions entre les objets dans les mêmes carrés.
  3. Vérifiez si la boîte englobante des objets se croise (leur rectangle contenant).
  4. Vérifiez la collision parfaite des pixels en utilisant une version basse résolution du contour (voir Physique des jeux).
  5. Effectuez une vérification normale du tracé de contour comme décrit dans Game Physics (Q 2)

Étape 1:

Créez un tableau 2D grille. Chaque objet sait quels carrés il occupe par sa position x, y et sa largeur et sa hauteur. Si un objet est éloigné, il se dégage de l'ancien carré et met à jour le nouveau carré qu'il occupe.

Cela ne prend que O (n) au total pour n objets. Pour tout objet spécifique O (1).

Étape 2:

Exécutez toutes les vérifications des collisions entre les objets dans les mêmes carrés. Pas besoin d'exécuter des tests de collision entre des objets dans des carrés différents. Un objet peut occuper jusqu'à quatre carrés s'il est de taille moyenne. Cela signifie très peu de contrôles.

Étape 3:

Vérifiez l'intersection entre les rectangles des objets. Si aucune intersection n'existe, arrêtez.

Étape 4:

Vérifiez les pixels parfaits entre les contours des objets uniquement à l'intérieur de la zone d'intersection. Cela devrait être assez rapide. Sinon, créez un tableau booléen basse résolution 2d et vérifiez-le d'abord, si vous y trouvez des collisions, il vous suffira de vérifier un petit segment dans le tableau 2d haute résolution pour vous faire gagner un temps précieux.

Veuillez lire ceci pour un concept sur la façon de diviser votre monde de jeu en une grille de carrés:

Créer un système de détection de collision efficace

Veuillez lire ceci pour l'intuition sur la façon de détecter les collisions parfaites de pixels .

Physique du jeu / Détection de collision 2D AS3

Vous pouvez améliorer considérablement les performances:

  1. Enregistrement d'une version basse résolution (1/16) du contour pour vérifier d'abord.

  2. Vérifier uniquement dans la zone où les deux rects se croisent.

  3. en divisant grossièrement le contour en segments et en ne vérifiant d'abord que les collisions entre segments.

N'hésitez pas à commenter et je développerai.

vérifier dans la zone d'intersection

Wolfdawn
la source
1
Comme Arthur l'a dit, remplacez vos étapes 1. et 2. par une grille et quant à la détection précise des collisions, vous pouvez utiliser une version basse résolution de vos images.
Markus von Broady
1
Et si vous en avez vraiment besoin, vous pouvez également utiliser une technique similaire à ma réponse ici: gamedev.stackexchange.com/questions/38481/…
Markus von Broady
Markus souligne une bonne idée. Vous devez utiliser un tableau booléen 2d ou un tableau 1d qui est traité comme 2d et vous pouvez enregistrer des versions 1/2 1/4 1/8 basse résolution de ce tableau pour accélérer les choses. Cela ne sera probablement pas nécessaire car le calcul sur des tableaux 2d-booléens est très rapide. C'est toujours un outil utile à avoir.
wolfdawn
Si le joueur est entièrement contenu dans une case de la grille, vous ne pouvez vérifier que les objets de cette case. Le joueur peut être dans quatre cases adjacentes à la fois. C'est ça que tu veux dire? Si vous voulez dire l'intersection entre les rectangles, oui, vous n'avez besoin de vérifier les collisions que si elles se croisent.
wolfdawn
1
J'espère que la mise à jour aide à clarifier les choses. Une fois que vous avez écrit du code, vous pouvez le publier dans la révision du code et nous lier pour des commentaires. codereview.stackexchange.com
wolfdawn