How to Make A Simple HTML5 Game With Enchant.js

This is a post by Tutorial Team member Guts Rodsavas, an iOS development trainer at Software Park Thailand and game developer at Coffee Dog Games. Are you curious about developing cross-platform mobile games that work in a web browser? Well, as you probably know, Apple doesn’t allow Flash to run on iOS devices, and Adobe […] By .

Leave a rating/review
Save for later
Share
You are currently viewing page 5 of 7 of this article. Click here to view the first page.

Tally the Score

This game could use a way to keep score. So, let’s change the “Hi, Ocean” label into something more useful.

Go to where you create the label in the SceneGame constructor and modify the code to look like this:

// Label
label = new Label('SCORE<br>0');
label.x = 9;
label.y = 32;        
label.color = 'white';
label.font = '16px strong';
label.textAlign = 'center';
label._style.textShadow ="-1px 0 black, 0 1px black, 1px 0 black, 0 -1px black";
this.scoreLabel = label;

This time you set the text to SCORE<br>0. The <br> between SCORE and 0 is the line-break tag.

The rest of the code sets the label’s properties, such as its position, color, font, and text alignment. These should be self-explanatory.

For some interesting effects, you can edit the CSS style of a label by accessing the _style property. For example:

label._style.textShadow ="-1px 0 black, 0 1px black, 1px 0 black, 0 -1px black";

The above line uses the text shadow property to add a black border around the text.

Finally, you keep a reference to the label in your SceneGame instance under the name scoreLabel.

Save and run the game again. The “Hi, Ocean” label should now be in the top center of the game screen, and should read, “SCORE 0”.

Of course, currently there is no scoring mechanism! You are going to increase the score as time passes.

Add the following two variables at the end of SceneGame’s constructor:

this.scoreTimer = 0;
this.score = 0;

You use scoreTimer as a timer to increase the game score as time passes, while the score variable contains the game score (obviously!).

You want the label to report the player’s current score. Whenever the score is modified, the text on the label should be updated as well. Therefore, it is a better idea to wrap the score modification into a method.

Add a method called setScore to SceneGame:

setScore: function (value) {
    this.score = value;
    this.scoreLabel.text = 'SCORE<br>' + this.score;
}

This method does exactly what you want. It changes the score, and updates the score label to reflect the current score.

Go to SceneGame’s update method and add the following lines at the beginning:

// Score increase as time passes
this.scoreTimer += evt.elapsed * 0.001;
if (this.scoreTimer >= 0.5) {
    this.setScore(this.score + 1);
    this.scoreTimer -= 0.5;
}

You’re probably familiar with this pattern by now: every 0.5 seconds, you increase the score by 1 point using the setScore method.

Save and run the game again. Now the score increases with each passing second, and you don’t even have to pretend to play! Wow, could this game get more difficult or exciting? :P

Don’t worry, it will! Your penguin’s field day won’t last much longer.

A Little Water Music

Before you configure your end game, let’s pause to ask: what’s a good game without some snazzy sound effects and music?

enchant.js also comes with a simple audio system. However, while the audio system works pretty well on a desktop browser, this isn’t quite the case for mobile browsers.

Audio on mobile browsers is still a big problem on any OS. Currently, it is acceptable for a mobile HTML5 game to NOT have any audio at all. Hopefully, things will improve on mobile browsers soon.

The audio system in enchant.js uses the Web Audio API with Flash fallback. In order to enable Flash fallback, you have to add some helper files to your project.

Go to the enchant.js folder (the one into which you extracted the files from the GitHub project) and copy sound.as and sound.swf:

Go back to your project folder and paste the copied files into the root folder, penguindive. Now, if a browser doesn’t support Web Audio, it will use Flash to play the sound file instead.

It’s time to preload more stuff! Modify the preload line in main.js to be as follows:

game.preload('res/BG.png',
             'res/penguinSheet.png',
             'res/Ice.png',
             'res/Hit.mp3',
             'res/bgm.mp3');

Inside SceneGame’s update method, go to the if block where you check for collision. Modify the if block to look like this:

if (ice.intersect(this.penguin)){
    var game = Game.instance;
    game.assets['res/Hit.mp3'].play();
    this.iceGroup.removeChild(ice);    
    break;
}

Unlike images, audio files loaded by enchant.js will be kept as Sound objects inside the assets dictionary. You can access these objects directly and call the play method to play the audio.

Save and run the game. When the penguin hits a boulder, the hit sound effect should play, which sounds kinda like a board slamming a wall (well, at least if you’re using a browser that supports it).

Note: Audio playback might or might not work correctly, depending on the browser. It worked fine for me on Safari on a Mac, but would not work correctly with the latest Firefox beta if I was loading the file directly. But if I loaded the game via a local web server, then it worked fine on Firefox as well.

So, if you get a loader bar (it usually appears very quickly without the sound pre-loading, and so you might not even notice it) and it doesn’t complete, then try a different browser or, if you are loading the file directly, try loading it via a local web server. If nothing works, remove the sound pre-loading, and things should work correctly again.

Next, you’ll add the background music to the game. Go to where you declare instance variables inside the SceneGame constructor. Add the following after the instance variables:

// Background music
this.bgm = game.assets['res/bgm.mp3']; // Add this line
// Start BGM
this.bgm.play();	

The above code stores a background music sound object for later use, and then tells the background music to play.

You want the background music to loop indefinitely, so go to update in SceneGame and add the following lines to the end:

// Loop BGM
if (this.bgm.currentTime >= this.bgm.duration ){
    this.bgm.play();
}

Since there is no loop option in the enchant.js audio system, you have to implement it manually. This block of code checks to see if the audio’s current time has reached the end of the audio file. If it has, then the audio is played from the start again.

Save and run the game, and you should hear the background music play – a happy and silly tune, perfect for this game!