Ya analicé esto bastante y no encuentro el motivo de la falla.
Explicaré este video:
https://youtu.be/O3L7eNHPpp8
Cuando 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, el meteoro esté en el centro de la pantalla.
En el video se ve que en esos casos queda en cualquier lado, 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 necesitan 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, el meteoro esté en el medio de la pantalla:
MeteorXSpeed = DistanciaX/TardanzaY-MovimientoPorCurva/TardanzaY;
También creo haber comprobado que eso está bien, aunque tengo más dudas.
Entiendo que quizá haya 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 quieran para ir buscando el motivo del error:
- Rotación inicial
- Velocidad Y inicial.
- Posición X inicial
Les pongo un ejemplo de salida de datos:
MeteorRotation: 10
MeteorYSpeed: -1.85306421986458
ApuntandoX: 0
ApuntandoY: 20.5
DistanciaY: 525
TardanzaY: 284
DistanciaX: 0
MovimientoPorCurva: 0.950151782573888
MeteorXSpeed: -0.00334560486821792
Frames: 260
MeteorX final: 568.329278266145
InfluenciaDeRotacion final: 0.934008644681193
La rotación fue poca, y cuando eso sucede no termina tan alejado de x 400, pero hay bastante diferencia entre 400 y 568.
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 24 frames más vaya a cambiar mucho, además cuando llega arriba se está alejando del medio, o sea, la distancia sería aún mayor.
InfluenciaDeRotacion final es lo que medí, con el programa, que la rotación influyó. O sea, hizo que el meteoro se mueva 0.9 algo hacia la derecha. La diferencia con lo que calculé, MovimientoPorCurva, es mínima así que no debería haber problema.
El meteoro debe terminar en x 400 ¿por qué no lo hace?
Les dejo el archivo editable y el ejecutable:
https://drive.google.com/file/d/1vRwS4DG3JhaKutOI1FEW-vjmTfNR0u9Z/view?usp=sharing
Lo que supongo relevante del código, puede que falte algo:
Código
function MeteorMoves () { MeteorXSpeed = MeteorXSpeed+MeteorRotation/1000*MeteorYDirection; if (MeteorYDirection == 1) { InfluenciaDeRotacion = InfluenciaDeRotacion+MeteorRotation/1000; trace("InfluenciaDeRotacion: "+InfluenciaDeRotacion); } MeteorRotation = MeteorRotation/1.01; MeteorX = MeteorX+MeteorXSpeed; Meteor._x = MeteorX; MeteorY = MeteorY+MeteorYSpeed; Meteor._y = MeteorY; if (Meteor.hitTest(Player) && MeteorYSpeed>0) { // Determinar rotación y velocidad Y al azar: MeteorRotation = Math.random()*(180+Dificultad)*(2*random(2)-1); MeteorYSpeed = -Math.random()*(2+Dificultad)-1; // Distancia Y desde el meteoro hasta el punto hacia donde se lo apuntó: DistanciaY = MeteorY-ApuntandoY; // Cuánto tardará el meteoro en recorrerla: TardanzaY = Math.ceil(DistanciaY/-MeteorYSpeed); // Distancia X desde el meteoro hasta el punto hacia donde se lo apuntó: DistanciaX = ApuntandoX+400-MeteorX; // Determinar cuánto de moverá debido a la curva (falta considerar la reducción): MovimientoPorCurva = MeteorRotation*0.101*(1-Math.pow(1.01, -TardanzaY)); // Determinar la velocidad X para que el meteoro llegue... // al punto X apuntado justo cuando llega al punto Y apuntado: MeteorXSpeed = DistanciaX/TardanzaY-MovimientoPorCurva/TardanzaY;
Si lo testean, tengan en cuenta que InfluenciaDeRotacion no tendrá el valor debido si el meteoro choca con una pared, se resetea cuando toca la nave naranja.
Y no, que eso falle no es la causa de que el programe falle, eso es sólo un contador para ver que MovimientoPorCurva se haya calculado bien.





Autor



En línea
