Thunderjack! HTML5 Game Update: Adding Sound Effects (Yeah!)

Hey there.

Well! At this point, the game play is all done. Woot! 👍🏿

Now, you’ll add sound effects to your game. You should add some sound effects to the game to make it more engaging. In this game, sound effects do not affect the game play itself, which is why we’ve deferred adding them until now. However, this does not mean that the sound effects should be an afterthought. When designing your game, you should have an idea of which events that happen in the game will produce sounds, and what those sounds should be.

That said, we’re going to do a little bit of design work here. First, we want to determine which events will produce sounds. Based on the elements in this game, here are some events that could make sense for adding to this game:

  • Button clicks
  • Player wins (at the end of each round, player won more credits than they spent)
  • Player bust
  • Player gets a Blackjack
  • Player gets a Blitz
  • Player gets a Thunderjack
  • Player doubles down
  • Player splits
  • Player surrenders
  • Dealer busts
  • Player or dealer hits
  • Player or dealer stands
  • Shuffling cards
  • Card is dealt
  • Player adds bet
  • Player clears bet

Note: You can use any sound effects you like for these events. You can also come up with your own events to add sound effects for. This article will not cover adding an event for every single event mentioned above. Once you know who to do it for a few events, you’ll have plenty of opportunities to practice adding sounds for the other events.

In this article, I’ll be assigning sounds only to the following events:

  • Player wins
  • Player busts
  • Player gets a Blackjack
  • Player gets a Thunderjack
  • Dealer busts

After adding a few sounds, you’ll get the gist of how to add sounds to your game.

Well, let’s get started!

Adding Sound Effects To Your Project

After you’ve decided which events that will play sounds, you need to add the sound files to your project. Phaser Editor can handle this. ⭐

Phaser Editor uses an asset pack manifest file that defines all the assets and the keys that Phaser uses to reference them. Instead of writing the code to load each asset, only this asset pack file needs to be loaded. It is a JSON file, and if you’d like to know more about assets management, visit this topic.

For this project, I have a manifest file called pack.json. After you have a pack file added to your project, this line of code is how Phaser loads the pack file:

phaserGame.load.pack('preload', 'assets/pack.json');

You’ll probably want to add that line to the preload function of your preloading game state.

Next, let’s add the sounds to the pack file using the following steps:

  1. Open the pack file in the project explorer by double-clicking on it.
  2. From the Assets window, select the preload folder (or a different section if you’d like to add the assets under a different one).
  3. Press the Add Asset button.
  4. On the Asset Type dialog, button, select audio from the list, then press OK.
  5. In the Audio Selected dialog, select the sounds you want to add to the pack file under the section you selected, then press OK.
  6. Save the pack file.

Note: After adding sounds by default, the key that Phaser Editor assigns to each sound is the name of the sound file. The key is how you will reference the sound in your code so you can play it. If you want, you can change the key of any sound by editing the key text field. If you do, make sure the key is unique to all the other keys.

Finally, if you need to later, you can add more sounds to the audio group later on, or remove sounds that you will not be using.

Now that the sound files have been added to the asset pack file, let’s start using them for some events in the game.

Add the Player Wins Sound

First, we’ll add a sound that plays when you win. “Winning” is defined as winning more credits that you spent during the round.

We’ll return to the endRound function that we last saw here. Make the following edits to it:

endRound
GamePlay.prototype._endRound = function() {
  if (this._dealerData.isBust) {
    this._presentPlayersWinViaDealerBust();
  } else {
    this._compareCards();
  }
  
  this._showBetUi();
  this._playWinSound();
};
playWinSound
GamePlay.prototype._playWinSound = function() {
  if (this._playerData.credits > this._startingCredits) {
    this.game.sound.play("snd_win01_12");
  }
};

The Phaser game object contains a sound property, which is a reference to SoundManager object. The SoundManager has a play function on it, and the first parameter is the asset key for the sound that was loaded.

Note: The snd_win01_12 string is the key of the win sound I used when loading the win sound in to the asset pack file. The key of your win sound will likely be different.

We’ve seen PlayerData.getTotalBet before, but what’s this this._startingCredits property? Hmm… 🤔

Well, we want to compare the number of credits the player has at the end of the round to the number of credits they had at the beginning of the round. The this._startingCredits property will track how many credits they had, just before they started the round (before having their credits deducted).

So, we can define this._startingCredits in our onBetButtonPressed function with this modification:

onBetButtonPressed
GamePlay.prototype._onBetButtonPressed = function() {
  if (!this._canAffordBet()) {
    //can't afford the bet - cancel the bet placing method, and don't start the game.
    return;
  }
  
  this._startingCredits = this._playerData.credits;
  this._payRoundCost();
  this._hideBetUi();
  this._beginRound();
};

That should do it for the win sound. Let’s see how it looks (and sounds like!) so far. The win sound should only play when you’ve won more credits than you spent:

Add The Player And Dealer Busts Sounds

Next, we’ll add a sound that plays each time a player or the dealer busts.

We’ll revisit the beginPlayerBust function, and make the following mods:

GamePlay.prototype._beginPlayerBust(player) {
  player.isBust = true;
  if (this._isPlayerId(s_playerId)) {
    this.game.sound.play("snd_bust");
  } else {
    var as_dealerBustSoundKeys = [ "snd_dealer_bust1", "snd_dealer_bust2" ];
    var s_dealerBustSoundKey = Phaser.ArrayUtils.getRandomItem(as_dealerBustSoundKeys);
    var dealerBustSound = this.game.sound.play(s_dealerBustSoundKey);
    if (dealerBustSound) {
      var f_onSoundStop = function(sound, marker) {
        this._setNextTurnPlayer();
      };
      
      dealerBustSound.onStop.addOnce(f_onSoundStop, this);
      return;
    } else {
      this._setNextTurnPlayer();
    }
  }
};

Added quite a bit to this one! 😅 If the player busts, we just play one sound. But if the DEEEEELUR busts, well, let’s get just a little fancy here. 😎

We’re doing two things here:

First, we’re choosing one of two sounds to play randomly (the dealer will have different busts sounds, just for the hell of it, and we want to stick it to the dealer when they lose).

Second, we want to wait until the sound has finish playing before we continue. Say the dealer busts, and the dealer bust sound plays. Also, say the player also won this game. What would happen is both sounds would be playing together – the dealer bust sound, and the player won sound. This isn’t what we want. So, we’ll wait until the dealer bust sound has completed playing before proceeding.

It’s worth pointing out that the f_onSoundStop variable is a function setup as a callback for the bust sound’s onStop Signal. We register the callback by calling the signal’s addOnce function, and specifying the callback as the first parameter. When the sound finishes playing, the Phaser will automatically call the f_onSoundStop function.

And here are the player and dealer bust sounds in action:

Add Blackjack and Thunderjack Sounds

Next, we’re adding sound effects that play every time a player wins with a Blackjack or a Thunderjack.

Let’s start with the Blackjack first.

Once again, we’ll be revisiting some code. In particular this pseudo code from this article will now be updated to:

var playerWithThunderjack = checkIfPlayerHasThunderjack();
var playersWithBlackjack = checkIfPlayersHaveBlackjacks();
var doesDealerHaveBlackjack = hasBlackjack(dealer);
if playerWithThunderjack {
  handleThunderjack(playerWithThunderjack);
  endRound();
} else {
  if doesDealerHaveBlackjack {
    handleDealerBlackjack();
    endRound();
  } else {
    if at least one player has blackjack {
      //play the blackjack sound here
    }
    setFirstTurnPlayer();
  }
}

The checkIfPlayersHaveBlackjacks will function return an array of all the players who have blackjack, so if this array has at least one player in it, we’re good.

Next, we’ll tackle playing a sound if a player has a Thunderjack.

Coming from the code above, we’ll modify the handleThunderjack function:

handleThunderjack
function handleThunderjack(player) {
  player.handData.hasThunderjack = true;
  //play the thunderjack sound here
}

That’s it for adding the Thunderjack sound! 👍🏿 And here are the sounds in play:

Most of the events are just finding the place in your code where it would seem most appropriate to add a playing sound. Only in special cases would you need to wait for a sound to complete playing before proceeding.

We’ll finish this article here. If you have any questions for me about anything I’ve discussed so far, feel free to ask in the comments below. If you’d like to add more sounds to more events, by all means have at it.

Or, if you’re looking to hire a coder to build your next card game (and add all your desired sounds into the game as well!), get in touch with me by e-mailing me at cartrell@gameplaycoder.com, or filling out my contact form.

Thanks guys, talk to you later. Take care,

– C. out.

Looking for Multiplayer in Phaser and Ended up Getting Music Featured!

Hey there.

I was looking around for how to code a multiplayer game using Phaser. This will be coming much later before the GameplayCoder produces a real time, multiplayer game. Nonetheless, exciting times ahead!

During my search, I found Dynetis Games, a game development studio run by Jérôme Renaux.

Jérôme wrote a tutorial on making a multiplayer game with Phaser, also using Socket.io, Node.js, and the Express module.

Having played around with the tutorial, this looks promising. He also has more advanced topics like communication between the server and clients, interest management, and synchronizing clients. This is all useful material and I’ll definitely be coming back to these.

Jérôme also made a simple RPG, hack-and-slash, multiplayer game called Phaser Quest, which you can play here if you want. The game is 100% free, requires no signup, and it can be completed in about a half hour (or much less, if you’re good).

He was asking for music contributions for the game. Since I’m a creator of music myself, and I’m pretty good with OpenMPT, a music tracker, and I’ve made music for my own two Flash games, Blast Force and Laser Stryker, I thought I’d take some time to make some music for Phaser Quest.

I decided on making 8-bit-sounding chip tunes, to match the old-school retro look of this pixel art game. Using an NES style format, that is, songs with only five channels: two pulse wave generators, a triangle wave, a noise channel (you know, “PSCHSCHSCSHCSHCH!!”), and a samples channel.

Man, I tell ya, when you’ve only three melodic channels (the two pulse waves and the triangle), that really forces you to be creative. Due to these constraints, creating chords that often use four or more notes, such as major sevenths and minor sevenths, suspended sevenths, and even more challenging with five-note chords like a dominant 9sus4 chord

Here are some examples of the aforementioned chords, all in the key of C:

Major seventh chord
Minor seventh chord
Suspended seventh chord
Dominant 9sus4 chord

I’ve identified seven areas in Phaser Quest for which I’d write the songs.

1. Intro
Lemme innerduce y’all to Phaser Quest!

The intro is very short, and friendly tune. This tune is played on the first screen, where you create your character or resume from a previous game. Inspiration came from music I wrote for a previous game coded for a client, Sprinter.

2. Town
Your adventure starts in this town, with your fellow neighbors, a serene environment, and of course, a buncha giant rats. Unlike most RPG games, yes, you can actually get killed by monsters in town. This game’s playin’ hardball. I love it!

Wanting to do something different than the often serene tunes heard in RPGs (especially those using a medieval theme), this is another friendly tune, but with an upbeat vibe to it.

3. South Shore
That dude in the shades is diggin’ it.
4. Forest
The forest, in my opinion, is the first challenging of the game, especially with them ogres, a buncha overgrown, stankin’ ass brutes.

North of the town is the forest. Here you’ll find a slower tune. The main rhythm is short and repeated a few times, each time, it ascends by a minor third, and switching between major and minor tonalities.

5. Desert & Graveyard
You’d better make sure your equipment is strong enough. That’s all I can say.

These two areas use the same tune, with a moderate speed rhythm. This area, especially the desert, is the first difficult area in the game, in my opinion, because of the ogres and especially, the armored skeletons. Because of these relatively strong monsters and harsh environment, the song has a melancholy feel to it. I got inspiration from this song from Tecmo’s Ninja Gaiden 3 for the Nintendo Entertainment System (NES), stage 2-1 theme.

6. Death Valley
The best song in the game, if I do say so myself.

This place reminded me of the music used in Acclaim’s Ironsword, Wizards & Warriors 2, fire elemental. I really like the part that starts 17 seconds into the tune. I liked it so much, that I used that segment and built an entire song around it, using it as the bridge of the song. The first half builds up to it using rather quirky chord patterns and a melodic riff to go along. There are even some influences of jazz in this tune as well. 😎

7. Skeleton King’s Chamber
The King’s guarded by his two lieutenants. Interesting enough, when you defeat the King, you get the strongest weapon and armor in the game. I’d think you’d get these two items BEFORE you get to the king. Unless there’s some monster that comes after the King who is stronger, there isn’t much use for these two items. But, you can look at them as prizes for beating the King. Dat red armor does look cool, tho.

The final area of the game reminds me of the River of Flame from Diablo II.

I got inspiration to make this “dark epic” tune from level 28 of Doom 2. I also added in some other ominous-sound elements. But to balance out all this gloom and doom, I also got inspiration from the escape theme of Metroid, which in my opinion, is a back-and-forth between urgency and heroism (you just defeated Mother Brain, after all). The tune finishes with a really twisted composition – I figured why not get a little crazy here.

So, those are the songs I contributed to Phaser Quests’s cause. Once the has been updated with all the songs, I’ll let you guys know.

In the meantime, give these tunes a listen and let me know what you think!

Thanks, and talk to you soon.

– C. out.