Creating the enemy
Now it’s time to make the enemies our player will have to dodge. Their behavior will not be very complex: mobs will spawn randomly at the edges of the screen, choose a random direction, and move in a straight line.
Mob scene, which we can then instance to create any number of independent mobs in the game.
Node setup
Click Scene -> New Scene and add the following nodes:
- RigidBody2D (named
Mob)- AnimatedSprite
- CollisionShape2D
- VisibilityNotifier2D
Don’t forget to set the children so they can’t be selected, like you did with the Player scene.
RigidBody2D properties, set
Gravity Scaleto0, so the mob will not fall downward. In addition, under the CollisionObject2D section, click theMaskproperty and uncheck the first box. This will ensure the mobs do not collide with each other. AnimatedSprite like you did for the player. This time, we have 3 animations:fly,swim, andwalk. There are two images for each animation in the art folder.3for all animations.Playingproperty in the Inspector to “On”. We’ll select one of these animations randomly so that the mobs will have some variety.AnimatedSprite‘sScaleproperty to(0.75, 0.75).Playerscene, add aCapsuleShape2Dfor the collision. To align the shape with the image, you’ll need to set theRotation Degreesproperty to90(under “Transform” in the Inspector). Save the scene.Enemy script
Moblike this: GDScript C#C++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
_ready()we play the animation and randomly choose one of the three animation types: GDScript C#C++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()]);}
framesproperty. This returns an Array containing all three animation names:["walk", "swim", "fly"].0and2to select one of these names from the list (array indices start at0).randi() % nselects a random integer between0andn-1. Noterandomize()if you want your sequence of “random” numbers to be different every time you run the scene. We’re going to userandomize()in ourMainscene, so we won’t need it here.screen_exited()signal of theVisibilityNotifier2Dnode and add this code: GDScript C#C++func _on_VisibilityNotifier2D_screen_exited(): queue_free()
public void OnVisibilityNotifier2DScreenExited(){ QueueFree();}
This completes the Mob scene. With the player and enemies ready, in the next part, we’ll bring them together in a new scene. We’ll make enemies spawn randomly around the game board and move forward, turning our project into a playable game.// This code goes in `mob.cpp`.void Mob::_on_VisibilityNotifier2D_screen_exited() { queue_free();}
