Creating the Enemies

Now that we have a player and something to shoot, we need to have something to shoot at! So it’s time to create an enemy class. Once again, create a new scene, save it as Enemy.tscn. Start by renaming the root node to EnemyRoot.

Next, we want to add a sprite node temporarily (eventually we will do this in code, so we can have multiple different enemies!). Simply drag an image file from /assets/graphics/enemies, select the file enemy2_blue.png, then drag and drop it onto the scene (this is an alternative way to add a sprite). Select Sprite when prompted for how to treat the file:

Add-Sprite-Dialog in Godot Screenshot

Make sure that the Sprite is positioned at (0,0) before proceeding.

Next, add an Area2D to the EnemyRoot node. Then add a CollisionPolygon child to the Area2D node, this is the exact same process as we did when we created the Player so I won’t cover it again. The end result should look something like:

CollisionPolygon-for-Enemy-Sprite Godot

At this point, select the Sprite node you created earlier and delete it. We only needed it so we could trace the shape of our Collision shape.

While we are here, select the Area2D and set up the following collision settings.

Enemy-Collision-Mask Godot Screenshot

Next up, its time to create a Script and attach it to the root node, calling it Enemy.gd. Next enter the following code:

extends Node2D

var sprite = null;
const sprites = [ "enemy1_blue.png", "enemy1_green.png",
        "enemy1_red.png", "enemy1_yellow.png",
        "enemy2_blue.png", "enemy2_pink.png",
        "enemy2_red.png", "enemy2_yellow.png"]
      
var speed = 100

func _ready():
  speed = speed + (globals.currentStage * 10)

func _enter_tree():
  sprite = Sprite.new()
  sprite.texture = load("res://assets/graphics/enemies/" + sprites[randi()%sprites.size()])
  add_child(sprite)

func _process(delta):
  move_local_x(-delta*speed)

func _on_Area2D_area_entered(area):
  #Hit by bullet
  if(area.get_collision_layer_bit(3)):
    pass #We will do this part later!

This code does a couple of things… First, in _ready() we are setting the speed our enemies move at based on the current stage stored in a global variable. This means each stage we move by +10. In _enter_tree(), which is called as the object is added to the stage we programmatically create our Sprite node, load it at random from the array of filenames we defined earlier, then add the newly created Sprite node to our Enemy object. Each frame we simply move negative x by the current speed normalized based on the framerate.

The _on_Area2D callback will be populated later and is called when a collision occurs. Just like we did when creating the bullet, be sure to set this Signal up to call _on_Area2D_area_entered() in the Node\Signals panel.

 

Scroll to Top