Risposte:
Se conosci il vettore normale del muro e hai una direzione in arrivo per l'oggetto, allora quello che vuoi è il riflesso di un vettore attraverso un piano .
Se n è un vettore normalizzato e v è la direzione in entrata , allora ciò che vuoi è - (2 ( n · v ) n - v ). Il segno meno spiega il fatto che la formula del riflesso in realtà non inverte la direzione, poiché la velocità di un oggetto si invertirà.
Questa risposta è data in termini di matematica vettoriale, non di un angolo, perché di solito è preferibile se non si ha un motivo esplicito per usare un angolo. Nota che se devi parlare di angoli, l'angolo di riflessione è uguale all'angolo di incidenza. Se l'angolo viene misurato dalla normale, l'angolo in uscita è la negazione dell'angolo in entrata; se l'angolo viene misurato dalla parete, allora è il complemento dell'angolo in arrivo.
Non hai specificato se si trattava di un gioco 2D o 3D. Ma se si tratta di un gioco 2D e le pareti sono garantite per essere orizzontali o verticali e vuoi solo far rimbalzare l'oggetto da loro, c'è un modo molto più semplice che dover affrontare i riflessi.
Basta negare il componente X della velocità dell'oggetto quando si colpisce un muro verticale, o il componente Y della velocità dell'oggetto quando si colpisce un muro orizzontale. Esempio:
if( /* hit vertical wall */ )
{
object.velocity.x *= -1;
}
if( /* hit horizontal wall */ )
{
object.velocity.y *= -1;
}
Ma se ti interessa davvero conoscere l'angolo, quindi in termini generali, l'angolo di riflessione è lo stesso dell'angolo di incidenza. Questo angolo viene misurato in relazione alla normale della parete. Ecco un'immagine che dovrebbe chiarire:
Nel caso in cui sia necessario gestirlo per muri arbitrari, è necessario esaminare come riflettere un vettore. È davvero solo una piccola formula che prende il normale del muro e il vettore di incidenza e restituisce il vettore riflesso per te. Ecco la formula utilizzata da XNA:
public static Vector3 Reflect(Vector3 vector, Vector3 normal)
{
return vector - 2 * Vector3.Dot(vector, normal) * normal;
}
E per il 2D potresti semplicemente fare:
public static Vector2 Reflect(Vector2 vector, Vector2 normal)
{
return vector - 2 * Vector2.Dot(vector, normal) * normal;
}
if it's a 2D game and your walls are guaranteed to be horizontal or vertical
non è corretta. La seconda parte della risposta riguarda l'implementazione corretta. IMHO, l'ordine delle parti dovrebbe essere invertito, presentando prima la soluzione generale e in enfasi, mentre la soluzione ad angolo retto è presentata come una semplificazione per il caso eccezionale.
Si tratta solo di riflettere un vettore lungo il vettore normale delle pareti.