Hola soy nuevo en GML y he estudiado algunas cosas pero mi proyecto de juego requiere más ayuda de todo lo que he aprendido. Mientras sigo haciéndolo, quiero pedir la ayuda de alguien.

Estoy haciendo un Tower Defence. Tengo 2 torres diferentes (torre flecha y torre mago) y 2 enemigos diferentes (EnemigoEsqueleto y Enemigo Zombie)

MI PROBLEMA ES: No puedo lograr que el ENEMIGO tome el DAÑO que la FLECHA hace (el daño lo determina la Torre de la cual sale)

Para que las torres me reconozcan como objetivos a los dos enemigos los asocié e un EnemyParent.

Por lo tanto, la torre tiene este código:
/CREATE/
Alcance=200;
Dano=2;
Vel=8;
Nivel=1;
Toptime=45;
tim=Toptime;
AspectoBala=spr_Flecha;
Objetivo=obj_EnemyParent;
Bala=obj_flecha;

La flecha sale de la torre. Hay un evento de colisión con la torre en la que la flecha absorbe los valores de la torre.
CREATE DE LA FLECHA ES ESTE:
origen=0;
objetivo=0;
Alcance=0;
Dano=0;
Vel=0;

FLECHA: COLISION CON TORRE
if origen=0
{
origen=other.id;
Alcance=other.id;
Dano=other.id;
Vel=other.id;
}


En el obj_EnemigoEsqueleto le puse el evento colisión con la FLECHA
Hp-=Dano;


PERO ME LANZA ERROR! Es como si no reconociera de dónde sacar el valor de Dano. Solamente me acepta cuando le pongo un numero determinado. Pero quiero lograr que el daño no sea siempre el mismo sino que varíe entre 1 y 4. Pero primero necesito que me reconozca el valor.

Lo más cercano que logré fue que en el obj_EnemigoEsqueleto agregué un evento de colisión con la FLECHA y agregué el siguiente SCRIPT:

if place_meeting(x,y,obj_EnemyParent)
{
obj_EnemyParent.Hp-=Dano;
}

pero el resultado fue que al eliminar a 1 enemigo, eliminó a todos los que estaban en la pantalla. No sé por qué será.

Procura poner siempre el mensaje de error. Así es más fácil para lo demás entender la falla.

Lo que pasa es que  esto no es correcto:
if origen=0
{
origen=other.id;
Alcance=other.id;
Dano=other.id;
Vel=other.id;
}

a 4 variables (muy distintas entre sí) les estás dando el mismo valor, esto no tiene sentido. Y aun más, ese valor es el identificador de instancia de la otra instancia implicada en la colisión. En este código, no hay nada que reste o quite vida. para quitar vida, sería.
[gml]if origen=0
{
     vida -=other.Dano      //Restar el valor de Dano a la variable vida (la variable vida debe estar inicializada en CREATE)
}[/gml]

Cita de: bcortesl@gmail.com en Febrero 25, 2015, 12:23:43 AM
Lo más cercano que logré fue que en el obj_EnemigoEsqueleto agregué un evento de colisión con la FLECHA y agregué el siguiente SCRIPT:

if place_meeting(x,y,obj_EnemyParent)
{
obj_EnemyParent.Hp-=Dano;
}

pero el resultado fue que al eliminar a 1 enemigo, eliminó a todos los que estaban en la pantalla. No sé por qué será.

Eliminó a todos porque te estás refiriéndote a TODAS las instancias. En GM, si tú le quitas vida a UN OBJETO, entonces, todas las instancias de ese objeto que existan en la habitación van a recibir el daño, ya sea que haya una instancia, diez instancias o cien instancias.
Solución: No quitarle vida a un objeto, sino sólo a UNA de las instancias de ese objeto.

Bien, he modificado lo de "other.id"

Tengo entendido que lo que estoy haciendo es lo siguiente.

La flecha se crea con 'origen=0'. Al colisionar con la torre (que lo hace al momento de ser creada) le digo que si el origen=0, que tome el origen de la torre (other.id).

Es correcta esta interpretación?


Pensé que debía especificarle a la flecha que también debe tomar los valores de dano, alcance y Vel de la torre. 

Bien, lo que puse en la colisión de la flecha con el enemigo fue

Hp-=Dano;

Pero no se hacerle saber al programa que lo que me refiero a Dano es a los valores de la torre flecha.

Copio mensaje de error
___________________________________________
############################################################################################
FATAL ERROR in
action number 1
of  Step Eventobj_flecha
for object obj_EnemigoEsqueleto:

Push :: Execution Error - Variable Get -1.Hp(100009, -2147483648)
at gml_Object_obj_EnemigoEsqueleto_CollisionEvent_1 (line 3) - Hp-=Dano;
############################################################################################

#3 Febrero 25, 2015, 02:45:01 AM Ultima modificación: Febrero 25, 2015, 03:12:41 AM por penumbra
Comprendo lo que quieres hacer, pero la explicación me resulta confusa.

Cita de: bcortesl@gmail.com en Febrero 25, 2015, 12:57:55 AM
Tengo entendido que lo que estoy haciendo es lo siguiente.
La flecha se crea con 'origen=0'. Al colisionar con la torre (que lo hace al momento de ser creada) le digo que si el origen=0, que tome el origen de la torre (other.id).
Es correcta esta interpretación?
A lo que tú le llamas origen, se le conoce como identificador de instancia. origen es otra cosa: es el punto que indica la posición de un objeto, definido en las propiedades del sprite de ese objeto. Y sí es posible: el identificador de instancia "A" se puede guardar en una variable de otra instancia "B" al momento que se crea esta segunda instancia.

Cita de: bcortesl@gmail.com en Febrero 25, 2015, 12:57:55 AM
Pensé que debía especificarle a la flecha que también debe tomar los valores de dano, alcance y Vel de la torre. 

Bien, lo que puse en la colisión de la flecha con el enemigo fue

Hp-=Dano;

Pero no se hacerle saber al programa que lo que me refiero a Dano es a los valores de la torre flecha.
Disculpa, lo que pasa es que ahora me doy cuenta que usas el evento colisión para darle valores a las flechas cuando se crean. Es una manera algo inusual, porque la mayoría de las veces el evento colisión se usa para restar vida, pero tú lo usas justo cuando se crea la flecha para asignar variables, eso me confundió. La asignación sería (si se usa el evento de colisión)
[gml]if origen=0
{
   origen=other.origen
   Alcance=other.Alcance
   Dano=other.Dano
   Vel=other.Vel
}[/gml]
Suponiendo que las variables de la torre tienen el mismo nombre que las de la flecha

El error es porque al momento de querer restarle el Dano, la variable "Hp" no está inicializada, La debes definir en el evento CREATE (Hp = 100, por decir algo).







#4 Febrero 25, 2015, 03:21:26 AM Ultima modificación: Febrero 25, 2015, 03:29:16 AM por ChinglesVara
Para que te funcione bien las variables debei ir así


if origen=0{
origen=other.id
Alcanse=origen.Alcanse
Vel=origen.Vel
Dano=origen.Dano
}

Traduccion: Si el valor de origen de la flecha es = a 0, a este se le asigna la id de la torre que lo creo,
ahora a la flecha le traspasamos el valor de las demas variables,
esto se hiso así para que cuando aumente de nivel la torre,
se modifiquen las variables de dano vel alcanse a la torre,
asi evitar de crear un proyectil diferente para cada nivel.
por eso se usa tambien la variable de la imagen Aspecto_Bala,
así t podemos cambiar el aspecto de la bala al salir de la torre,
tambien nos ahorramos de crear una bala para cada torre,
ya que con este sistema solo con un objeto bala es suficiente


Como a origen ya le dimos el id del objeto creador, basta con usar origen.El valor de las variables de daño velocidad y alcance.
Se ve que no miraste bien el video

Lo que pasa es que si se usa el evento de colisión (como especificó en el comentario original), no es necesario usar una variable "origen", porque la palabra especial other ya se refiere a la instancia de la cual quiere leer las variables.

Si en lugar del evento de colisión se quiere usar otro lugar, entonces sí habría que utilizar una variable para guardar el id de instancia.

Cita de: penumbra en Febrero 25, 2015, 03:35:25 AM
Lo que pasa es que si se usa el evento de colisión (como especificó en el comentario original), no es necesario usar una variable "origen", porque la palabra especial other ya se refiere a la instancia de la cual quiere leer las variables.

Si en lugar del evento de colisión se quiere usar otro lugar, entonces sí habría que utilizar una variable para guardar el id de instancia.

Si eso es cierto disculpa, no habia leeido el comentario antes de responder.

tambien otra solucion o cambio seria crearla desde step y darle los valores desde la torre misma


en step:
objetivo=instance_nearest(x,y,obj_Enemy_Parent)

if distance_to_object(objetivo)<=Alcanse{
   Bala=instance_create(x,y,obj_Bala)
   Bala.sprite_index=Aspecto_Bala
   Bala.Dano=Dano
   Bala.Vel=Vel
   Bala.Alcanse=Alcanse
}

Otra manera, sin depender del evento de colisión, sería que al crear una flecha/bala (por ejemplo, un evento keypress de una tecla)

with (instance_create(x,y, obj_flecha) )
{
     Alcance = other.alcance
     Dano=other.Dano
     speed = other.Vel      //Esto haría que la flecha de inmediato tuviera velocidad y se moviera
     origen = other.id       //Por si se quiere "marcar" la flecha para saber qué torre la creó.
}

Aunque todos los métodos son más o menos lo mismo  XD


Muchísimas gracias!!!
Al final era todo más simple y resolví con lo más simple.

A cada obj_enemigo le di un evento de colisión con cada obj_bala y obj_flecha, etc, etc. y le escribí lo siguiente:

Hp-=other.Dano;

Les agradezco, pero sigo aprendiendo, aunque en un nivel bajo bajo como el que me encuentro.

Saludos  ;)