Octubre 20, 2012, 07:53:44 PM Ultima modificación: Octubre 20, 2012, 07:58:38 PM por Mgbu
Es difícil, lo que necesito es que el enemigo sepa apuntar bien para que al lanzar un objeto (que va cayendo) pase por un punto especificado, o sea las coordenadas del jugador, acá hay una imagen para que se entienda:


Intenté hacerlo pero no pude, intente buscando la forma de hacerlo usando las ecuaciones de fisica de caida libre y tiro vertical. Las cosas importantes son que los disparos salen siempre con la misma velocidad, si se les hace mas facil regulando la velocidad del objeto no hay problema. Y la gravedad es siempre la misma (0,2) y va hacia abajo

¿Se les ocurre alguna forma? No tengo problema en hacerlo yo, me gustaria para prender, a lo mejor qon una pista me sale
Si prefieren hacerlo ustedes ¿Necesitan el editable o saber los tamaños de los objetos, la gravedad y eso? No tengo problema en darle algo
Si no se puede hacer exacto no hay problema, buscaría la forma de adaptar el arma (hacer como un cluster no estaria mal) mientras que no erre demasiado jaja
El Manual

- Ley de la gravitación selectiva: toda herramienta se caerá donde produzca el mayor daño.
- Si todo parece estar bien, es obvio que uno no encontró el problema
- Todo aquello que se corte a medida resultara ser demasiado corto.
- Todo archivo borrado era necesario, todo archivo conservado es inutil
- Cuando a usted se le ocurra la solución ideal, alguien habrá resuelto ya el problema.

                                                               Murphy


#1 Octubre 20, 2012, 09:38:07 PM Ultima modificación: Octubre 20, 2012, 10:13:43 PM por penumbra
Qué fórmulas exactamente estás usando. Las fórmulas de caída libre y tiro vertical no te van a funcionar (si es que buscas realismo), porque este no es un tiro vertical ni hay caída libre, lo que tienes es un tiro parabólico, por lo que deberías usar la fórmula:

R(t) = (V0x*t + x0)i + (-0.5gt^2 +V0y*t + y0)j

Que es la fórmula para conocer la posición del proyectil, en un instant (t)

V0x = Es tu velocidad inicial en x. Tienes que especificar un valor de velocidad con la que sale disparado el proyectil del cañón

t = Es el instante de tiempo, para el cual quieres saber la posición del proyectil. Va a ser necesario que hagas un script que cuente el tiempo (en este caso, el número de pasos entre la velocidad de fps que manejas en tu juego). En el momento que la bala sale disparada, iniciar en el paso = cero, y a partir de ahí contar los pasos. Puedes manejar directamente el número de pasos, pero tienes que tener en cuenta que hay mucha diferencia entre t = 5 (pasos) o t = 5 (segundos)

x0 = Es la posición en x del cañón, con respecto al origen de la pantalla.

g = tu gravedad

V0y = Velocdad inicial en y

Y0 = Es la posición en y del cañón, con respecto al origen de la pantalla.

Recuerda que para conocer V0x o V0y tienes que usar algo similar a

Vx0 =lengthdir_x(v, angulo)     v = velocidad inicial a tu gusto   angulo = el ángulo de disparo del cañón

o en lugar del método anterior, usar las funciones seno y coseno según corresponda.
Vx0 = cos(angulo*pi/180)*v

No sé si los cañones pueden variar su ángulo o van a estar fijos. El objetivo final es calcular en qué momento disparar la bala para que le de al blanco (o se aproxime a la zona donde está localizado). Esto quiere decir que además de calcular distancias, tambien tendrías que calcular tiempos en base a la velocidad de tu personaje. Esto fue la primer idea que me vino a la cabeza, igual y hay un método más sencillo, pero no se me ocurre  ;D

Por último, puedes olvidarte de toda la teoría y probar hasta dar con alguna velocidad y ángulo de los cañones para que el jugador tenga que ser hábil y esquive los proyectiles, aunque así el juego sería menos dinámico sin duda.

Suerte.

#2 Octubre 21, 2012, 02:36:06 AM Ultima modificación: Octubre 21, 2012, 04:44:26 AM por Mgbu
Ahh, perfecto, esa formula esta muy buena, no la aprendi todavia en la escuela XD
Me expliqué un poco mal, la torreta apunta para disparar hacia donde se encuentra el personaje, y como la bala sale siempre a la misma velocidad V0x y V0y puedo relacionarlas dejando una sola como incognita, el problema es el tiempo, por lo que me parece mejor poner un tiempo mas o menos elacionado con la distancia y listo.
Ahora me voy a poner a ver como va, si encuentro un problema aviso

EDIT: Encontré justo lo que necesitaba, es esto:
Eso me da el ángulo para la velocidad de salida que quiero, gracias por guiarme porque no sabia nada de esto ;D
El Manual

- Ley de la gravitación selectiva: toda herramienta se caerá donde produzca el mayor daño.
- Si todo parece estar bien, es obvio que uno no encontró el problema
- Todo aquello que se corte a medida resultara ser demasiado corto.
- Todo archivo borrado era necesario, todo archivo conservado es inutil
- Cuando a usted se le ocurra la solución ideal, alguien habrá resuelto ya el problema.

                                                               Murphy


De nada. Suerte con el sistema de disparo

#4 Octubre 21, 2012, 05:52:59 PM Ultima modificación: Octubre 21, 2012, 09:50:42 PM por Mgbu
Atención base Houston, tenemos un problema! XD

Transcribí esa ecuación a código, parece que no tengo problemas con las unidades (por ejemplo px/step > m/s) porque funciona perfectamente si el jugador está en la misma Y que el enemigo, el problema viene cuando el jugador sube o baja. Cuando el jugador está arriba los tiros no llegan, y cuando está abajo se pasan de largo, como si tirara depreciando la Y del jugador.

Te adjunto el jueguito, pasé lo que importaba a un nuevo editable para que no influya nada externo, acá también te muestro la ecuación real, y mi adaptación. Puse paréntesis por todos lados XD


v=10
g=0.2
xj=obj_jugador.x-x
yj=obj_jugador.y-y

direccion=arctan(   ((power(v,2))/(g*xj))*(1+sqrt(1-((2*g*yj)/(power(v,2)))-((power(g,2)*power(xj,2))/(power(v,4)))))  )



No te preocupes si l ecuación no sirve al irse del lado izquierdo del enemigo, eso lo arreglo con unos if


EDIT: Ya esta, necesito ayuda para arreglar el dibujado y termino, pero lo de trayectorias lo arreglé, dentro de poco publico un ejemplo por si alguien necesita
El Manual

- Ley de la gravitación selectiva: toda herramienta se caerá donde produzca el mayor daño.
- Si todo parece estar bien, es obvio que uno no encontró el problema
- Todo aquello que se corte a medida resultara ser demasiado corto.
- Todo archivo borrado era necesario, todo archivo conservado es inutil
- Cuando a usted se le ocurra la solución ideal, alguien habrá resuelto ya el problema.

                                                               Murphy


Voy de salida, y no tuve mucho tiempo para trabajar en el código. Hice unas pequeñas modificaciones, aun falla, pero mejoró un poquito el comportamiento. No adjunto archivo porque sólo puedo guardar como gm81

xj = abs(obj_jugador.x - x)

yj = abs(obj_jugador.y-y)


validar = 1-( (2*g*yj) / (power(v,2)) ) - ( (power(g,2)*power(xj,2)) / (power(v,4)) )
if validar > 0
    direccion=arctan(   ((power(v,2))/(g*xj))*(1+sqrt(1-((2*g*yj)/(power(v,2)))-((power(g,2)*power(xj,2))/(power(v,4)))))  )


Con las pequeñas modificaciones, si el jugador no estáa muy alejado del cañón y tiene una "y" menor que la torreta (es decir que está algo más arriba) la bala si le alcanza a dar

Tambien se solucionó el error de raíz negativa si el jugador avanzaba más allá de x = 500 en la pantalla.

Como te dije, no tuve mucho tiempo de meterle mano, pero lo que te recomiendo es que apliques la ecuación tal cual, es decir, hay dos soluciones, una con + antes de la raíz y una con - antes de la raíz. En el código sólo tienes la solución con "+", pero puede que en ocasiones funcione con "-". Ese tipo de ecuación indica que matemáticamente hay dos soluciones, pero en el mundo real, solamente una es válida, a veces funciona una, y a veces otra. Prueba implementando "direccion2" =

Se me ocurre que para la fórmula con signo negativo, crees un segundo objeto tipo bala, y que dispares las dos balas siempre, cada una va a usar una fórmula, la primera bala, usa la fórmula que ya hiciste, la segunda usa la solución con signo "-". Esto para que veas la diferencia en las trayectorias

Espero haberme explicado. Nos vemos. Suerte

Ahora lo dejo ordenado por si a alguien le sirve, el problema que tenía era que en matemática el eje Y va hacia arriba, pero en las computadoras va hacia abajo XD, luego necesitaba adaptar un poco para que funcione también si el objetivo está a la izquierda.
Así quedó:

[gml]

//DATOS/////////////////////////////////////////////////
v=10 //Velocidad de disparo                           //
g=0.2 //Gravedad                                      //
xj=abs(obj_jugador.x-x) //Posición X del jugador      //
if xj=0 exit //Para prevenir una división por 0       //
yj=obj_jugador.y-y //Posición Y del jugador           //
////////////////////////////////////////////////////////
/*
Tener en cuenta que la ecuación tiene 2 soluciones, una para un disparo más directo y otra para un disparo más alto,
este ejemplo está listo para el disparo directo que es más efectivo, para obtener el otro disparo se debe cambiar el
signo - que está entre el 1 y la raíz, justo como se ve en la ecuación comentada
También si el resultado de lo que va destro de la raíz cuadrada da negativo significa que el objetivo está fuera de
alcance, por eso el exit
*/
//ECUACIÓN//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
raiz=1-((2*g*-yj)/(power(v,2)))-((power(g,2)*power(xj,2))/(power(v,4))) //Contenido de la raíz cuadrada                       //
if raiz<0 exit //Si devuelve un numero menor que 0 significa que el objetivo está fuera de rango                              //
                                                                                                                              //
direccion=arctan(((power(v,2))/(g*xj))*(1-sqrt(raiz))) //Terminamos de calcular la ecuación para disparo directo              //
//direccion=arctan(((power(v,2))/(g*xj))*(1+sqrt(raiz))) //Terminamos de calcular la ecuación para disparo indirecto          //
                                                                                                                              //
direccion=radtodeg(direccion) //Pasamos el resultado a grados                                                                 //
if obj_jugador.x<x direccion=-direccion+180 //Si el objetivo está a la izquierda espejamos el ángulo (Gracias Jairo Honorio)  //                                                                                                                         
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


if reload=0 { //Si el arma esta recargada
    bala=instance_create(x,y,obj_bala) //Crear la bala
    bala.speed=v //Poner su velocidad...
    bala.gravity=g // ...su gravedad...
    bala.direction=direccion // ...y su dirección
    reload=50 //Descargar el arma
}

reload-=1 //Recargar el arma lentamente
image_angle=direccion //Dibujar la torreta con el angulo de disparo
[/gml]
Eso obviamente va en step

Listo, dejo un ejemplo adjunto y algunas tags para el buscador XD

CitarProyectil, Disparo, Gravedad, Calculo, Parabola, Calcular, Lanzar, Lanzado, Lance, Objetos
El Manual

- Ley de la gravitación selectiva: toda herramienta se caerá donde produzca el mayor daño.
- Si todo parece estar bien, es obvio que uno no encontró el problema
- Todo aquello que se corte a medida resultara ser demasiado corto.
- Todo archivo borrado era necesario, todo archivo conservado es inutil
- Cuando a usted se le ocurra la solución ideal, alguien habrá resuelto ya el problema.

                                                               Murphy