Primero, esta parte:
obj_bala.step:
[gml]if place_meeting(x,y,obj_enemigo){
instance_destroy()
}
if distance_to_object(obj_enemigo) < obj_torre.rango_vision and object_exists(obj_enemigo){
move_towards_point(obj_enemigo.x,obj_enemigo.y,5)
}[/gml]
object_exists(obj_enemigo) lo usamos para comprobar si existe alguna instancia del objeto obj_enemigo, por lo que es más aconsejable ponerlo antes de intentar hacer nada con obj_enemigo, como chequear la distancia o ver si estamos chocando con una instancia. Además, si chocas con un enemigo destruyes la bala, por lo que no haría falta seguir comprobando la distancia para moverse. Así que el código quedaría así:
[gml]
if instance_exists(obj_enemigo){//Ojo, hay que usar instance_exists, no objec_exists. Mira las diferencias en el manual.
if place_meeting(x,y,obj_enemigo) instance_destroy();
else if distance_to_object(obj_enemigo) < obj_torre.rango_vision move_towards_point(obj_enemigo.x,obj_enemigo.y,5);
}[/gml]
Respecto a que las balas sigan sólo al primer enemigo eso es porque estás usando obj_enemigo, que es el nombre genérico del objeto, en vez de usar el id de la instancia concreta que quieres seguir. Si no tienes clara la diferencia entre un objeto y una instancia te recomiendo que compruebes el manual porque esto es algo básico que te va a hacer falta para muchas cosas.
Volviendo a tu duda, lo que tenemos que hacer es identificar al enemigo concreto que ve la torre y decirle a cada bala que siga a ese enemigo.
obj_torre.step:
[gml]
if enemigo_detectado==noone{//Si NO hemos detectado a ningún enemigo
var vEnemy = instance_nearest(x, y, obj_enemigo);//Me guardo la id del enemigo más cercano en una variable temporal
if point_distance(x, y, vEnemy.x, vEnemy.y) < rango_vision{//Compruebo a ver si hay está dentro del rango
enemigo_detectado = vEnemy;//Me guardo la id en la variable enemigo_detectado.
tiempoDisparo = tiempoDisparoMax;//Y pongo la cuenta atrás para el tiempo de disparo
}
}else{//Ya tenemos un enemigo_detectado
if tiempoDisparo > 0 tiempoDisparo--;//Reduzco la cuenta atrás para disparar
else{//Cuando la cuenta atrás se complete
with (instance_create(x, y, obj_bala)) enemigo = enemigo_detectado;//Creo una bala y le paso la id del enemigo que había detectado
enemigo_detectado = noone;//Marco que ya no tengo enemigo, así puedo volver a intentar detectar a otro enemigo, o al mismo si sigue dentro del rango
}
}
[/gml]
He definido unas cuantas variables nuevas que tendrás que inicializar en el evento create:
[gml]
enemigo_detectado = noone;//id del enemigo detectado o noone si no hemos detectado nada
tiempoDisparo = 0;//Variable para hacer la cuenta atrás del disparo
tiempoDisparoMax = 2;//Valor máximo de la cuenta atrás
[/gml]
Ahora, a obj_bala le tenemos que decir que use la id del enemigo que le hemos pasado. Modificamos el código que teníamos antes y donde usábamos obj_enemigo ponemos enemigo, que es la variable que hemos usado al crear la bala para guardar la id del enemigo más cercano:
obj_bala.step:
[gml]
if instance_exists(enemigo){
if place_meeting(x,y,enemigo) instance_destroy();
else if distance_to_object(enemigo) < obj_torre.rango_vision move_towards_point(enemigo.x,enemigo.y,5);
}[/gml]
En el evento create de obj_bala tienes que inicializar la variable enemigo = noone;
Con esto te debería funcionar, aunque te va a pasar que por ejemplo si el enemigo se aleja mucho de la bala la bala se queda parada. Creo que deberías hacer que en este caso la bala siguiera recta y se destruyera al salir de la pantalla, o algo así.
Bueno de todas formas, creo que es importante que consultes el manual y que entiendas bien la diferencia entre objeto e instancia. Mira también las funciones que tienen versiones de objeto e instancia para entender bien para qué sirve cada una.
Ánimo!
obj_bala.step:
[gml]if place_meeting(x,y,obj_enemigo){
instance_destroy()
}
if distance_to_object(obj_enemigo) < obj_torre.rango_vision and object_exists(obj_enemigo){
move_towards_point(obj_enemigo.x,obj_enemigo.y,5)
}[/gml]
object_exists(obj_enemigo) lo usamos para comprobar si existe alguna instancia del objeto obj_enemigo, por lo que es más aconsejable ponerlo antes de intentar hacer nada con obj_enemigo, como chequear la distancia o ver si estamos chocando con una instancia. Además, si chocas con un enemigo destruyes la bala, por lo que no haría falta seguir comprobando la distancia para moverse. Así que el código quedaría así:
[gml]
if instance_exists(obj_enemigo){//Ojo, hay que usar instance_exists, no objec_exists. Mira las diferencias en el manual.
if place_meeting(x,y,obj_enemigo) instance_destroy();
else if distance_to_object(obj_enemigo) < obj_torre.rango_vision move_towards_point(obj_enemigo.x,obj_enemigo.y,5);
}[/gml]
Respecto a que las balas sigan sólo al primer enemigo eso es porque estás usando obj_enemigo, que es el nombre genérico del objeto, en vez de usar el id de la instancia concreta que quieres seguir. Si no tienes clara la diferencia entre un objeto y una instancia te recomiendo que compruebes el manual porque esto es algo básico que te va a hacer falta para muchas cosas.
Volviendo a tu duda, lo que tenemos que hacer es identificar al enemigo concreto que ve la torre y decirle a cada bala que siga a ese enemigo.
obj_torre.step:
[gml]
if enemigo_detectado==noone{//Si NO hemos detectado a ningún enemigo
var vEnemy = instance_nearest(x, y, obj_enemigo);//Me guardo la id del enemigo más cercano en una variable temporal
if point_distance(x, y, vEnemy.x, vEnemy.y) < rango_vision{//Compruebo a ver si hay está dentro del rango
enemigo_detectado = vEnemy;//Me guardo la id en la variable enemigo_detectado.
tiempoDisparo = tiempoDisparoMax;//Y pongo la cuenta atrás para el tiempo de disparo
}
}else{//Ya tenemos un enemigo_detectado
if tiempoDisparo > 0 tiempoDisparo--;//Reduzco la cuenta atrás para disparar
else{//Cuando la cuenta atrás se complete
with (instance_create(x, y, obj_bala)) enemigo = enemigo_detectado;//Creo una bala y le paso la id del enemigo que había detectado
enemigo_detectado = noone;//Marco que ya no tengo enemigo, así puedo volver a intentar detectar a otro enemigo, o al mismo si sigue dentro del rango
}
}
[/gml]
He definido unas cuantas variables nuevas que tendrás que inicializar en el evento create:
[gml]
enemigo_detectado = noone;//id del enemigo detectado o noone si no hemos detectado nada
tiempoDisparo = 0;//Variable para hacer la cuenta atrás del disparo
tiempoDisparoMax = 2;//Valor máximo de la cuenta atrás
[/gml]
Ahora, a obj_bala le tenemos que decir que use la id del enemigo que le hemos pasado. Modificamos el código que teníamos antes y donde usábamos obj_enemigo ponemos enemigo, que es la variable que hemos usado al crear la bala para guardar la id del enemigo más cercano:
obj_bala.step:
[gml]
if instance_exists(enemigo){
if place_meeting(x,y,enemigo) instance_destroy();
else if distance_to_object(enemigo) < obj_torre.rango_vision move_towards_point(enemigo.x,enemigo.y,5);
}[/gml]
En el evento create de obj_bala tienes que inicializar la variable enemigo = noone;
Con esto te debería funcionar, aunque te va a pasar que por ejemplo si el enemigo se aleja mucho de la bala la bala se queda parada. Creo que deberías hacer que en este caso la bala siguiera recta y se destruyera al salir de la pantalla, o algo así.
Bueno de todas formas, creo que es importante que consultes el manual y que entiendas bien la diferencia entre objeto e instancia. Mira también las funciones que tienen versiones de objeto e instancia para entender bien para qué sirve cada una.
Ánimo!