Bienevnidos sean a este post, en el post de hoy agregaremos la capacidad de disparo para nuestros enemigos.
Para esto debemos crear un nuevo objeto que sera el laser del enemigo pero antes crearemos un sprite, para ello usaremos el editor interno y crearemos uno de 8 x 4, y la llamaremos spr_laser_enemigo, les dejo un ejemplo de lo creado por mi

Este es un ejemplo simple y sirve como idea para crearlo, luego debemos centrar el origen como hicimos en los sprites anteriores, recuerden pasar el origen de Top Left a Middle Centre, y por ultimo debemos establecer el Collision Mask de Automatic a Manual, y si lo creen necesario modificar la mascara de colision que genera con esta modificacion, con esto nos resta crear un nuevo objeto que llamaremos obj_laser_enemigo, le asignamos el nuevo sprite y lo hacemos heredera o hijo del objeto Padre (clase_enemigo) tal como vimos anteriormente en este post, con todo esto realizado vamos a agregar un nuevo evento Create donde agregaremos la siguiente linea:
ps = 5;
En este caso le establecemos un nivel de salud al laser para que pueda ser destruido por nuestro jugador pero de eso hablaremos mas adelante por ahora lo dejaremos de esa forma, nuestro siguiente paso sera modificar el evento Step heredado, para ello debemos hacer click con el boton derecho y seleccionamos Inherit event, tal como vimos en este post, este nos reemplazara el codigo y nos dejara la funcion event_inherited al cual le agregaremos el siguiente codigo:
event_inherited();
if (collision_rectangle(x - 3, y -3,
x + 2, y, obj_Nave, false,
false) != noone)
instance_destroy();
La primera linea es para seguir teniendo las instrucciones del evento heredado, luego usamos un condicional con un viejo conocido como es collision_rectangle al cual le pasaremos los valores de left, top, right y bottom, como objeto a verificar usaremos a obj_Nave, los dos siguientes como siempre seran false, y este condicional funciona tal como lo usamos anteriormente donde si el valor de la funcion es distinta de noone procede a ejecutar la funcion instance_destroy para destruir esta instancia, con esto terminamos el objeto para el laser enemigo, pasemos al objeto del enemigo.
En nuestro objeto del enemigo agregaremos la habilidad de perseguir a nuestra nave y una vez dentro del rango dispararnos y para ello deberemos ir al evento Step y despues del condicional donde hacemos girar a nuestro enemigo agregaremos el siguiente bloque:
if (instance_exists(obj_Nave))
{
if (distance_to_object(obj_Nave) <= 200)
{
speed = 0;
if (puede_disparar)
{
bala_uno = instance_create_depth(x,
y, 0, obj_laser_enemigo);
bala_dos = instance_create_depth(x,
y, 0, obj_laser_enemigo);
with(bala_uno)
{
motion_set(other.image_angle,10);
image_angle = other.image_angle;
}
with(bala_dos)
{
motion_set(other.image_angle + 180, 10);
image_angle = other.image_angle;
image_xscale = -1 * other.bala_uno.image_xscale;
}
alarm[0] = 30;
puede_disparar = false;
}
}
}
En este condicional primero verificamos si existe el objeto de la nave del jugador, en caso de ser verdadero procede a ejecutar su bloque, dentro de este tenemos otro condicional que utiliza a la funcion distance_to_object para verificar cual es la distancia con respecto a otro objeto, en este caso pasamos el objeto de la nave y le decimos si es menor o igual a 200, en caso de ser verdadero procedemos a detenernos estableciendo la velocidad (speed) en 0 para despues verificar si puede_disparar tiene valor true, en caso de ser asi vamos a tener la secuencia para disparar, observen como vamos a generar dos instancias que almacenaremos en bala_uno y bala_dos, veamos la primera instancia:
bala_uno = instance_create_depth(x,
y, 0, obj_laser_enemigo);
No lo creamos de forma anonima porque necesitaremos referenciarlo luego, en este caso volvemos a utilizar instance_create_depth para generar la instancia del laser enemigo, luego tenemos otra referencia similar a esta pero la unica diferencia sera el nombre para diferenciarla con lo que sigue a continuacion.
Lo siguiente sera utilizar dos veces a with para cada una de las referencias que creamos antes, analicemos la primera:
with(bala_uno)
{
motion_set(other.image_angle,10);
image_angle = other.image_angle;
}
Lo que hacemos en este bloque es setear primero la direccion de la instancia que almacenamos en bala_uno, primero pasaremos el angulo de la imagen y luego la velocidad, y por ultimo estableceremos el angulo de esta instancia, pasemos a ver el siguiente bloque:
with(bala_dos)
{
motion_set(other.image_angle + 180, 10);
image_angle = other.image_angle;
image_xscale = -1 * other.bala_uno.image_xscale;
}
En este caso trabajaremos con la instancia almacencada en bala_dos, las dos primeras lineas del bloque son igual al caso anterior pero en este caso agregaremos 180° al angulo de la imagen para ponerlo del otro lado, y utilizaremos el image_xscale para hacer el efecto espejo de la imagen con respecto a bala_uno, despues de estos establecemos el valor para la alarma 0 para finalmente establecer a puede_disparar como false durante un tiempo para que no este constantemente disparando, con esto ya tenemos una parte culminada para nuestra siguiente modificacion trabajaremos con el condicional que verifica la distancia del objeto y le agregaremos el siguiente bloque else:
else
{
dir = point_direction(x, y, obj_Nave.x, obj_Nave.y);
if ((dir >= 315 || dir <= 45) &&
!collision_rectangle(x+16,y-16,x+26,y+16,
clase_enemigo, false, true)) ||
(dir > 45 && dir <= 135 &&
!collision_rectangle(x-16,y-26,x+16,y-16,
clase_enemigo, false, true)) ||
(dir > 135 && dir <= 225 &&
!collision_rectangle(x-26,y-16,x-16,y+16,
clase_enemigo, false, true)) ||
(dir > 225 && dir <= 315 &&
!collision_rectangle(x-16,y+16,x+16,y+26,
clase_enemigo, false, true))
{
motion_set(dir, 3);
}
else
{
speed = 0;
}
}
Primero vamos a crear una variable que almacenara la ubicacion de la nave del jugador con respecto a la nave enemiga, despues tendremos un condicional donde haremos varias verificaciones, la primera chequea si la variable dir es mayor o igual a 315 o menor o igual a 45, esto si lo llevamos al cuadrante donde nos movilizamos estarian ubicados a la derecha un cuarto por arriba y un cuarto por debajo del eje, y a su vez chequeamos que no haya colisionado con nadie de la clase enemiga, usamos a este para que se pueda vincular a todos los posibles hijos que seran parte de este objeto padre, si recuerdan despues de pasar el objeto informamos si debe usar precision o no y si somos nosotros o no, en este caso seguiremos a false para no usar la precision pero en el notme usaremos el true para informarle que no somos nosotros y evitar conductas extrañas, obviamente este es la primera condicion, luego tenemos otras similares.
La siguiente condicion verifica la seccion superior de una forma similar al anterior, tambien con la funcion para verificar que no existen ningun aliado o enemigo en ese cuadrante, la siguiente condicion verifica el de la izquierda y la ultima condicion la parte inferior, en todos los casos con las condiciones usamos a la funcion collision_rectangle anteriormente citada, con esto cubrimos todo el «circulo» donde podemos desplazarnos y para cada una de estas condiciones las compararemos por medio de un OR (||) para en caso de que se cumpla alguna de ellas procede a ejecutar la funcion del bloque, en este caso usamos a motion_set y le pasamos el valor almacenado en dir para que se dirija en esa direccion y una velocidad de 3, de lo contrario establecemos la velocidad en 0 para que no se desplace, nuestro condicional quedara de la siguiente manera:
if (instance_exists(obj_Nave))
{
if (distance_to_object(obj_Nave) <= 200)
{
speed = 0;
if (puede_disparar)
{
bala_uno = instance_create_depth(x,
y, 0, obj_laser_enemigo);
bala_dos = instance_create_depth(x,
y, 0, obj_laser_enemigo);
with(bala_uno)
{
motion_set(other.image_angle,10);
image_angle = other.image_angle;
}
with(bala_dos)
{
motion_set(other.image_angle + 180, 10);
image_angle = other.image_angle;
image_xscale = -1 * other.bala_uno.image_xscale;
}
alarm[0] = 30;
puede_disparar = false;
}
}
else
{
dir = point_direction(x, y, obj_Nave.x, obj_Nave.y);
if ((dir >= 315 || dir <= 45) &&
!collision_rectangle(x+16,y-16,x+26,y+16,
clase_enemigo, false, true)) ||
(dir > 45 && dir <= 135 &&
!collision_rectangle(x-16,y-26,x+16,y-16,
clase_enemigo, false, true)) ||
(dir > 135 && dir <= 225 &&
!collision_rectangle(x-26,y-16,x-16,y+16,
clase_enemigo, false, true)) ||
(dir > 225 && dir <= 315 &&
!collision_rectangle(x-16,y+16,x+16,y+26,
clase_enemigo, false, true))
{
motion_set(dir, 3);
}
else
{
speed = 0;
}
}
}
Nota: Si agregaron el incremento del eje Y del post anterior eliminen o comenten esa linea para que no afecte el movimiento de los enemigos.
Con todo esto realizado podemos probar nuestro juego para ver como funciona hasta el momento, compilemos y veamos que sucede mediante el siguiente video
Como podemos ver en el video ahora nuestros enemigos no solamente descienden hacia nosotros sino que ademas comenzaran a moverse hacia nosotros pero cuando llegan a una distancia se detienen y nos comienzan a disparar, por ahora un simple caos en nuestra contra.
En resumen, hoy hemos creados los laser de nuestros enemigos, hemos agregado la capacidad de poder desplazarse en la direccion que estemos, tambien le agregamos una «inteligencia» para no solamente perserguirnos sino tambien detenerse y comenzar a dispararnos, tambien hemos hecho que los lasers desaparezcan ante el contacto, espero les haya gustado sigueme en tumblr, Twitter o Facebook para recibir una notificacion cada vez que subo un nuevo post en este blog, nos vemos en el proximo post.


Donación
Es para mantenimento del sitio, gracias!
$1.00
