2010-04-17 2 views
4

Je travaille sur un petit jeu de plateforme/combat 2D avec C++ et SDL, et j'ai beaucoup de problèmes avec la détection de collision. Les niveaux sont constitués d'un tableau de mosaïques, et j'utilise une boucle for pour passer par chacun (je sais que ce n'est peut-être pas la meilleure façon de le faire, et j'ai peut-être besoin d'aide pour ça aussi). Pour chaque côté du personnage, je le déplace d'un pixel dans cette direction et vérifie s'il y a une collision (je vérifie aussi si le personnage bouge dans cette direction). S'il y a une collision, je mets la vélocité à 0 et déplace le joueur vers le bord de la tuile. Mon problème est que si je vérifie d'abord les collisions horizontales et que le joueur se déplace verticalement à plus d'un pixel par image, il gère la collision horizontale et déplace le personnage sur le côté de la tuile même si la tuile est en dessous (ou ci-dessus) le personnage. Si je gère d'abord la collision verticale, elle fait la même chose, sauf qu'elle le fait pour l'axe horizontal.Problèmes de collision de plate-forme 2D avec les deux axes

Comment puis-je gérer les collisions sur les deux axes sans avoir ces problèmes? Y a-t-il une meilleure façon de gérer les collisions que la façon dont je le fais?

+0

Vérifiez-vous vos collisions avant de déplacer votre personnage, ou après avoir bougé puis vérifié? –

+0

Je le vérifie après avoir déplacé le personnage. – ausgat

Répondre

3

XNA's 2D platformer example utilise également une collision à base de tuiles. La façon dont ils le manipulent est assez simple et peut vous être utile. Voici une explication dépouillée de ce qui est là-bas (enlever les choses spécifiques à leur démo):

  1. Après application mouvement, il vérifie les collisions.
  2. Il détermine les tuiles que le joueur chevauche en fonction de la boîte englobante du joueur.
  3. Il itère à travers toutes ces tuiles ...
    1. Si la tuile en cours de vérification n'est pas praticable:
    2. Il détermine la distance sur les axes X et Y le joueur chevauche la tuile non praticables
    3. Collision est résolu que sur l'axe faible profondeur :
      1. Si Y est l'axe peu profond (abs (overlap.y) < abs (overlap.x)), position.y + = overlap.y; de même si X est l'axe peu profond.
      2. Le cadre de sélection est mise à jour basée sur le changement de position
    4. Passez à la tuile suivante ...

Il est en player.cs dans la fonction HandleCollisions() si vous saisir le code et vouloir voir ce qu'ils font spécifiquement là.

+0

C'est probablement bizarre à demander, mais quel est l'axe peu profond? J'ai googlé et je n'ai rien trouvé de similaire. – DMan

+0

Par "Axe peu profond", je veux dire celui qui est moins pénétré par la collision. Par exemple, si la position du personnage est calculée sur 5 unités sur l'axe Y et 10 unités sur l'axe X, Y est l'axe peu profond. – chaosTechnician

0

Oui. La collision basée sur le vecteur sera beaucoup mieux que sur la base de carreaux. Définissez chaque bord d'une tuile en lignes (il y a des raccourcis, mais ignorez-les pour l'instant). Maintenant, pour voir si une collision s'est produite, trouvez la ligne horizontale et verticale la plus proche. si vous prenez le signe de lastPos.x * LineVector.y - lastPos.y * LineVector.x et comparez avec thisTurnsPos.x * LineVector.y - ThisTurnsPos.y * LinePos.x. Si les signes de ces deux valeurs diffèrent, vous avez franchi cette ligne ce tic. Cela ne vérifie pas si vous avez traversé la fin d'un segment de ligne. Vous pouvez former un produit scalaire entre le même lineVector et votre curPosition (une petite erreur ici, mais assez bonne probablement) et il est négatif ou supérieur à la grandeur de la ligne, vous n'êtes pas dans ce segment et aucune collision n'est survenue .

Maintenant, c'est farily complexe et vous pourriez probablement partir avec une simple vérification de la grille pour voir si vous avez traversé la zone d'un autre carré. Mais! L'avantage de le faire avec des vecteurs est qu'il résout le déplacement plus vite que la taille du problème de boîte de collision et (plus important encore), vous pouvez utiliser des lignes non axées pour vos collisions. Ce système fonctionne pour tous les vecteurs 2D (et avec un peu de massage, 3D aussi.) Il vous permet également de glisser votre personnage le long de la zone de collision plutôt facilement car vous avez déjà effectué 99% des calculs nécessaires pour Trouvez où vous êtes censé être après une collision. J'ai passé en revue quelques détails de mise en œuvre, mais je peux dire que j'ai utilisé la méthode ci-dessus dans d'innombrables jeux vidéo commerciaux et cela a fonctionné comme un charme. Bonne chance!

+0

J'ai oublié de mentionner que je suis relativement nouveau dans le développement de jeux, et le jeu sur lequel je travaille est assez simple. La détection de collisions à base de vecteurs semble mieux, mais je ne pense pas que je puisse le faire pour l'instant. – ausgat

Questions connexes