Respostas:
Se você conhece o vetor normal da parede e tem uma direção de entrada para o objeto, então o que você quer é o reflexo de um vetor através de um plano .
Se n é um vetor normalizado e v é a direção de entrada , então o que você deseja é - (2 ( n · v ) n - v ). O sinal de menos explica o fato de que a fórmula de reflexão não inverte realmente a direção, pois a velocidade de um objeto se inverte.
Essa resposta é dada em termos de matemática vetorial, não de ângulo, porque geralmente é preferível se você não tiver um motivo explícito para usar um ângulo. Observe que, se você precisar falar sobre ângulos, o ângulo de reflexão é igual ao ângulo de incidência. Se o ângulo é medido a partir do normal, o ângulo de saída é a negação do ângulo de entrada; se o ângulo é medido a partir da parede, é o complemento do ângulo de entrada.
Você não especificou se era um jogo 2D ou 3D. Mas se é um jogo em 2D e suas paredes são garantidas como horizontais ou verticais e você apenas deseja ressaltar o objeto, há uma maneira muito mais fácil do que lidar com reflexões.
Simplesmente negue o componente X da velocidade do objeto ao atingir uma parede vertical ou o componente Y da velocidade do objeto ao atingir uma parede horizontal. Exemplo:
if( /* hit vertical wall */ )
{
object.velocity.x *= -1;
}
if( /* hit horizontal wall */ )
{
object.velocity.y *= -1;
}
Mas se você realmente se importa em conhecer o ângulo, em termos gerais, o ângulo de reflexão é o mesmo que o ângulo de incidência. Este ângulo é medido em relação ao normal da parede. Aqui está uma figura que deve deixar claro:
Caso você precise lidar com isso para paredes arbitrárias, precisará analisar como refletir um vetor. É realmente apenas uma fórmula pequena que pega o vetor normal e de incidência da parede e retorna o vetor refletido para você. Aqui está a fórmula que o XNA usa:
public static Vector3 Reflect(Vector3 vector, Vector3 normal)
{
return vector - 2 * Vector3.Dot(vector, normal) * normal;
}
E para 2D, você pode simplesmente fazer:
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
não está correta. A segunda parte da resposta aborda a implementação correta. IMHO, a ordem das partes deve ser revertida, apresentando a solução geral primeiro e com ênfase, enquanto a solução em ângulo reto é apresentada como uma simplificação para o caso excepcional.
Trata-se de refletir um vetor ao longo do vetor normal das paredes.