Creando el enemigo¶
Es momento de hacer los enemigos que nuestro jugador tendrá que evitar. Su comportamiento no será muy complejo: los enemigos aparecerán al azar en los bordes de la pantalla y se moverán en una dirección al azar en línea recta.
Crearemos una escena Mob
, la que podremos instanciar para crear cualquier número independiente de enemigos en el juego.
Configuración del Nodo¶
Haz clic en Escena -> Nueva escena y agrega los siguientes nodos:
RigidBody2D (llamado
Mob
)
No olvides marcar los hijos para que no se puedan seleccionar, como hiciste con la escena Player.
En las propiedades RigidBody2D, establece Gravity Scale
a 0
, para que el mob no caiga hacia abajo. Además, en la sección CollisionObject2D, haz clic en la propiedad Mask
y desmarca la primera casilla. Esto asegurará que los mobs no colisionen entre sí.
Configura el AnimatedSprite como hiciste con el jugador. Esta vez, tenemos 3 animaciones: fly
, swim
, y walk
. Hay dos imágenes para cada animación en la carpeta art.
Ajusta la "Speed (FPS)" a 3
para todas las animaciones.
Ajuste la propiedad Playing
en el Inspector a "On".
Nosotros seleccionamos una de estas animaciones al azar así los mobs tendrán algo de variedad.
Al igual que las imágenes de los jugadores, estas imágenes de los enemigos necesitan ser reducidas. Establece la propiedad Scale
de AnimatedSprite
en (0.75, 0.75)
.
Igual que en la escena Player
, añade un CapsuleShape2D
para las colisiones. Para alinear la forma de colisión con la imagen, deberás ajustar la propiedad Rotation Degrees
a 90
(en la sección "Transform" del Inspector).
Guarda la escena.
Script del enemigo¶
Añade un script al Mob
de esta manera:
extends RigidBody2D
public class Mob : RigidBody2D
{
// Don't forget to rebuild the project.
}
// Copy `player.gdns` to `mob.gdns` and replace `Player` with `Mob`.
// Attach the `mob.gdns` file to the Mob node.
// Create two files `mob.cpp` and `mob.hpp` next to `entry.cpp` in `src`.
// This code goes in `mob.hpp`. We also define the methods we'll be using here.
#ifndef MOB_H
#define MOB_H
#include <AnimatedSprite.hpp>
#include <Godot.hpp>
#include <RigidBody2D.hpp>
class Mob : public godot::RigidBody2D {
GODOT_CLASS(Mob, godot::RigidBody2D)
godot::AnimatedSprite *_animated_sprite;
public:
void _init() {}
void _ready();
void _on_VisibilityNotifier2D_screen_exited();
static void _register_methods();
};
#endif // MOB_H
Ahora veamos el resto del script. En _ready()
reproducimos la animación y elegimos aleatoriamente uno de los tres tipos de animación:
func _ready():
$AnimatedSprite.playing = true
var mob_types = $AnimatedSprite.frames.get_animation_names()
$AnimatedSprite.animation = mob_types[randi() % mob_types.size()]
public override void _Ready()
{
var animSprite = GetNode<AnimatedSprite>("AnimatedSprite");
animSprite.Playing = true;
string[] mobTypes = animSprite.Frames.GetAnimationNames();
animSprite.Animation = mobTypes[GD.Randi() % mobTypes.Length];
}
// This code goes in `mob.cpp`.
#include "mob.hpp"
#include <RandomNumberGenerator.hpp>
#include <SpriteFrames.hpp>
void Mob::_ready() {
godot::Ref<godot::RandomNumberGenerator> random = godot::RandomNumberGenerator::_new();
random->randomize();
_animated_sprite = get_node<godot::AnimatedSprite>("AnimatedSprite");
_animated_sprite->_set_playing(true);
godot::PoolStringArray mob_types = _animated_sprite->get_sprite_frames()->get_animation_names();
_animated_sprite->set_animation(mob_types[random->randi() % mob_types.size()]);
}
En primer lugar, obtenemos la lista de nombres de animación de la propiedad frames
de AnimatedSprite. Esto devuelve un array que contiene los tres nombres de animación: ["walk", "swim", "fly"]
.
Luego debemos tomar un número al azar entre 0
y 2
para seleccionar uno de los nombres en la lista (los índices de los array comienzan en 0
). randi() % n
selecciona un entero al azar entre 0
y n-1
.
Nota
Tienes que usar randomize()
si quieres que la secuencia de números al "azar" sea diferente cada vez que se ejecute la escena. Usaremos randomize()
en la escena Main
, así que no lo necesitaremos aquí.
La última parte es hacer que los enemigos se borren a sí mismos cuando abandonan la pantalla. Conecta la señal screen_exited()
del nodo VisibilityNotifier2D
y agrega este código:
func _on_VisibilityNotifier2D_screen_exited():
queue_free()
public void OnVisibilityNotifier2DScreenExited()
{
QueueFree();
}
// This code goes in `mob.cpp`.
void Mob::_on_VisibilityNotifier2D_screen_exited() {
queue_free();
}
Esto completa la escena Mob.
Con el jugador y los enemigos listos, en la siguiente parte los reuniremos en una nueva escena. Haremos que los enemigos aparezcan al azar alrededor del tablero de juego y avanzaremos, convirtiendo nuestro proyecto en un juego jugable.