Friday, January 8, 2016

You Can't Play Forever

With my one hour of game development time this evening, I decided to finally add "lives" to my Phaser platformer. While I don't want to actually kill Science Frog, the concept of getting more than one life (or attempt) in a game is a fairly standard concept. So far, my game was once-and-done.

The glasses represent the number
of tries (or lives) you get in the game.
Keeping track of how many lives you currently have in the game was simple. I added a lives field to my gameState object. That's the one that I am using to keep track of aspects in the game that need to be shared between the two main game states - the picking a stage and the playing.

var gameState = {
    levels: [],
    currentLevel: "sb",
    lives: 3
};

Now to use that... First, to display the number to the player I added an image of the frog's glasses next to some text beside it. I decided that the glasses would be a good representation of Science Frog. Maybe when he gets beat up too much his glasses will break and that's why he has to restart. That way, I don't have to say he gets killed. Anyway, those steps are simple.

var g = game.add.image(40, 15, "glasses", 0, meters);
g.fixedToCamera = true;

var livesText = game.add.text(78, 5, "x " + gameState.lives, {
    fontSize: 20,
    fill: "#FFFFFF",
    stroke: "#000000",
    strokeThickness: 3
}, meters);
livesText.fixedToCamera = true;

First, I add an Image to the game at position (40, 15). The key for the image is "glasses" which is what I assigned to this image in the asset pack. The 4th parameter, 0, is unused here because as an Image (as opposed to a Sprite) there is only one frame. The last parameter is the group to which this image is added. I am putting it in my meters group, the same one that contains the health bar. After creating it, I set it to be fixed to the camera. This way it doesn't scroll with the rest of the world.

Adding the text for the lives is also simple. Calling game.add.text is all it takes! The first two arguments are the X and Y coordinates. The third is the text itself. The fourth argument is the style object. Its fields define the style of the text. I set the size, fill, stroke, and stroke thickness. Since the background can be very light, putting a black border around the text makes it more readable. The fifth argument is once again the group to which this text should be added - again I use my meters group. Finally, this also gets fixed to the camera.

I've had an onKilled listener on my frog object for some time now, but it didn't do a whole lot. I expanded on that today to take advantage of the lives counter.

frog.events.onKilled.add(function() {
    dieSound.play();
    gameState.lives--;
    bgmusic.stop();
    if (gameState.lives === 0) {
        console.log("game over!");
        game.state.start("stageSelect");
    } else {
        console.log("try again!");
        game.state.restart();
    }
}, this);

The player's frog is killed by Phaser when its health reaches 0 (from colliding with enemies) or when it falls off the bottom of the map. This onKilled event listener is called when that happens. It plays the death sound, decrements the number of lives, and stops the music. If the player has no more lives, the game is returned to the stage select screen, but otherwise the current level just gets reset and the frog starts over back at the beginning.

I suppose this means I need to add in extra-life power-ups somewhere...

You can access the complete source code for this game on GitHub, and you can access the complete Amphibian.com comic on Amphibian.com! Or click on the picture below.

Amphibian.com comic for 8 January 2015