hola! eh estado practicando un poco peor no eh podido encontrar solución a este problema espero puedan ayudarme.

tengo un enemigo que es como un tanque que se queda quieto o aveces se mueve pero siempre frena en cierto punto para atacar al jugador, en vez de atacarlo directamente, me gustaría que calcule donde esta el jugador en el piso y lance un proyectil en arco (a la metal slug) y que este tenga cierto rango para poder dispararle al jugador.

si alguien tiene una idea o algun codigo que pueda ayudarme seria genial <3  de ante mano muchas gracias  :)
Programame! como a una de tus árcades chinas

GET BEHIND ME DOCTOR!

Hummm si yo quisiera saber donde esta el jugador debería saberlo con esto.
ubicacionx=obj_jugador.x
ubicaciony=obj_jugador.y
Ya tendría las coordenadas de donde esta mi jugador, prueba con draw gui poniendo esas variables
en la pantalla, ahora mi enemigo ya sabe donde esta mi jugador y esta parte si tendría que investigar
de como crear un disparo ya teniendo el destino, pero intenta con un  MOVE_TOWARDS_POINT ubicacion x, ubicacion y
con eso tu  disparo iria al jugador, pero ese disparo te persigue, no se si hay una funcion en game maker que me permita
poner un destino x y destino y y asi el disparo va a mi direccion pero ya no me perseguira.

Cita de: shadowmanuel en Septiembre 20, 2018, 02:31:30 AM
Hummm si yo quisiera saber donde esta el jugador debería saberlo con esto.
ubicacionx=obj_jugador.x
ubicaciony=obj_jugador.y
Ya tendría las coordenadas de donde esta mi jugador, prueba con draw gui poniendo esas variables
en la pantalla, ahora mi enemigo ya sabe donde esta mi jugador y esta parte si tendría que investigar
de como crear un disparo ya teniendo el destino, pero intenta con un  MOVE_TOWARDS_POINT ubicacion x, ubicacion y
con eso tu  disparo iria al jugador, pero ese disparo te persigue, no se si hay una funcion en game maker que me permita
poner un destino x y destino y y asi el disparo va a mi direccion pero ya no me perseguira.

esto funcionaria solo que el disparo fuera directo como el caso de una ballesta, si es un arco, se tendria que calcular la parabola que este seguira, para que mientras avance la flecha ,esta sea afectada por la fuerza, gravedad y la rotacion, con fisicas esto deberia ser bastance sencillo, sin embargo, aconsejaria hacerlo sin las fisicas para que no tengas que cambiar todo el diseno de tu juego.
Es Mejor No Saber Porque Funciona, Que Saber El Porque No Funciona...
Tienes alguna duda con "Game Design" o de videojuegos en general, contactamente mas facil en twitter @pavulzavala

#3 Septiembre 20, 2018, 05:59:33 AM Ultima modificación: Septiembre 20, 2018, 06:02:23 AM por BssString
Hola cristopher2545

Podrías intentar usar las ecuaciones físicas de movimiento en dos ejes.
Eje x:
X = X inicial + V inicial * coseno(angulo) * tiempo
Eje y:
Y = Y inicial + V inicial * seno(angulo) * tiempo - (g/2) * (tiempo^2)

"X" e "Y" son las coordenadas del player, "X inicial" e "Y inicial" son las coordenadas del cañón (o de la bala cuando se crea)
"V inicial" es la velocidad con la que sale disparada la bala del cañón.
"angulo" es la inclinación del cañón (que es también la dirección en la que sale disparada la bala)
"tiempo" es el tiempo que tarda la bala en llegar a su objetivo.

1- En esta ecuación, la mayoría de valores son constantes y conocidos, salvo dos variables, que son ángulo del cañon y velocidad de la bala, ambas variables pueden variar de manera infinita entre ellas y en TODOS esos casos pueden generar infinitas combinaciones posible donde alcanzan al player, así que debes hacer una de las dos constantes (ej, el ángulo del cañón) para que la ecuación funcione.

2- Como el tiempo en que la bala alcanza al player en el EJE X es el mismo tiempo que tarda la bala en alcanzar al player en el EJE Y, podemos combinar el tiempo como un tiempo único y olvidarnos de esa variable.

3- Después de mucha matemática, la fórmula se reduce a esto en game maker:

En el Evento Step
var rango_max = 240
var rango_min = 16
if abs(obj_player.x-x) >= rango_min && abs(obj_player.x-x) <= rango_max && alarm[0] = -1 { //Verifica que el player esté en rango para hacer el disparo (entre 16 y 240 pixeles en el eje X)
var shot_angle = 0;
if obj_player.x < x { shot_angle = 135 }
else { shot_angle = 45 }

var bala = instance_create(x,y,obj_bala)
with bala {
gravity = 0.4 //Setea la gravedad de la bala
direction = other.shot_angle //La dirección de la bala es el ángulo del cañón
speed = sqrt((sqr(obj_player.x-x)) / ((2/-gravity)*((y-obj_player.y)-dtan(direction)*(obj_player.x-x))*sqr(dcos(direction)))) //Esta es la ecuación resultante de combinar las dos ecuaciones de arriba
}
alarm[0] = 2*room_speed //Le da un cooldown de 2 segundos para efectuar el siguiente disparo
}


En el Evento ALARM0
//Sólo pon un comentario para que se active el contador y se pueda usar como delay o cooldown entre disparos

Eso calcula la velocidad que debe tomar la bala para que pueda golpear al player. Mi recomendación es que en vez de usar las físicas de la realidad, uses tu propio código de movimiento aunque sea algo irreal, ej: que la bala se deslice de forma horizontal hasta que está cerca del player y recién ahí tome gravedad.
Ese movimiento no está apegado a la realidad, pero dará un mejor efecto in-game.

Algunos juegos utilizan mecánicas falsas que hacen que el juego se sienta mejor a la vista o en jugabilidad. En Fifa por ejemplo, el caminar y disparo al arco de los jugadores es más exagerado que lo que pasa en la vida real para dar una mejor sensación al jugador, así puedes controlar mejor al personaje. En GTA, cuando dos autos colisionan, rebotan con un efecto de partículas que muestra la destrucción. En la vida real en cambio, quedarían prácticamente unidos los autos al chocar rápido, pero si se hiciera así el GTA, no podrías ni manejar.

Saludos

Tal vez esto te ayude, este es un ejemplo de disparar flechas con gravedad y parabola (dependiendo donde fijes el arco)
https://www.escueladevideojuegos.net/ejemplos_edv/Talleres/VT_06_Defender_Base/
Mira que sucede subiendo y bajando el arco, como se mueven las flechas, creo que puedes modificar el codigo a lo que quieres.
Si es lo que deseas y de paso quieres aprender un poco mas de game maker
https://www.escueladevideojuegos.net/academia-gamemaker/
Busca el archivo defender la base.

Hola a todos gracias por sus respuestas se aprecia la atención y apoyo que recibió el tema tan rápido


probé el primer código por BssString y funcionaba muy bien es justo lo que esperaba hasta que empezaron los problemas... primero que nada el codigo funciona muy bien los problemas salen cuando el jugador esta en un punto puerto es decir que se pone enmedio del "tanque" lanza un error me imagino que la ecuacion llega a fallar intentando calcular esa situacion

por otra parte solo dispara de un lado intente hacer que disparara hacia el otro pero me fue totalmente imposible.

en metal slug cuando te pones en medio de un tanque este dispara muy cerca de ti formando una parábola en este codigo cada vez que te hacercas mas el arco empieza a disminuir mas y mas hasta que da error de la raiz cuadrada.

si pudieran ayudarme a desifrarlo seria maravilloso ya que es lo que busco pero siento que le falta un poco y trate de arreglrarlo por mi mismo pero arruine mas el codigo
Programame! como a una de tus árcades chinas

GET BEHIND ME DOCTOR!

#6 Septiembre 27, 2018, 04:12:54 AM Ultima modificación: Septiembre 27, 2018, 04:15:07 AM por BssString
Hola cristopher2545

Efectivamente, la ecuación falla cuando el "X" del player es igual al "X" del cañón, por eso que he utilizado las variables locales "rango_max" y "rango_min", para que esa situación jamás pase.
"rango_max" evita que el cañón dispare con rango infinito
"rango_min" evita que se calcule una raíz negativa o una división por cero, así que debe ser MAYOR a cero siempre.

Las soluciones que te propongo:
1- Para solucionar el problema de la dirección, he notado que he llamado una variable de instancia (usando other.), pero la variable finalmente cree como una variable local (usando el "var" adelante).
Cambia el:
direction = other.shot_angle //La dirección de la bala es el ángulo del cañón
por:
direction = shot_angle //La dirección de la bala es el ángulo del cañón


Eso debería corregir el problema de la dirección.

2- Para solucionar el problema de la Raíz, debes asignarle un valor mayor a cero a la variable local "rango_min".
si quieres que el tanque dispare incluso cuando el player está en la misma coordenada que el tanque, debes hacer fija la velocidad a un valor.
Ej:
if abs(obj_player1.x-x) < rango_min { //Para cuando el player esté más cerca del rango mínimo del tanque
creas la bala con todas las variables necesarias y speed fija a 2.5 o el valor que estimes conveniente, incluso puedes usar la misma fórmula, reemplazando ambos "obj_player1.x-x" por "rango_min*sign(obj_player1.x-x)".
Eso hace que para distancias menores a 16 pixeles (valor de la variable rango_min) la fórmula utilice como distancia los 16 pixeles mínimos en vez de la distancia real que puede ser 10 pixeles, 8 o incluso 0 pixeles (que da el error)
}
else if abs(obj_player1.x-x) <= rango_max {
//Para cuando el player esté pasado el rango mínimo pero antes del rango máximo
ejecutas el código de forma normal para que calcule la parábola
}

EDIT: La raíz también se buggea cuando el cañón está apuntando a la derecha, pero el player está posicionado a la izquierda del cañón, para ese caso no he creado ninguna condición, lo siento... tendrás que hacerlo por ti mismo, si no lo logras hacer, me comentas y vemos como solucionarlo