Comunidad Game Maker

Ayuda => Preguntas y respuestas => Mensaje iniciado por: luceratto en Septiembre 23, 2015, 06:32:19 PM

Título: (ayuda) Torreta que apunta y dispara a diversos enemigos.
Publicado por: luceratto en Septiembre 23, 2015, 06:32:19 PM
hola, soy nuevo en la comunidad, o la primera vez que pido ayuda xD.

Estoy tratando de hacer un tower defence, y tengo problemas con las torretas.

La idea es que cuando un enemigo entra en el radio de alcance, la torreta le apunta y le dispara, el problema es que la torreta sigue apuntando y disparando al primer enemigo, por que detecta a otro igual cerca.

Lo que pense es tomar la id del objeto enemigo, y que la torreta apunte y dispare hacia esa id.

Otro problema que tengo es que al programar mas de 1 enemigo diferente, el programa le da prioridad al enemigo 1, luego al 2, luego al tres, es decir que, si la oleada es así:

X O X O X O

Siendo O el enemigo 1 y X el enemigo 2, la torreta apunta y elimina primero a todos los enemigos 1, cuando ya no hay enemigos 1, ahi comienza a eliminar al enemigo 2. Lo que yo pensaba era que apunte al enemigo mas cercano y lo deje en paz cuando este salga del radio de alcance.

----------------------

Mas aya de todo eso, me las estoy arreglando para ver como hago, leyendo el manual de gms y viendo ejemplos, y por ahora quiero que la torreta apunte al enemigo 1, desarrolle este código pero me da error:

Evento Create.
{
    EnemigoFijado = 0;      //esta variable me da error
    instance_create(x,y,obj_torreta_base1);
    image_angle = 90;
}


Evento Step.
{
    if EnemigoFijado = 0   //y se supone que el error esta aqui.
    {
        if distance_to_object(obj_enemigo_terrestre1) < 112
        {
            var EnemigoID = obj_enemigo_terrestre1.id
            EnemigoFijado = 1
            exit;
        }
    }
    if EnemigoFijado = 1
    {
        image_angle = point_direction(x,y,EnemigoID.x,EnemigoID.y);
        if distance_to_object(EnemigoID) > 112
        {
            EnemigoID = 0
            EnemigoFijado = 0
        }
    }
}


Y el error que me da es el siguiente  >:( :

###################################################
FATAL ERROR in
action number 1
of  Step Event0
for object obj_torreta_canon1:

Push :: Execution Error - Variable Get -7.EnemigoFijado(100006, 0)
at gml_Object_obj_torreta_canon1_Step_0 (line 2) -     if EnemigoFijado = 0
###################################################

El error se produce en el momento que coloco la torreta en el mapa.
Título: Re:(ayuda) Torreta que apunta y dispara a diversos enemigos.
Publicado por: Clamud en Septiembre 23, 2015, 09:02:07 PM
En el primer bloque de código se ve que la torreta es creada por otro objeto y se asignan dos variables, el problema es que esas variables no se asignan a la torreta, sino al objeto que la crea, por eso aparece el error. El código debería ser así:
[gml]
with instance_create( x,y, obj_torreta_base1 )
{
    EnemigoFijado = 0;
    image_angle = 90;
}
[/gml]
En el segundo bloque sería más fácil usar la función instance_nearest, ejemplo:
[gml]
Enemigo = instance_nearest( x,y, obj_enemigo_terrestre1 );
if( Enemigo <> noone )
if( point_distance(x,y,Enemigo.x,Enemigo.y) < 100 )
image_angle = point_direction( x,y, Enemigo.x,Enemigo.y );
[/gml]
Título: Re:(ayuda) Torreta que apunta y dispara a diversos enemigos.
Publicado por: luceratto en Septiembre 23, 2015, 10:01:04 PM

{
    instance_create(x,y,obj_torreta_base1);  //esto es otra cosa xD
    image_angle = 90;
}


el codigo me funciono genial, pero como lo implemento para mas de 1 obj_enemigo?

ejemplo:

Enemigo = instance_nearest( x,y, obj_enemigo_terrestre1 );
if( Enemigo <> noone )
if( point_distance(x,y,Enemigo.x,Enemigo.y) < 100 )
image_angle = point_direction( x,y, Enemigo.x,Enemigo.y );

Enemigo = instance_nearest( x,y, obj_enemigo_terrestre2 );
if( Enemigo <> noone )
if( point_distance(x,y,Enemigo.x,Enemigo.y) < 100 )
image_angle = point_direction( x,y, Enemigo.x,Enemigo.y );

Enemigo = instance_nearest( x,y, obj_enemigo_terrestre3 );
if( Enemigo <> noone )
if( point_distance(x,y,Enemigo.x,Enemigo.y) < 100 )
image_angle = point_direction( x,y, Enemigo.x,Enemigo.y );
Título: Re:(ayuda) Torreta que apunta y dispara a diversos enemigos.
Publicado por: penumbra en Septiembre 23, 2015, 10:11:01 PM
No es necesario escribir tres veces el bloque de código. Lo más práctico es agrupar todos esos objetos bajo un objeto Parent, y usar el nombre del objeto padre en la función instance_nearest
[gml]Enemigo = instance_nearest( x,y, obj_ParentEnemy)[/gml]
Título: Re:(ayuda) Torreta que apunta y dispara a diversos enemigos.
Publicado por: luceratto en Septiembre 24, 2015, 04:18:45 AM
hola, ya solucione el problema xD!! muchas gracias me ayudaron demaciado.

ahora tengo un nuevo problema, el comportamiento de las torretas es feo, me gustaria que una vez que se detecto al enemigo mas cercano, no se cambie el objetivo hasta que este este fuera de rango. o mejor aun, que apunte al enemigo con menos salud, pero buscare en el foro a ver que encuentro xD.
Título: Re:(ayuda) Torreta que apunta y dispara a diversos enemigos.
Publicado por: Clamud en Septiembre 24, 2015, 07:55:55 PM
Puedes usar este código para rotar suavemente
[gml]
///Rotar
d = point_direction( x,y, EnemigoFijado.x,EnemigoFijado.y ); //calcular dirección
d = angle_difference( image_angle, d ); //diferencia de ángulos
image_angle += min(abs(d), VelocidadDeRotacion )*sign(d); //rotar
[/gml]
está basado en el ejemplo que aparece en la ayuda de la función angle_difference, debes cambiar VelocidadDeRotacion por el que valor que quieras. Sería conveniente escribir el código anterior en un script para usarlo como se muestra a continuación.

Para fijar un sólo enemigo mientras esté en el rango de alcance se me ocurre esto. Primero creamos la variable EnemigoFijado en el evento Create
[gml]
EnemigoFijado = noone;
[/gml]
Después, en el evento Step, se hace lo siguiente
[gml]
if instance_exists(EnemigoFijado) //si hay objetivo y no se ha destruido
{
    d = point_distance( x,y, EnemigoFijado.x,EnemigoFijado.y ); //calcular distancia
    if( d <= RangoDeDeteccion ) Rotar(); //si está en el rango de detección, rotar
    else //si el enemigo ha salido del rango de detección
    EnemigoFijado = noone; //fijar nada
}
else //si no hay enemigo fijado o se ha destuido
{
    EnemigoCercano = instance_nearest(x,y,obj_enemigo); //buscar el más cercano
    if instance_exists(EnemigoCercano) //si existe
    {
        d = point_distance( x,y, EnemigoCercano.x,EnemigoCercano.y ); //calcular distancia
        if( d <= RangoDeDeteccion ) //si está en el rango de detección
        {
            EnemigoFijado = EnemigoCercano; //fijar objetivo
            Rotar();
        }
    }
}
[/gml]
es necesario cambiar RangoDeDeteccion por un valor adecuado.
Título: Re:(ayuda) Torreta que apunta y dispara a diversos enemigos.
Publicado por: luceratto en Septiembre 24, 2015, 11:25:52 PM
Clamud, eso sirve para que al cambiar de objetivo la torreta, en lugar de apuntar rapido, valla lento hasta que lo fije?
Título: Re:(ayuda) Torreta que apunta y dispara a diversos enemigos.
Publicado por: Clamud en Septiembre 25, 2015, 04:26:42 AM
Si, eso hace.