- Getting Started with melon.js
- Recipe: Creating a Tiled Map
- Recipe: Starting the Game
- Recipe: Adding a Character
- Recipe: Building a Collision Map
- Recipe: Walking and Jumping
- Recipe: Title Screen
- Recipe: Adding Collectables
- Recipe: Enemies
- Recipe: Powerups
- Recipe: Losing, Winning, and Information
- Summary
Recipe: Title Screen
First, you need the TitleScreen object that you’ll show players when they start the game or when Guy falls into a hole. Let’s add the code in Listing 5.11 to the bottom of the screens.js file.
Listing 5.11. Creating a TitleScreen Object
var TitleScreen = me.ScreenObject.extend({ init: function() { this.parent(true); me.input.bindKey(me.input.KEY.SPACE, "jump", true); }, onResetEvent: function() { if (this.title == null) { this.title = me.loader.getImage("titleScreen"); } }, update: function() { if (me.input.isKeyPressed('jump')) { me.state.change(me.state.PLAY); } return true; }, draw: function(context){ context.drawImage(this.title, 50, 50); } });
Let’s look at what this code in Figure 5.11 does. First, you create the variable TitleScreen to inherit from me.ScreenObject. Then in the init function, you call this.parent(true) to set the TitleScreen as visible and ensure that the update and draw functions work. You also bind the spacebar to the jump key.
In the onResetEvent function, you load the titleScreen image if it has not already been set. The update function waits for the spacebar to be pressed and goes to the main game loop if it has.
The draw function draws the image (first parameter) at the specified pixel offsets (second and third parameters). If you haven’t been through any of the other chapters with games that use canvas-based engines, you may wonder what context, the parameter in the draw function, refers to. This is the Canvas Rendering Context. melonJS declared it for you. In this case, it is the 2-D canvas, but the API that declared this as canvas.getContext('2d'), can also be used to initialize a webgl (3d) context.
As one last bit of cleanup, there’s no sense in binding the jump key twice, so while you’re in the screens.js file, take out this line from the PlayScreen object: me.input.bindKey(me.input.KEY.SPACE, "jump", true);.
Next, load the screen image to resources.js as in Listing 5.12.
Listing 5.12. Loading the Screen Image as a Resource
{ name: "titleScreen", type: "image", src: "titleScreen.png" }
Next, you need to make three changes to your loaded function in main.js. First, you need to assign your TitleScreen object to the predefined MENU state. Then, you need to change the state that is loaded at the beginning of the game from PLAY to MENU. Last, you can define a transition effect between screens. It should now look like Listing 5.13.
Listing 5.13. Working with the MENU State
loaded: function() { me.entityPool.add("player", PlayerEntity); me.state.set(me.state.PLAY, new PlayScreen()); me.state.set(me.state.MENU, new TitleScreen()); me.state.transition("fade", "#2FA2C2", 250); me.state.change(me.state.MENU); }
We’re almost there; our title screen boots up quite nicely at the beginning, but we still haven’t enabled automatic resetting after falling into a hole. To do this, we’ll make a few minor adjustments to our PlayerEntity object in the entities.js file.
Add the gameOver function after the update function in the PlayerEntity object with the code in Listing 5.14. This can go just above the last line in the file. Make sure to add the comma to the curly brace above the gameOver function. Don’t add a new curly brace there. Just the comma.
Listing 5.14. The gameOver Function in entities.js
}, // Don't forget to add this comma here gameOver: function() { me.state.change(me.state.MENU); } }); // This is the end of the file (not new)
You also need some condition to trigger the gameOver function, as shown in Listing 5.15. Depending on how you set up your map, you may want to do it differently, but a basic “fell in the hole” type condition is to check the position of Guy along the y-axis. If he’s too low, it’s game over. This can directly follow the call to updateMovement.
Listing 5.15. Game Over if Guy Falls in a Hole
this.updateMovement(); if (this.bottom > 490){ this.gameOver(); }
Now players see the title screen when they lose, which is a much better experience than having to reload the page after every mishap. That’s great, but we still have a problem. Right now, the only “adventure” that Guy is on is the “adventure of trying not to fall in holes.” How about we give him a better reason for leaving home?