Adding an Enemy
We’ve got a weapon, we’ve got health, we’ve got treasure to collect. What’s missing?
Something to fight!
We’ll be keeping our enemy fairly simple, it’ll operate off a circular detection range, and walk toward the player if it enters that range, without taking into account walls (Though it will of course still collide with walls)
Enemy Scene
Let’s get to making the scene!
-
It’ll need: a root CharacterBody2D (Called “Enemy”) with three children: a CollisionShape2D, an Area2D (named “range”) and an AnimatedSprite2D
Additionally we’ll want to give the Area2D a CollisionShape2D as a child.
-
First, on the CharacterBody2D under the Collision section, we’ll want Layer 2 and 3 selected. With only 3 selected under Mask
-
Let’s skip down to setting up the AnimatedSprite2D. Create two animations, call the first “idle” and the second “move”. Then, pick something to be your enemy! Selecting both the idle and move animation as we did for the player, using the Add from file button.
You may want to speed the animations up as they’re fairly slow by default, I found 10 fps to be good for both! You’ll also want to make sure you set the idle animation to be autoplay!
-
Set the CollisionShape2D that’s a child of the Root node to have a shape that generally matches the sprite.
-
Set the shape of the CollisionShape2D child of the Area2D to be a circle, making it however large you want the ‘detection’ range of the enemy to be!
-
Finally, let’s create a new Group and call it “enemy”, and assign it to the root node of the scene.
Enemy Scripting
Now let’s get the enemy moving!
-
Let’s create some variables:
- a boolean to keep track of if the player is in range
- a reference to the player
- a variable to control our speed
It should look something like this, again getting the reference to the AnimatedSprite2D the usual way:
-
Then, we’ll want to connect two signals from the “range” Area2D node, we’ll want to connect both the “on_body_entered” and “on_body_exited” signals to the script we created!
Let’s write those functions. When the player enters the range, we’ll want to set our in_range boolean, and play our move animation
-
In the exited function, we’ll want to do the inverse!
-
Now, in the _process() function, we’ll want to check if our player is in range, if they are, move toward them. We’ll also want to flip our sprite based on where the player is in relation to the enemy.
-
For a final script that looks like this:
and that’s it! The last thing we need to do is head over to our Player scene, create a group called “player” and add the root node of the scene to it.
Add an enemy to the scene, and you should notice that if you get close to it, it’ll walk toward you, and take health away whenever it touches you!
Although there’s one problem… We can’t destroy it!
Destroying the enemy!
Head to your Weapon Scene and open the weapon.gd script. We’ll just need to make some slight modifications to check if the sword is colliding with enemies when we attack.
-
First, let’s get a reference to the Area2D node.
-
Then, in our _process() function, if we’re attacking, we’ll want to get all the bodies we’re colliding with and check if they’re enemies.
-
Leaving the _process(): function looking like this:
Test it out, and hopefully you’ll find you can now destroy the enemies!
Checklist
- I’ve created the enemy scene
- I’ve created the enemy script
- The enemy damages me
- The enemy moves toward me
- I’m able to destroy the enemy