Phew - we’ve done a lot so far, but let’s add some sound effects to our game to make it a bit more fun. Sound effects are crucial for adding feedback and immersion to your game. When bullets strike an asteroid or make it explode, playing the right sound effect can let the user know what’s happened even if they’re not looking at the correct part of the screen.

Task Definition

This task uses techniques that you learned when adding music to the game earlier in the project. You will use similar audio objects that you used then.

Basic Solution: A basic solution to this task will see your game playing the following sound effects when certain events occur;

  • player_fire_01.mp3: Whenever the player fires a bullet.
  • asteroid_hit_01.mp3: Whenever one of the player’s bullets hits an asteroid.
  • asteroid_death_01.mp3: Played whenever you do enough hits to an asteroid to destroy it.

Advanced Solution: A more advanced solution to this task will build upon the basic solution by loading multiple sound effects for a given event and picking one at random. It can get boring and repetetive if you play the same sound effect over and over for events that occur regularly, which is why we have provided multiple sounds for some events.

In the template project you will notice that there are 6 different sound files which you can pick from whenever the player shoots a bullet (player_fire_01.mp3, player_fire_02.mp3, …, player_fire_06.mp3).

Hints

Some of the functions you will need to make use of to preload and play audio effects are listed below;

this.load.audio([name], [path]): This preloads an audio file into your game in the same way that you preload images in earlier steps.

let sfx = this.add.audio([name]): This will add an audio object to your game. An audio object is a sound effect that you can re-use over and over again. Initially, the audio object will not do anything (it won’t play the sound), but you can use the next method to make the sound effect play.

sfx.play(): Once you have created a sound effect object, you can call ‘play()’ on it to cause the sound effect to start playing.

Walkthrough - Simple Solution

First, let’s go through the simple solution where we simply add one audio effect for whenever a player fires a bullet, and another effect when an asteroid is hit.

1. Preload the audio file

Just like with images and musuc, you must preload the audio files you wish to play in your preload() function using the method this.load.audio. This is just like what we did with the music earlier in the course.

2. Create an audio object

For each sound file we are going to add a single audio object to our scene. You can think of an audio object like a electronic speaker that exists on the stage / in the scene which can only play one file. You can use the same audio object over and over to play that one sound file repeatedly in the game.

To create a single audio object, you should use this.soundX = this.sound.add(name) function which will add an audio object to your scene named ‘soundX’. Then you can later use this object to play your sound effect with this.soundX.play();.

If you refer back to the lesson on adding Background Music to our game - playing a sound effect is exactly the same.

### 3. Play the effects

You already have functions which are called when a player fires a bullet and when a bullet hits an asteroid, so it’s simply a case of hooking in our sound effects when those things happen. In your fireBullet() function you can now add a call to play your sound effect.

Walkthrough - Advanced Solution

1. Preload all of the audio files

You should be familiar with preloading assets now and this will require adding a bunch more lines to your preload method. Load the audio files that you intend to use in your solution using game.load.audio([name], [path]).

preload() {
    // Add this code to your game's preload function to load the sound effects
    this.load.audio('player_fire_01', 'assets/audio/player_fire_01.mp3');
    this.load.audio('player_fire_02', 'assets/audio/player_fire_02.mp3');
    this.load.audio('player_fire_03', 'assets/audio/player_fire_03.mp3');
    this.load.audio('player_fire_04', 'assets/audio/player_fire_04.mp3');
    this.load.audio('player_fire_05', 'assets/audio/player_fire_05.mp3');
    this.load.audio('player_fire_06', 'assets/audio/player_fire_06.mp3');
},

2. Create all of the audio objects

In your create method you should create one different audio object for each possible sound effect. Creating the audio object will not cause it to play immediately, but will give you the option of playing it later on.

As you create these audio objects, you should add them to an array, such as this.playerFireSfx that you can use later to pick one at random.

create() {
    ...
    
    // Add this to your create function to add the sound effect to your world
    // Note that it will not play until you tell it to play later
    this.playerFireSfx = [];
    this.playerFireSfx.push(this.sound.add("player_fire_01"));
    this.playerFireSfx.push(this.sound.add("player_fire_02"));
    this.playerFireSfx.push(this.sound.add("player_fire_03"));
    this.playerFireSfx.push(this.sound.add("player_fire_04"));
    this.playerFireSfx.push(this.sound.add("player_fire_05"));
    this.playerFireSfx.push(this.sound.add("player_fire_06"));
}

3. Play a random SFX

Now, when you come to play a sound effect after the player has fired a bullet, you should pick one of the sound effects at random from the array. For this, you can use Phaser.Math.RND.between(min, max);. Note that ‘max’ should not be bigger than the last index in the array (ie. if the array has length of 5 then the last index is 4)!

fireBullet() {
    ...
    var index = game.rnd.integerInRange(0, this.playerFireSfx.length - 1);
    this.playerFireSfx[index].play();
}

Extensions

Some ideas for how you might extend this feature are as follows;

  • Try to make a ‘playRandomSfxFromArray’ that you can use again and again to do this if you need too.
  • Given you know there are 6 audio files with the same name, you could load them using a for loop and string concatenation. That makes it much nicer if you one day have 20 sound effects!
  • Prevent the same sound effect from playing twice in a row.

Finished Solutions

Basic Solution

A simple version of the basic solution will load one of each possible sound effect during the ‘preload’ stage of your game and then play them whenever you fire a bullet or trigger another action.

preload() {
    // Existing Code...
    this.load.audio('fire-bullet', 'assets/audio/player_fire_01.mp3');
}

create() {
    // Existing Code...
    this.fireSound = this.sound.add('fire-bullet');
}

fireBullet() {
    // Existing Code...
    this.fireSound.play();
}

Advanced Solution

For a more advanced solution we will create an array of sound effects and pick one at random to play whenever the player fires a bullet.

preload() {
    // Existing Code...
    this.load.audio('fire-bullet-01', 'assets/audio/player_fire_01.mp3');
    this.load.audio('fire-bullet-02', 'assets/audio/player_fire_02.mp3');
    this.load.audio('fire-bullet-03', 'assets/audio/player_fire_03.mp3');
    ...
}

create() {
    this.fireSfx = [];
    this.fireSfx.push(this.sound.add('fire-bullet-01'));
    this.fireSfx.push(this.sound.add('fire-bullet-02'));
    this.fireSfx.push(this.sound.add('fire-bullet-03'));
}

fireBullet() {
    var index = Phaser.Math.RND.between(0, this.fireSfx.length - 1);
    this.fireSfx[index].play();
}