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 .
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Contents
How to Make A Simple HTML5 Game With Enchant.js
60 mins
- Introducing enchant.js
- Setting Up the Environment
- Preparing Your Project Structure
- Why Hello There, Ocean!
- Node, Scene and Game: The Basic Concepts
- Object-Oriented Style With enchant.js
- Who Let the Penguin Out!
- A Closer Look at Sprites
- Basic Animation
- Touch Detection
- Ice, Ice Baby
- Collision Detection
- Tally the Score
- A Little Water Music
- Every Penguin Has His Day
- Testing Your Game on Mobile Browsers
- Prepare for iOS Device
- Where To Go From Here?
- Credits
Preparing Your Project Structure
enchant.js doesn’t enforce any directory structure for projects. You can structure the project folders any way you like. So in this tutorial, you’re going to structure things in a way that makes sense to me. Hopefully, it will make sense to you, too. ;]
Go to the directory that you want to be your workspace and create a new folder named penguindive.
Next, create subfolders within your penguindive folder so that the folder structure is as shown:
penguindive/
penguindive/js
penguindive/js/lib
penguindive/res
The res and js folders will be where you store your JavaScript files and your game assets, respectively. The lib folder will be where you store third-party JavaScript files/libraries.
The next step is to put all the game assets you downloaded earlier inside the res folder. Simply extract the ZIP file and copy the files. Once you do that, you should have the following files in the res folder:
BG_Over.png
BG.png
bgm.mp3
Eat.mp3
fishSheet.png
Hit.mp3
Ice.png
penguinGameOver.png
penguinSheet.png
You will not be using all of these files in this tutorial. However, feel free to use them to extend the game on your own, as a challenge. There are some suggestions for how to do this at the end of the tutorial. :]
Next, extract the enchant.js archive you downloaded from GitHub. Copy the enchant.js file and put it in your js\lib folder.
Note: You’ll notice that there are two versions of enchant.js in the archive – enchant.js and enchant.min.js. The second file is the minified version, where extra spaces and carriage returns have been removed to make the smallest downloadable version possible for the code.
Since that version also replaces variable names and methods with short (usually incomprehensible) alternatives, it doesn’t lead to very human-readable code. So it’s best to use the standard version of the code during development and debugging (enchant.js) and to use the minified version in production (enchant.min.js).
Note: You’ll notice that there are two versions of enchant.js in the archive – enchant.js and enchant.min.js. The second file is the minified version, where extra spaces and carriage returns have been removed to make the smallest downloadable version possible for the code.
Since that version also replaces variable names and methods with short (usually incomprehensible) alternatives, it doesn’t lead to very human-readable code. So it’s best to use the standard version of the code during development and debugging (enchant.js) and to use the minified version in production (enchant.min.js).
You’re now ready to start the actual coding!
Why Hello There, Ocean!
Let’s start with something simple: saying hi to the world where your game will take place. :]
Launch your favorite text editor and start by creating the index.html file, which as I’m sure you’re aware, will be the first file loaded when the game folder is accessed via a browser:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Penguin Dive</title>
<script src="js/lib/enchant.js"></script>
<script src="js/main.js"></script>
</head>
<body>
</body>
</html>
Save the file (name it index.html) in the penguindive folder.
The HTML code is fairly simple. You’ve included two JavaScript files – the enchant.js library itself, and a main.js, which will be the file where you write code for your game.
Next, create main.js and add the following code to it (as the index.html file indicated, the main.js file goes in the js subfolder when you save it):
// 1 - Start enchant.js
enchant();
// 2 - On document load
window.onload = function() {
// 3 - Starting point
var game = new Game(320, 440);
// 4 - Preload resources
game.preload('res/BG.png');
// 5 - Game settings
game.fps = 30;
game.scale = 1;
game.onload = function() {
// 6 - Once Game finishes loading
console.log("Hi, Ocean!");
}
// 7 - Start
game.start();
};
The code above is all you need to get an enchant.js game working. Let’s go over it step-by-step:
- Export all the library classes globally. This allows you to use classes from enchant.js without having to type the namespace every time.
- Create a function that will be invoked once the HTML document is done loading. You will initialize your game inside this function.
- Create an instance of the Game class, which is the main application class of an enchant.js game. The constructor for the Game class takes two arguments: the width and height of the game’s screen in pixels.
- Preload the background image for the game. When you have resources that take a lot of time to load (like big images or background soundtracks), it’s a good idea to load them before you actually need to use them.
- Configure the game settings. Notice the line setting the game frame rate to 30 fps (frames per second). This does not mean that the game will always run at 30 fps. It’s very likely that the fps will drop on mobile platforms. Think of this as a maximum fps that the game will try its best to achieve.
- The Game object’s onload event will be invoked once the game finishes loading everything in the preload queue. This is the entry point of your game.
- As the method name implies, this will start your game. Starting your game will initiate the preloading process, and invoke the onload method once the preloading is finished.
Note: The game’s frame rate and scale cannot be changed after you start the game. Make sure to set them before calling game.start()!
Note: The game’s frame rate and scale cannot be changed after you start the game. Make sure to set them before calling game.start()!
Save your main.js. It’s time to see if your game is running correctly on the desktop browser. Simply open index.html, or, if you’re using a web server, navigate to the game folder via localhost.
When you open the game page, there shouldn’t be anything on the screen – after all, you haven’t put anything there yet! But if you check your browser JavaScript console, you should see “Hi, Ocean!” displayed.
Node, Scene and Game: The Basic Concepts
When working with enchant.js, there are some basic concepts that you need to know:
Scene
enchant.js uses the concept of a scene to handle the game flow. A game can have many scenes, but only one of them can be running at a time. By switching scenes, you can change the game’s state/screen.
For example, a game’s flow might look like this:
According to the diagram, there are four scenes in the game. Starting from the Title Scene, players can go to the Game Scene, where the main gameplay takes place. From there, they can switch between the Game Scene and the Option Scene to adjust the game’s settings.
Once the player is back in the Game Scene and the game is over, the game moves to the Game Over Scene, before returning to the Title Scene again, ready for the next game session.
Game
As stated earlier, the Game class is the main application class. One Game object represents one single enchant.js game. The Game class also acts as a Scene Manager. It stores instances of scenes in a stack, where the top scene on the stack is the active scene.
In enchant.js, a game always comes with a scene called the Root Scene (i.e. the first scene in the stack). By manipulating the scene stack, you can change the game’s state easily.
There are three ways you can manipulate the scene stack through a Game object:
- Replace: This replaces the active scene with a new one. You can’t go back to the old scene, unless you store a reference to it somewhere before replacing it.
- Push: This pushes a new scene on top of the stack, making it the active scene. The old scene is kept inactive in the stack.
- Pop: This removes the scene at the top of the stack, making the next scene in the stack the active scene.
Node
Scenes in enchant.js are implemented using a tree data structure. Hence, many objects in an enchant.js game are nodes. In fact, if you are familiar with Cocos2D development, the concept is fairly similar to that of a node in Cocos2D.
There are many types of nodes in enchant.js. Here are a few examples, all of which you’ll use shortly:
- Sprite: a node for displaying static images and animation.
- Label: a node for displaying text.
- Group: a node for grouping many nodes together.
Therefore, a scene is actually a tree of nodes, where the root is a Scene node. It may have some children nodes that are sprites, labels, and so on.
Do you “node” what I mean? Not quite? Let’s write some code to help you understand this better! :]
Add the following lines to main.js after you print “Hi, Ocean!” to the console:
// 1 - Variables
var scene, label, bg;
// 2 - New scene
scene = new Scene();
// 3 - Add label
label = new Label("Hi, Ocean!");
// 4 - Background
bg = new Sprite(320,440);
bg.image = game.assets['res/BG.png'];
// 5 - Add items
scene.addChild(bg);
scene.addChild(label);
// 6 - Start scene
game.pushScene(scene);
Let’s take a closer look at each section:
You can access the image data you have loaded into the game through the game’s assets dictionary. This dictionary will map the path to the loaded resource. Since you told the game to preload a file at path res/BG.png, this path will be used as a key that maps to the ocean background.
Note: The order in which you add nodes to a scene is important. In enchant.js, the framework will draw a newly-added node on top of those that were added previously.
If you switch the order in the code above, you won’t see the label even though it is actually in the scene. This is because the background would be on top of the label.
- Define some variables that will be used in the following code.
- Create an empty scene. You will use this scene as your main game scene.
- Create a Label node to display the text “Hi, Ocean!” on the screen. The Label class constructor takes one argument, which is the text you want to display.
- Create a Sprite node for the background image. The constructor takes two arguments: the width and the height of the image you want to display. Once the sprite is created, you assign the image you want this sprite to display.
You can access the image data you have loaded into the game through the game’s assets dictionary. This dictionary will map the path to the loaded resource. Since you told the game to preload a file at path res/BG.png, this path will be used as a key that maps to the ocean background.
- Add your new nodes to the scene. The addChild method means that the node you add will become one of the scene’s child nodes.
Note: The order in which you add nodes to a scene is important. In enchant.js, the framework will draw a newly-added node on top of those that were added previously.
If you switch the order in the code above, you won’t see the label even though it is actually in the scene. This is because the background would be on top of the label.
- Your scene is ready. It’s time to make this scene your active scene. To do this, you simply push the scene onto the game’s scene stack.
Note: The order in which you add nodes to a scene is important. In enchant.js, the framework will draw a newly-added node on top of those that were added previously.
If you switch the order in the code above, you won’t see the label even though it is actually in the scene. This is because the background would be on top of the label.
Save main.js and reload your browser page. You should see something similar to the following: