Breakout Collision: rilevamento del lato della collisione


10

Sto scrivendo un clone breakout (il mio primo gioco) e sono totalmente bloccato su come ho capito da che parte del mattone è stato colpito.

Ho un metodo di rilevamento delle collisioni che assomiglia a questo:

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;  

Funziona perfettamente, ma ho bisogno di conoscere il lato della collisione e la posizione rispetto al centro per poter rispondere correttamente.

Ho passato gli ultimi giorni a curiosare in giro ma mi sono perso.

Risposte:


13

Tutto ciò può essere ricavato dalla posizione della palla rispetto alla posizione del mattone con cui si è scontrato.

Dopo aver rilevato una collisione:

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

I primi due controllano se la palla è sopra o sotto il mattone. Se nessuno dei due deve essere vicino al mattone, quindi controlla da che parte si trova. Dovrà essere ruotato per adattarlo alla posizione da cui stai prendendo la posizione, ovvero brickPosition è il centro del mattone o brickPosition è l'angolo in alto a sinistra.


1
Ma come useresti questo per riposizionare il giocatore, dal momento che il giocatore si muove all'interno di un mattone, saranno soddisfatte più di quelle condizioni e se resetti la x desiderata sul bordo del muro, ad esempio se preme il tasto di un mattone imposta la x desiderata esattamente accanto al muro, quindi non funzionerebbe davvero perché quando controlli la posizione teorica del personaggio per vedere da quale direzione si scontra, verranno soddisfatte più di queste condizioni, quindi come faresti usalo per resettare il player, devi aggiungere altro alla fine di ogni if)?
Bluejayke,

Per quanto ne so il "giocatore" in una partita tipo breakout è la pagaia. La paletta non si muove all'interno di un mattone, né stai cambiando la posizione della paletta in base all'interazione della palla con i mattoni. Se è quello che stai facendo, non hai bisogno di ulteriore logica, ma non elaborare il riposizionamento fino a quando non hai eseguito tutti i controlli di collisione. O restituire una volta che uno dei controlli è vero.
MichaelHouse

8

Puoi usare Vector Math per scoprire gli angoli tra loro!

Ecco una breve risposta:

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


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

Il rivestimento del mattone è un vettore complicato, è il "punto iniziale" del calcolo dell'angolo. e se vuoi che il vettore punti verso l'alto, fallo (0, 1), punta a sinistra (-1, 0), a destra (1, 0), punta verso il basso (0, -1). Supponendo che tu sia nell'asse OpenGL, dove su e destra sono positivi.

Se non lo sai, ecco le definizioni di ciascuna funzione utilizzata:

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 )

Riferimento: http://blog.wolfire.com/2009/07/linear-algebra-for-game-developers-part-2/

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.