Buenas, tengo un grupo de enemigos llamados obj_enemigo1, esos mismos enemigos tienen un parent llamado obj_parent_enemigos (ya que en un futuro añadiré mas enemigos, de momento solo tengo 1 tipo, el nombrado anteriormente), quisiera saber como puedo hacer para que el enemigo mas cercano del parent me detecte para que haga el código que yo quiero.
De momento lo único que tengo es esto (y no funciona):
if instance_exists(obj_parent_enemigos)
{
id_objetivo = instance_nearest(x, y, obj_parent_enemigos);
//Aquí iría el código que haría con el enemigo mas cercano no??
}
Gracias de antemano!
Es muy facil:
[gml]
if instance_exists(obj_parent_enemigos) {
with (instance_nearest(x, y, obj_parent_enemigos)) {
//Aquí iría el código que haría con el enemigo mas cercano. :)
}
}
[/gml]
El codigo se ejecuta desde el objeto encontrado como el mas cercano.
Revisa la documentación de la palabra with paramas detalles.
Cita de: Johann en Octubre 25, 2018, 06:10:27 PM
Es muy facil:
[gml]
if instance_exists(obj_parent_enemigos) {
with (instance_nearest(x, y, obj_parent_enemigos)) {
//Aquí iría el código que haría con el enemigo mas cercano. :)
}
}
[/gml]
El codigo se ejecuta desde el objeto encontrado como el mas cercano.
Revisa la documentación de la palabra with paramas detalles.
No me funciona..
He probado tu código y no lo consigo, he probado cambiando algunas cosas y tampoco.
Te dejo mi código a ver si hay algún error:
if instance_exists(obj_parent_enemigos)
{
with (instance_nearest(x, y, obj_parent_enemigos))
{
dir = point_direction(x,y,obj_parent_enemigos.x,obj_parent_enemigos.y);
if ( dir < 90 || dir > 270 ) {sprite_index = spr_jugador_parado; image_xscale = 1;} else
if ( dir < 270 && dir > 90 ) {sprite_index = spr_jugador_parado; image_xscale = -1;}
}
}
Este código funciona perfectamente si en la room solo coloco 1 enemigo, a la que hay 2 enemigos (con el mismo nombre obj_enemigo1) solo hace caso al primer enemigo que coloque en la room, no se si es casualidad o no, es decir.. mi código hace que el jugador SIEMPRE mire al enemigo, y lo dicho si solo hay 1 enemigo funciona perfecto, pero a la que hay 2 o mas deja de funcionar, como ves ya he implemente el código que tu me diste pero sigue igual..
Gracias de antemano!!
Hola, saludos cordiales.
Él código de Johann es correcto pues le está diciendo al enemigo más cercano que tome acciones. Pero luego agregas una nueva dificultad que es mirar al enemigo más cercano. Entonces son dos acciones distintas.
Para el objeto player
[evento step]
if instance_exists(obj_parent_enemigos) {
with (instance_nearest(x, y, obj_parent_enemigos)) {
//Aquí iría el código que haría con el enemigo mas cercano. :)
}
//Esto es para mirar al enemigo más cercano
objetivo=instance_nearest(x, y, obj_parent_enemigos);
dir = point_direction(x,y,objetivo.x,objetivo.y);
if ( dir < 90 || dir > 270 ) {sprite_index = spr_jugador_parado; image_xscale = 1;} else
if ( dir < 270 && dir > 90 ) {sprite_index = spr_jugador_parado; image_xscale = -1;}
}
(https://image.ibb.co/nJQcBV/solucion.png) (https://imgbb.com/)
Si es el jugador el que mira al enemigo no necesitas que sea el enemigo en que ejecute el codigo sino el mismo jugador conociendo la instancia mas cercana.
Haz como puso dixon al final de su codigo, olvida la palabra "with"
El código funciona perfectamente!!
El causante del error era este código:
(point_distance(x,y,obj_parent_enemigos.x,obj_parent_enemigos.y) < 150)
Este hace que cuando mi personaje (obj_jugador) entre en un rango de 150 o menos "entre en combate con el enemigo" y por eso quería hacer que el jugador mirase al enemigo, si esta este código mi personaje no busca al enemigo mas cercano, peeero, si elimino este código SÍ funciona el código que me habéis dado.
Voy a seguir probando mas y mas hasta ver como consigo hacer funcionar las 2 cosas y cerrar este tema ya porque me esta dando mas problemas.. jajajajaja
Actualmente mi código es este:
ASÍ NO FUNCIONA:
if instance_exists(obj_parent_enemigos) and (point_distance(x,y,obj_parent_enemigos.x,obj_parent_enemigos.y) < 150)
{
objetivo = instance_nearest(x, y, obj_parent_enemigos);
dir = point_direction(x,y,objetivo.x,objetivo.y);
if ( dir < 90 || dir > 270 ) {sprite_index = spr_jugador_movimiento; image_xscale = 1;} else
if ( dir < 270 && dir > 90 ) {sprite_index = spr_jugador_movimiento; image_xscale = -1;}
}
ASÍ SÍ:
if instance_exists(obj_parent_enemigos)// and (point_distance(x,y,obj_parent_enemigos.x,obj_parent_enemigos.y) < 150)
{
objetivo = instance_nearest(x, y, obj_parent_enemigos);
dir = point_direction(x,y,objetivo.x,objetivo.y);
if ( dir < 90 || dir > 270 ) {sprite_index = spr_jugador_movimiento; image_xscale = 1;} else
if ( dir < 270 && dir > 90 ) {sprite_index = spr_jugador_movimiento; image_xscale = -1;}
}
La única diferencia es que estoy comentando el código de "point_distance", pero bueno, tendré que buscar una opción para que funcionen los dos códigos a la vez!
Gracias, dejo el tema abierto por si no encuentro solución.. si la encuentro la diré (por si alguien mas lo necesita) y pondré mi Solucionado en el titulo, gracias!
EDITO:
He conseguido hacer CASI que funcione!
He conseguido que ahora el jugador mire a un enemigo (dentro del obj_parent_enemigos) justo cuando entra dentro de su distancia con point_distance, así que eso es lo que yo quería en un principio y por fin lo he logrado, pero ahora se me vuelve a complicar otra vez cuando he decidido agregar una caja (como ejemplo) dentro del obj_parent_enemigos pero esta caja con una distancia_jugador = 25, cuando el obj_enemigo1 tiene una distancia_jugador = 150. Es decir.. mi personaje entra en "modo combate" por decirlo de alguna manera con el jugador en 150 y la caja en 25, ya que la caja no se mueve y la he echo solo de prueba. ¿Donde esta el problema? que mi código no detecte la distancia_jugador del enemigo mas cercano si no la del enemigo que antes he puesto en la room. Llevo varias horas probando a conseguir esto pero no hay manera, me gustaría que si mi personaje tiene mas cerca suyo la caja que el enemigo (ambos metidos en obj_parent_enemigos) mire a la caja en el rango 25 y no que la mire a 150.
Mi actual código es este:
[gml]
var ex, ey;
ex = instance_nearest(x, y, obj_parent_enemigos).x;
ey = instance_nearest(x, y, obj_parent_enemigos).y;
if instance_exists(obj_parent_enemigos) and point_distance(x,y,ex,ey) < obj_parent_enemigos.distancia_jugador
{
objetivo = instance_nearest(x, y, obj_parent_enemigos);
dir = point_direction(x,y,objetivo.x,objetivo.y);
if ( dir < 90 || dir > 270 ) {sprite_index = spr_jugador_movimiento; image_xscale = 1;} else
if ( dir < 270 && dir > 90 ) {sprite_index = spr_jugador_movimiento; image_xscale = -1;}
}
[/gml]
Lo dicho, funciona CASI TODO, mi personaje ahora puede caminar por la room libremente, mirando para donde me dirijo.. y a la hora de "luchar" (entrar en rango de distancia_jugador) mira con una distancia de 150 ya sea una caja (que debería ser 25) o el enemigo 1 (que este si es 150), no distingue que distancia tiene cada objeto.
Muchas gracias por todo.. y a ver si me quito este dolor de cabeza ya! jajajaja
Hola gusto en saludarles en esta mañana de este bello lunes 29 de octubre. Se le saluda de Maracay Estado Aragua en Venezuela.
Vuelves a agregar complejidad al código, pero no te preocupes.
Para solucionar tenemos que tomar en cuenta lo siguiente: Supongamos que un tal Axel de streets of rage 2 se siente un poco preocupado porque al parecer en la Game Off 2018 no ofrecen ningún premio solo un reconocimiento, entonces al ver que hay mucha crisis decide donar unos pocos dolares que le queda a la caja de la comunidadgm. Entonces obtendriamos esto
(https://image.ibb.co/jG8bfq/axel-2.png) (https://imgbb.com/)
El código que se está manejando presenta las siguientes caracteristicas.
1. El enemigo actua cuando es el más cercano al player.
2. El player detecta solo al enemigo mas cercano.
3. Cada enemigo tiene una distancia de deteccion distinta.
El código es el siguiente:
PARA EL OBJETO player
[CREATE EVENT]
global.distancia=150
[STEP EVENT]
//detectar enemigos
if instance_exists(obj_parent_enemigos)
{
global.objetivo = instance_nearest(x, y, obj_parent_enemigos);
dir = point_direction(x,y,global.objetivo.x,global.objetivo.y);
if(point_distance(x,y,global.objetivo.x,global.objetivo.y) < global.distancia)
{
if ( dir < 90 || dir > 270 ) {sprite_index = spr_jugador_movimiento; image_xscale = 1;} else
if ( dir < 270 && dir > 90 ) {sprite_index = spr_jugador_movimiento; image_xscale = -1;}
}
}
PARA EL OBJETO obj_parent_enemigos
[CREATE EVENT]
distancia=150
[STEP EVENT]
if(global.objetivo=id)
{
global.distancia=distancia
}
PARA EL OBJETO obj_enemigo1
[CREATE EVENT]
distancia=150
[END STEP]
if(global.distancia=distancia && point_distance(x,y,player.x,player.y) < global.distancia)
{
//aqui colocas lo que va ha hacer el enemigo
}
PARA EL OBJETO caja
[CREATE EVENT]
distancia=25
[END STEP]
if(global.distancia=distancia && point_distance(x,y,player.x,player.y) < global.distancia)
{
//aqui colocas lo que va ha hacer LA CAJA
}
Para modificar las distintas distancias de los objetos del parent, se modifica la variable distancia de cada objeto en el evento create.
Al final hay un ejemplo para descargar
Cita de: dixon2010 en Octubre 29, 2018, 12:55:08 PM
Hola gusto en saludarles en esta mañana de este bello lunes 29 de octubre. Se le saluda de Maracay Estado Aragua en Venezuela.
Vuelves a agregar complejidad al código, pero no te preocupes.
Para solucionar tenemos que tomar en cuenta lo siguiente: Supongamos que un tal Axel de streets of rage 2 se siente un poco preocupado porque al parecer en la Game Off 2018 no ofrecen ningún premio solo un reconocimiento, entonces al ver que hay mucha crisis decide donar unos pocos dolares que le queda a la caja de la comunidadgm. Entonces obtendriamos esto
(https://image.ibb.co/jG8bfq/axel-2.png) (https://imgbb.com/)
El código que se está manejando presenta las siguientes caracteristicas.
1. El enemigo actua cuando es el más cercano al player.
2. El player detecta solo al enemigo mas cercano.
3. Cada enemigo tiene una distancia de deteccion distinta.
El código es el siguiente:
PARA EL OBJETO player
[CREATE EVENT]
global.distancia=150
[STEP EVENT]
//detectar enemigos
if instance_exists(obj_parent_enemigos)
{
global.objetivo = instance_nearest(x, y, obj_parent_enemigos);
dir = point_direction(x,y,global.objetivo.x,global.objetivo.y);
if(point_distance(x,y,global.objetivo.x,global.objetivo.y) < global.distancia)
{
if ( dir < 90 || dir > 270 ) {sprite_index = spr_jugador_movimiento; image_xscale = 1;} else
if ( dir < 270 && dir > 90 ) {sprite_index = spr_jugador_movimiento; image_xscale = -1;}
}
}
PARA EL OBJETO obj_parent_enemigos
[CREATE EVENT]
distancia=150
[STEP EVENT]
if(global.objetivo=id)
{
global.distancia=distancia
}
PARA EL OBJETO obj_enemigo1
[CREATE EVENT]
distancia=150
[END STEP]
if(global.distancia=distancia && point_distance(x,y,player.x,player.y) < global.distancia)
{
//aqui colocas lo que va ha hacer el enemigo
}
PARA EL OBJETO caja
[CREATE EVENT]
distancia=25
[END STEP]
if(global.distancia=distancia && point_distance(x,y,player.x,player.y) < global.distancia)
{
//aqui colocas lo que va ha hacer LA CAJA
}
Para modificar las distintas distancias de los objetos del parent, se modifica la variable distancia de cada objeto en el evento create.
Al final hay un ejemplo para descargar
Muchísimas gracias por tu atención!
Al final lo solucione ya que pensaba que no tuve respuesta en este tema, ya que normalmente gamemaker me notifica por correo electrónico cuando me responden un tema y esta vez o no lo hizo o no me di cuenta (mas bien la 2..).
Al final después de muchísimas horas cambiando y probando varias cosas lo conseguí, me quedo así:
[gml]
var ex, ey;
ex = instance_nearest(x, y, obj_parent_enemigos).x;
ey = instance_nearest(x, y, obj_parent_enemigos).y;
objetivo = instance_nearest(x, y, obj_parent_enemigos);
if instance_exists(obj_parent_enemigos) and point_distance(x,y,ex,ey) < objetivo.distancia_jugador
{
dir = point_direction(x,y,objetivo.x,objetivo.y);
if ( dir < 90 || dir > 270 )
{sprite_index = spr_jugador_movimiento; image_xscale = 1;} else
if ( dir < 270 && dir > 90 )
{sprite_index = spr_jugador_movimiento; image_xscale = -1;}
}
[/gml]
Casi igual que como estaba, lo único que cambian un par de cosas, las justas.. para que funcione, mi juego es 2D top down y ahora si que si detecta cual es el jugador mas cercano y que "distancia_jugador" tiene. Te dejo una captura de pantalla para que veas el resultado final.
(https://image.ibb.co/n0bYf0/prueba1.png) (https://imgbb.com/)
Y por cierto me hizo mucha gracia que pusieras en tu ejemplo mi foto de perfil jajajajaja!
La redonda roja es la "distancia_jugador", el enemigo tiene 150 y la caja 35 por eso tiene esa diferencia de tamaño y la linea roja que sale del player marca el objetivo mas cercano, en este caso era la caja, con id = 1 (lo puse para cuando habían muchos enemigos iguales..) y me dice que su radio es de 35 (la redonda roja dicha anteriormente).
Ahora si mi pj se mete dentro de la redonda roja ("distancia_jugador") se activa el if y mi personaje mira cara al enemigo mas cercano.
Bueno, muchísimas gracias por todo, toca dar por solucionado el tema, un saludo!!!!