Bueno Richard, te preparo una explicación desde 0.
Video:
Lo he subido al foro también, el formato es asf pero un programa que lea MP4 debería leerlo, hasta se le puede cambiar la extensión de asf a MP4 y no me ha dado problema:
https://foro.rinconmatematico.com/index.php?action=dlattach;topic=129751.0;attach=35607Cuando el meteoro sale desde la nave naranja, o cuando la toca, se le asigna (medio al azar) una rotación hacia un lado u otro.
Y una velocidad (también) hacia arriba, hacia la nave azul.
Por ahora, quiero que en ese caso, cuando el meteoro vaya a tocar la nave azul, esté en el centro de la pantalla.
En el video se ve que el meteoro en esos casos hace cualquier cosa, a veces choca contra una pared porque va muy hacia un costado, otras va un poco al centro pero no suficiente, etc.
Eso es lo que quiero arreglar.
Por ejemplo, sabiendo que el meteoro debido a la rotación se moverá cierta cantidad de píxeles hacia la izquierda, hay que asignarle una velocidad X hacia la derecha para contrarrestar. ¿Cuánto se debe asignar, cómo se calcula? Es lo que quiero averiguar.
En cada frame, o ejecución del código, la velocidad X del meteoro es influída por su rotación así:
MeteorXSpeed = MeteorXSpeed+MeteorRotation/1000
Luego la rotación disminuye así:
MeteorRotation = MeteorRotation/1.01;
No sé si necesitas más que eso.
Los cálculos los intento así:
Calculo la distancia Y entre el meteoro y el lugar Y al que debe llegar:
DistanciaY = MeteorY-ApuntandoY;
Calculo cuántos frames o ejecuciones tardará en llegar hasta ese punto (o línea, es el eje X, en un punto de Y):
TardanzaY = Math.ceil(DistanciaY/-MeteorYSpeed);
La distancia X entre el meteoro y el lugar X al que debe llegar:
DistanciaX = ApuntandoX+400-MeteorX;
400 es la mitad x de la pantalla.
Cuánto se va a mover el meteoro debido a la rotación:
MovimientoPorCurva = MeteorRotation*0.101*(1-Math.pow(1.01, -TardanzaY));
Creo haber comprobado que esa fórmula está bien.
Finalmente: La velocidad X que el meteoro debe tener para que cuando llegue a la nave azul, esté en el medio de la pantalla:
MeteorXSpeed = DistanciaX/TardanzaY-MovimientoPorCurva;
Creo que esto es lo que está mal, lo que hace que el meteoro vaya demasiado a la izquierda, etc.
Si no es eso, no sé, quizá algún error de mi lenguaje, que maneja mal los decimales, pero no debería haber las diferencias abismales que hay.
Puedo asignar los valores que quieras para ir buscando el problema:
- Rotación inicial
- Velocidad Y inicial.
- Posición X inicial
Te pongo un ejemplo de salida de datos:
MeteorRotation: -10.80258038398
MeteorYSpeed: -1.48908506263471
ApuntandoX: 0
ApuntandoY: 20.5
DistanciaY: 525
TardanzaY: 353
DistanciaX: 0
MovimientoPorCurva: -1.05852163876754
MeteorXSpeed: 1.05852163876754
Frames: 323
MeteorX final: 494.210208441683
InfluenciaDeRotacion final: -1.04720298986347
La rotación fue poca, y cuando eso sucede no termina tan alejado de x 400, pero hay bastante diferencia entre 400 y 494.
Frames es la cantidad de frames o ejecuciones ocurridas. Es menor que tardanzaY, eso puede ser un problema, pero mi teoría es que como el meteoro es grande el choque con la nave azul se capta antes de que su centro llegue al punto calculado. Y yo no observo que por 20 frames más vaya a cambiar mucho, cuando llega arriba la velocidad X es casi 0.
InfluenciaDeRotacion final es lo que medí, con el programa, que la rotación influyó. O sea, hizo que el meteoro se mueva 1. algo hacia la izquierda. La diferencia con lo que calculé, MovimientoPorCurva, es mínima así que no debería haber problema.
Otra salida:
MeteorRotation: 39.6237854657805
MeteorYSpeed: -2.04296611856807
ApuntandoX: 0
ApuntandoY: 20.5
DistanciaY: 525
TardanzaY: 257
DistanciaX: 0
MovimientoPorCurva: 3.69177198746066
MeteorXSpeed: -3.69177198746066
Frames: 238
MeteorX final: 111.113794405423
InfluenciaDeRotacion final: 3.62721027605372
El meteoro terminó en x 111 en vez de 400.
¿Qué falla?
Luego de escribir esto tuve que salir, anduve pensándolo en el viaje y demás, y según eso la fórmula sería:
MeteorXSpeed = DistanciaX/TardanzaY-MovimientoPorCurva/TardanzaY;
¡Pero parece que funciona mal también! ¿entonces?