Collision en petits groupes: détection du côté de la collision

10

J'écris un clone de breakout (mon premier jeu) et je suis totalement bloqué quant à la façon dont je détermine quel côté de la brique a été touché.

J'ai une méthode de détection de collision qui ressemble à ceci:

DetectCollision(Object a, Object b)

   x = distance(a.x, b.x);
   y = distance(a.y, b.y);

   if (x is smaller than the combined width &  y is smaller is than combined height {
       return true;
   }
return false;  

Cela fonctionne parfaitement, mais j'ai besoin de connaître le côté de la collision et l'emplacement par rapport au centre afin de réagir correctement.

J'ai passé les derniers jours à fouiner mais je suis perdu.

user590903
la source

Réponses:

13

Tout cela peut être glané de la position de la balle par rapport à la position de la brique avec laquelle elle est entrée en collision.

Une fois que vous avez détecté une collision:

if(ballPosition.y <= brickPosition.y - (brickHeight/2))
  //Hit was from below the brick

if(ballPosition.y >= brickPosition.y + (brickHeight/2))
  //Hit was from above the brick

if(ballPostion.x < brickPosition.x)
  //Hit was on left

if(ballPostion.x > brickPosition.x)
  //Hit was on right

Les deux premiers vérifient si la balle est au-dessus ou au-dessous de la brique. Si ni l'un ni l'autre, il doit être à côté de la brique, alors vérifiez de quel côté il est. Cela devra être modifié pour s'adapter à l'endroit où vous prenez l'emplacement, c'est-à-dire brickPosition est le centre de la brique ou brickPosition est le coin supérieur gauche.

MichaelHouse
la source
1
Mais comment utiliseriez-vous cela pour repositionner le joueur, car si le joueur se déplace à l'intérieur d'une brique, plusieurs de ces conditions seront remplies, et si vous réinitialisez le x souhaité au bord du mur, par exemple s'il a touché la touche d'une brique définissez le x souhaité exactement à côté du mur, alors cela ne fonctionnerait pas vraiment parce que lorsque vous vérifiez la position théorique du personnage pour voir dans quelle direction il entre en collision, plusieurs de ces conditions seront remplies, alors comment feriez-vous utilisez-le pour réinitialiser le lecteur, devez-vous ajouter d'autres à la fin de chaque si)?
bluejayke
Autant que je sache, le "joueur" dans un jeu de type évasion est la pagaie. La palette ne se déplace pas à l'intérieur d'une brique, et vous ne modifiez pas la position de la palette en fonction de l'interaction de la balle avec les briques. Si c'est ce que vous faites, vous n'avez pas besoin de logique supplémentaire, ne traitez pas le repositionnement avant d'avoir effectué toutes les vérifications de collision. Ou retournez une fois que l'un des contrôles est vrai.
MichaelHouse
8

Vous pouvez utiliser Vector Math pour découvrir les angles entre eux!

Voici une réponse courte:

ballToBrick = ballPosition - brickPosition;
ballToBrick.Normalize();
brickFacing = Vector2(0,1).Normalize();


float angle = acos( Dot(ballToBrick, brickFacing) );

Le parement de brique est un vecteur délicat, c'est le "point de départ" du calcul de l'angle. et si vous voulez que le vecteur pointe vers le haut, faites-le (0, 1), pointez à gauche (-1, 0), à droite (1, 0), pointez vers le bas (0, -1). En supposant que vous êtes dans l'axe OpenGL, où haut et droite sont positifs.

Si vous ne le savez pas, voici les définitions de chaque fonction utilisée:

Vector2.Normalize()
{
    float length = squareroot(x * x + y * y);
    x = x / length;
    y = y / length;
    return this;
}

Dot(Vector2 a, Vector2 b)
{
    return a.x * b.x + a.y * b.y;
}

( https://en.wikipedia.org/wiki/Dot_product )

Référence: http://blog.wolfire.com/2009/07/linear-algebra-for-game-developers-part-2/

Gustavo Maciel
la source