Ângulo de reflexão

11

Eu tenho esse jogo "estilo Breakout".

Eu tenho um canhão no centro, blocos ao redor do canhão e almofadas ao redor dos blocos. É assim que o jogo se parece:

Um jogo circular Breakout

Consegui obter a colisão por pixel e minha bola " reflete " no contato com os blocos com a seguinte matemática:

Ball.Direction = 2 * (Block.Direction - Ball.Direction) + 180;

Imagem que descreve um cálculo do ângulo de reflexão

Onde a linha azul é a direção da bola e a linha preta (linha de base) é a superfície do bloco.

Direção é um ângulo expresso em radiano (que pode ser convertido em graus, é claro).
A bola é movida por:

// Event.ENTER_FRAME
x += Math.sin(Direction) * Velocity;
y -= Math.cos(Direction) * Velocity;

Por enquanto, tudo bem.

Meu problema vem agora, com as almofadas (os três blocos escuros e grandes ao redor dos pequenos blocos coloridos).

Quando eles se viram, o ângulo da superfície muda.
Mais do que isso, a bola deve bater nos lados também, então, como posso medir a direção do golpe e a nova direção do movimento da bola?

ps : Se necessário, eu posso fornecer código e um swf jogável.


Editar

Ok, o problema com ângulos foi resolvido com Vetores , mas ainda tenho o problema com lados e colisão traseira.

Vou abrir outra pergunta e vincular aqui.

NemoStein
fonte
3
Se você reassociar suas contas, receberá o bônus de reputação +100. Deve ser uma opção na guia Contas do seu perfil. Nesse meio tempo, porém, postarei essas imagens para você.
Grace Note
Acho que sua direção é um ângulo entre 0 e 360 ​​e para mover a bola você está usando trigonometria?
Jonathan Connell
@ Grace, muito obrigado pelas imagens ... @ 3nixios, adicionei mais informações sobre o ângulo e o movimento.
NemoStein 16/06
Se você armazena apenas uma "direção" por bloco, talvez você reimagine cada bloco preto como um grupo de quatro blocos individuais, onde a face da "direção" está sempre voltada para o exterior. Provavelmente haveria casos extremos nos quatro cantos.
21811 horatio

Respostas:

8

Não tenho certeza se entendi seu problema corretamente, mas presumi que o que você quer fazer é encontrar a direção resultante da sua bola após uma colisão.

Aqui está um rápido desenho no meu quadro branco que mostra uma possível solução para isso:

insira a descrição da imagem aqui

As setas verdes representam a velocidade da bola (como um vetor), os blocos azuis representam seus grandes blocos pretos e a seta vermelha é o vetor resultante.

No primeiro caso, o bloco azul tem uma inclinação de 30 graus. Uma maneira de corrigir o problema da colisão é trazer tudo de volta ao eixo horizontal. O que você precisa fazer é girar tudo em 30 graus (a inclinação do bloco) (você pode usar matrizes para isso).

Então, você verifica de onde foi a colisão . Se a colisão for horizontal, inverta o componente x da velocidade. Se fosse vertical (como neste caso), o componente y ( ball.Velocity.Y = -ball.Velocity.Y). Isso também fará com que a bola atue corretamente quando bate nos cantos (inverte os dois componentes). Depois disso, você só precisa voltar à situação real (que não está no desenho).

No segundo caso, é a mesma coisa, exceto que a velocidade da bola não é perpendicular ao bloco. Você gira 70 graus, verifica a origem da colisão e inverte os componentes apropriados. Depois, você volta à sua situação real.

Nota: notei que você está usando um ângulo para representar a direção em vez de um vetor. Você pode apenas criar um vetor para esses cálculos ou manter a mesma ideia geral, mas trabalhando com ângulos.

Certamente este não é o melhor caminho a percorrer e tenho certeza de que você pode calculá-lo de alguma forma, mas acho que é uma possível solução para o seu problema.

Jesse Emond
fonte
Obrigado ... Adorei seu fórum. Vou tentar em um minuto ... Ahn, e você acha que os vetores poderiam ser melhores para manter / trabalhar?
NemoStein 16/06
Haha perdoa minhas más habilidades de desenho.
precisa
Opa, na verdade eu esqueci uma etapa importante ao desenhar .. Você precisa girar para trás -block inclination anglepara ter uma resposta de colisão apropriada.
precisa
Eu acho que é sobre preferências pessoais, mas eu prefiro vetores muito. Você não precisa pensar na matemática por trás deles na maioria das vezes e isso geralmente torna o código mais limpo. Então, você poderia manter um Direction(como um vetor) e atualizar a posição da bola assim: ball.Position += ball.Direction * ball.Speed;.
Jesse Emond
@ Jessie, eu não era capaz de fazer isso até agora. Entendi perfeitamente o seu método, mas não consegui implementá-lo. Para fazer isso, precisarei reescrever a parte inteira que usa ângulos radianos para usar vetores (isso não é muito, na verdade). Por enquanto, tentarei outras alternativas e, se você tiver outra, ficarei feliz em tentar. Obrigado.
NemoStein 16/06