Ángulo de reflexión

11

Tengo este juego de "estilo de ruptura".

Tengo un cañón en el centro, bloques alrededor del cañón y almohadillas alrededor de los bloques. Así es como se ve el juego:

Un juego circular Breakout

Me las arreglé para obtener la colisión por píxel y mi bola "se refleja " en contacto con los bloques con las siguientes matemáticas:

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

Imagen que representa un cálculo del ángulo de reflexión

Donde la línea azul es la dirección de la bola, y la línea negra (línea base) es la superficie del bloque.

La dirección es un ángulo expresado en radianes (que se puede convertir a grados, por supuesto).
La pelota es movida por:

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

Hasta aquí todo bien.

Mi problema viene ahora, con las almohadillas (los 3 bloques oscuros y grandes alrededor de los pequeños bloques de colores).

A medida que giran, el ángulo de la superficie cambia.
Más que eso, la pelota también debe golpear los lados, entonces, ¿cómo puedo medir la dirección del golpe y la nueva dirección de movimiento de la pelota?

ps : si es necesario, puedo proporcionar código y un swf jugable.


Editar

Ok, el problema con los ángulos se resolvió con vectores , pero todavía tengo el problema con los lados y la colisión trasera.

Abriré otra pregunta para eso y la vincularé aquí.

NemoStein
fuente
3
Si vuelve a asociar sus cuentas, debería obtener el bono de reputación de +100. Debe ser una opción en la pestaña Cuentas de su perfil. Mientras tanto, sin embargo, publicaré esas imágenes para usted.
Grace Note
¿Entiendo que su dirección es un ángulo entre 0 y 360 y para mover la bola que está usando trigonometría?
Jonathan Connell
@Grace, muchas gracias por las imágenes ... @ 3nixios, he agregado más información sobre el ángulo y el movimiento.
NemoStein
Si almacena solo una "dirección" por bloque, quizás vuelva a imaginar cada bloque negro como un grupo de cuatro bloques individuales, donde la cara de "dirección" siempre está orientada hacia afuera. Probablemente habría casos extremos en las cuatro esquinas.
Horacio

Respuestas:

8

No estoy seguro si entendí tu problema correctamente, pero asumí que lo que quieres hacer es encontrar la dirección resultante de tu bola después de una colisión.

Aquí hay un dibujo rápido en mi pizarra que muestra una posible solución para eso:

ingrese la descripción de la imagen aquí

Las flechas verdes representan la velocidad de la pelota (como un vector), los bloques azules representan sus grandes bloques negros y la flecha roja es el vector resultante.

En el primer caso, el bloque azul tiene una inclinación de 30 grados. Una de las formas de solucionar el problema de colisión es llevar todo de vuelta al eje horizontal. Lo que debe hacer es rotar todo 30 grados (la inclinación del bloque) (puede usar matrices para eso).

Luego, verifica de dónde fue la colisión . Si la colisión fue horizontal, invierta el componente x de la velocidad. Si era vertical (como en este caso), el componente y ( ball.Velocity.Y = -ball.Velocity.Y). Esto también hará que la pelota actúe correctamente cuando golpee las esquinas (invertirá ambos componentes). Después de eso, solo tiene que volver a la situación real (que no está en el dibujo).

En el segundo caso, es lo mismo, excepto que la velocidad de la pelota no es perpendicular al bloque. Gira 70 grados, verifica de dónde fue la colisión e invierte los componentes apropiados. Después, vuelves a tu situación real.

Nota: Noté que estás usando un ángulo para representar la dirección en lugar de un vector. Simplemente podría crear un vector para estos cálculos o mantener la misma idea general pero trabajando con ángulos.

Ciertamente, este no es el mejor camino a seguir y estoy seguro de que puede calcularlo de alguna manera, pero creo que es una posible solución a su problema.

Jesse Emond
fuente
Gracias ... Me encantó tu tabla. Lo intentaré en un minuto ... Ahn, ¿y crees que los vectores podrían ser mejores para mantener / trabajar?
NemoStein
Jaja perdona mis pobres habilidades de dibujo.
Jesse Emond
Vaya, en realidad olvidé un paso importante mientras dibujaba. Necesitas rotar hacia atrás -block inclination anglepara tener una respuesta de colisión adecuada ... Tonto.
Jesse Emond
Supongo que se trata de preferencias personales, pero prefiero los vectores MUCHO. Simplemente no tiene que pensar en las matemáticas detrás de ellos la mayor parte del tiempo y generalmente hace que el código sea más limpio. Por lo que podría mantener una Direction(como un vector) y actualizar la posición de la bola, así: ball.Position += ball.Direction * ball.Speed;.
Jesse Emond
@Jesse, no pude hacer esto hasta ahora. Entendí tu método perfectamente, pero no pude implementarlo. Para hacer esto, tendré que reescribir toda la parte que usa ángulos en radianes para usar vectores (de hecho, esto no es mucho). Por ahora intentaré otras alternativas, y si tienes otra, estaré encantado de intentarlo. Gracias.
NemoStein