Como calcular o ângulo de retorno?

Eu brinquei com isso por um tempo, mas eu simplesmente não consigo entender.

Eu fiz um tanque que triggers mísseis, e quando os mísseis atingem as paredes, eu quero que eles saltem, mas eu quero que eles saltem para o ângulo certo.

Neste momento eu não tenho nenhum obstáculo, os mísseis apenas saltam quando eles saem do viewportRectangle eu fiz.

A solução que estou procurando é bastante avançada?

Existe uma maneira relativamente simples de fazer isso?

Eu acho que uma maneira mais fácil de fazer isso é usar a velocidade do míssil em vez de calcular ângulos. Digamos que você tenha um míssil que tenha xVelocity e yVelocity para representar seu movimento horizontal e verticalmente. Essas velocidades podem ser positivas ou negativas para representar esquerda, direita, para cima ou para baixo.

  • Se um míssil atingir uma borda superior ou inferior, inverterá o sinal da yVelocity .
  • Se um míssil atingir uma borda esquerda ou direita, inverta o sinal da xVelocity .

Isso manterá o movimento no eixo oposto o mesmo.

Tomando emprestada a imagem da resposta de Chris , digamos que o míssil começa na posição I.

Ângulo de reflexão

Com o xVelocity e yVelocity ambos sendo positivos (em charts 2D direito e para baixo são tipicamente positivos) o míssil viajará na direção indicada. Vamos apenas atribuir valores de

 xVelocity = 3 yVelocity = 4 

Quando o míssil atinge a parede na posição C , sua xVelocity não deve mudar, mas sua yVelocity deve ser invertida para -4, de modo que ela viaje de volta na direção para cima, mas continue indo para a direita.

O benefício desse método é que você só precisa acompanhar os xPosition , yPosition , xVelocity e yVelocity de um míssil. Usando apenas esses quatro componentes e a taxa de atualização do seu jogo, o míssil sempre será redesenhado na posição correta. Uma vez que você entra em obstáculos mais complicados que não estão em ângulos retos ou estão se movendo, será muito mais fácil trabalhar com velocidades X e Y do que com ângulos.

Você pode pensar que, porque suas paredes estão alinhadas com os eixos coordenados, faz sentido escrever código de caso especial (para uma parede vertical, negar a coordenada x da velocidade; para uma parede horizontal, anular a coordenada y da velocidade ). No entanto, uma vez que você tenha o jogo funcionando bem com paredes verticais e horizontais, provavelmente a próxima coisa que você vai pensar é: “e as paredes em ângulos arbitrários?” Então vale a pena pensar no caso geral desde o começo.

No caso geral, suponha que seu míssil tenha velocidade v e atinja uma parede com superfície n normal.

Míssil com vetor v prestes a bater obliquamente em uma parede com superfície n normal.

Dividir v em componentes perpendiculares à parede e paralelamente a ela.

Triângulo retângulo com hipotenusa para v, lado curto u paralelo à parede e lado longo w paralelo à parede.

Onde:

u = ( vn / nn ) n
w = vu

Aqui, v · n é o produto escalar dos vetores v e n . Veja o link para uma explicação de como calculá-lo. O produto escalar n · n avalia o quadrado do comprimento do vetor normal; se você sempre mantém suas normais na forma de vetores unitários, então n · n = 1 e você pode omitir a divisão.

Depois de saltar, o componente de movimento paralelo à parede é afetado pela fricção f , e o componente perpendicular à parede é afetado pela elasticidade, que pode ser dada na forma de um coeficiente de restituição r .

Então a velocidade após a colisão é v = f wr u . Em uma colisão perfeitamente elástica, sem atrito, v = wu ; isto é, o movimento é refletido sobre o normal no ponto de colisão, como no diagrama dado na resposta de Bill.

Essa abordagem funciona da mesma forma em três dimensões também.

(Obviamente, esta é uma noção muito simplificada de saltos; ela não leva em conta o momento angular ou a deformação. Mas, para muitos tipos de videogames, esse tipo de simplificação é perfeitamente adequado.)

Para partículas perfeitas (& luz) o ângulo de reflection é igual ao ângulo de incidência, como ilustrado por este diagrama (de commons.wikimedia.org).

Ângulo de reflexão

Faça uma pesquisa por “ângulo de reflection” (sem as aspas) no Google.

É um pouco mais complicado quando se leva em conta a elasticidade e os materiais do object e os obstáculos;)

Eu tive esse problema, a única maneira que encontrei foi separar os eixos de colisão!

Tente:

 x += velocity * Math.cos(angle * Math.PI /180); y += velocity * Math.sin(angle * Math.PI /180); if (x < 0 || x > canvas.width) { angle = 180 - angle; } else if (y < 0 ||y > canvas.height) { angle = 360 - angle; } 

Espero que isso ajude você!

Como um aparte à pergunta física específica que você está perguntando, eu recomendaria o livro “Começando Matemática e Física para Programadores de Jogo” por Wendy Stahler. Eu achei bastante útil para meus projetos de programação de jogos / física.

O código que acompanha o livro é C ++, mas se você conhece o C #, seria muito fácil fazer a conversão.

Tenha um bom dia!

Não é nada complicado – pseudo-código:

 angleObjectHitWall = a; bounceAngle = 180-a; 

Claro que este é um cálculo muito simples, e é totalmente irrelevante quando você começa a levar em conta fatores como material, gravidade, paredes que não são retas, etc …

180-a não funcionará em todas as instâncias, a menos que você esteja meramente trabalhando em um salto em uma superfície superior quando X está aumentando.

Uma direção a seguir é o fórum XNA ou o código de exemplo XNA. É C # e é para construir jogos. Eu não estou dizendo que você quer construir seus jogos no XNA, mas é uma ótima ferramenta, e é grátis.

Esta é realmente uma questão de física, por isso, se você não é um físico (e desde que você está fazendo esta pergunta, eu vou assumir que você não é) vai exigir muita leitura e brainstorming para acertar.

Sugiro ler esta input da wikipedia para ter uma ideia básica sobre a profundidade da sua pergunta.

Se você quiser apenas “parecer plausível”, então eu não me preocuparia muito com isso e usaria a resposta de Bill the Lizard , mas se você quiser fazer o certo, terá uma aventura e tanto. Não deixe que isso te assuste! Boa sorte!

 if(!Collide(Missle, Mainchar)){ (Velocity.x)*-1; (Velocity.y)*-1; } 

Funciona e é simples, boa sorte.