We’d love to hear from you. Whether you have a question that you’d like us to answer as part of our FAQ,  you’ve identified something that just doesn’t quite look right in one of our tutorials, you have a business opportunity or for any other reason, please use this simple form to contact us.

We’ll do our best to provide a prompt response.

Like what you see?...pass it on!

Making things Explode

Now we want for enemies to explode when they are hit. Time to create an Explosion class. Create a new Scene, save it as Explosion.tscn, then create the following node hierarchy.

Explosion-Nodes

Select the Sprite and drag the file /assets/graphics/explosion/explosion.png over to the Texture field of the sprite. You will notice that this is actually a sprite sheet, containing multiple frames of animation in a single file. Set Vframes and Hframes to 3 each, giving us 9 frames of animation to work with.

Explosion-frames

Next select the AnimationPlayer node, then create a new animation just like we did back when we created a bullet. We create an animation named Explode with the following keys and tracks configured:

Explosion-key-frames-and-tracks

Here we created 3 tracks, a Property track that changes the frame property of Sprite over time, advancing through our animation. We also created a Method call track that calls queue_free() at the end of the animation. Finally, we added an Audio Playback Track that plays the file Explosion.wav available in /assets/audio/explode/explode.wav.

When creating the Audio Playback Track, select the AudioStreamPlayer when prompted. Then create a new key, and set Explode.wav as the Stream, like so:

Set-audio-key

Now open up Enemy.gd and add the following code:

onready var explode = preload("res://Explosion.tscn").instance()

func _on_Area2D_area_entered(area):
  #Hit by bullet
  if(area.get_collision_layer_bit(3)):
  
    explode.set_position(self.get_position())
    get_parent().add_child(explode)
    globals.kills = globals.kills + 1
    queue_free()

This invokes our newly created Explosion object. Basically, when the Enemy is hit, we check to see if the thing that hit us was on the Bullet layer, if it was, we create an explosion, set it to our current position, increment the global kills count and then remove us from the scene.

And finally, we need to make the Player explode if they collide with an enemy. Our Player.gd script now consists of:

extends Node2D


var speed = 150
var verticalMovement = 0
const MAX_VERTICAL_MOVEMENT = 200
var bulletObj = null
const RATE_OF_FIRE = 3.0
var dying = false


onready var shotCooldown = $Timer
onready var explode = preload("res://Explosion.tscn").instance()


func _ready():
  bulletObj = load("res://Bullet.tscn")
  shotCooldown.wait_time = 1.0/RATE_OF_FIRE
  shotCooldown.one_shot = true
  

func _process(delta):
  move_local_x(speed*delta)
  if(self.position.y > 1  && self.position.y <= get_viewport_rect().size.y):
    move_local_y(verticalMovement*delta)
  else:
    if(self.position.y < 1): 
      move_local_y(10) #Bounce off top
      verticalMovement = 0
    if(self.position.y > get_viewport_rect().size.y): 
      move_local_y(-10) #Bounce off bottom
      verticalMovement = 0
  if(dying == true):
    if(shotCooldown.time_left == 0):
      get_node("/root/GameSceneRoot").PlayerDied()
      queue_free()
      print("Dead")
  
func stop():
  speed = 0

func explode():
  explode.set_position(self.get_position())
  get_parent().add_child(explode)
  globals.kills = globals.kills + 1
  shotCooldown.wait_time = 2.5
  shotCooldown.start()
  $PlayerSprite.visible = false
  dying = true


func _input(event):
  if(event.is_action("PLAYER_UP")):
    if(verticalMovement >= -MAX_VERTICAL_MOVEMENT):
      verticalMovement-=10
  if(event.is_action("PLAYER_DOWN")):
    if(verticalMovement <= MAX_VERTICAL_MOVEMENT):
      verticalMovement+=10
  if(event.is_action("PLAYER_SHOOT")):
    if(shotCooldown.time_left == 0):
      var bullet = bulletObj.instance()
      bullet.position = self.get_position()
      bullet.position.y = bullet.position.y + 20
      get_node("/root/GameSceneRoot").add_child(bullet)
      shotCooldown.start()



func _on_Area2D_area_entered(area):
  #Layer 2 is another enemy
  if(area.get_collision_layer_bit(2)):
    explode()

Again be sure that the area_entered() signal has been connected. In this code, we reuse the shot timer (this has the advantage of preventing shots while dying) to delay removing the object from the scene until after the explosion animation is done. In the meanwhile, while waiting to be destroyed, we set our sprite to be invisible.

Adding Shooting to Game<<PreviousTable of ContentsNext>>The Final Code

Like what you see?...pass it on!

script ends --->