Alphadrop Screenshot

Creating Animated Scoring in an HTML5 Phaser Game



·

When it comes to games (and apps in general really), I’m a big believer that making your game just that little bit more juicy can make the overall quality and enjoyability of your game increase drastically.

Juicy is clearly a pretty vague term, but I think it’s pretty fitting (think biting into a juicy orange filled with flavour). In the context of a game this would mean adding things like:

  • When the player collides with something or kills an enemy, add some particle effects
  • If the player is running fast have their hair or cape blow in the wind
  • Create tweens and animations for things
  • Add sound effects

To give you an example, in a game I’m working on right now I’ve created a more interesting scoreboard by adding some animations:

Alphadrop Preview

(If you want to learn how to build a game like this, I’ve started a tutorial series on building a word search game in Phaser)

Rather than just having the scores text label update to the new score, the scoring process now goes something like this:

  • A ‘+5’ label appears wherever the user finishes the word to indicate how many points they got for that word (this doesn’t just add juice to the game, it also provides valuable information to the player)
  • That label is then tweened to the score label
  • When the new label reaches the score label, it is destroyed, the new score is added to the total score and a growing / shrinking animation is triggered
  • The score also is not added to instantly, the score is applied over time so it rises like a stopwatch timer

These little improvemnts are quite easy to make, maybe they’ll require you to spend 10% more time bulding your game, but it can really give your game that level of polish that will take it to the next level.

In this tutorial, I’m going to walk you through how you can create a similar style animated scoring system for your own Phaser game. By the end of it, you should have something that looks like this:

Score Animations Preview

BONUS CONTENT: Grab a template for Phaser games and the source code for this tutorial by entering your email address below:

Setting up the Scoreboard

Before we can do anything fancy, first let’s just add the basic scoring. I’ll also show you my simple little trick for gradually increasing the score now as well.

Add the following code to the create method in your main state:

	create: function() {

		var me = this;

		me.game.stage.backgroundColor = '#16a085';

		//Keep track of the users score
		me.score = 0;
		me.scoreBuffer = 0;

		//Create the score label
		me.createScore();
	
	},

We’ve set up a couple of variables here: the score is the players actual score, and the scoreBuffer is how many points the player has that need to be “animated” into the main score. We also make a call to createScore here to set up the score label, which we will create now:

Add the following function to your main state:

    createScore: function(){

        var me = this;
        var scoreFont = "100px Arial";

        //Create the score label
        me.scoreLabel = me.game.add.text(me.game.world.centerX, 50, "0", {font: scoreFont, fill: "#ffffff", stroke: "#535353", strokeThickness: 15}); 
        me.scoreLabel.anchor.setTo(0.5, 0);
        me.scoreLabel.align = 'center';

        //Create a tween to grow / shrink the score label
        me.scoreLabelTween = me.add.tween(me.scoreLabel.scale).to({ x: 1.5, y: 1.5}, 200, Phaser.Easing.Linear.In).to({ x: 1, y: 1}, 200, Phaser.Easing.Linear.In);

    },

Here we are just creating a simple text label and setting it’s intial value to “0”. We also set up a tween here though, this tween will make the score label grow to 1.5x it’s original size (we are tweening the labels scale property to do this) and then shrink back down to it’s original size. This tween won’t do anything yet, but we will be able to trigger it later.

Now what we want to be able to do is add whatever score we want to the scoreBuffer and then have that automatically be animated into the total score.

Add the following code to the update method in your main state:

    update: function() {

        var me = this;

        //While there is score in the score buffer, add it to the actual score
        if(me.scoreBuffer > 0){
            me.incrementScore();
            me.scoreBuffer--;
        }
    },

If you’re unfamiliar with the update method in Phaser, basically it is called on loop throughout your game to update things. It constantly checks the state of the game and acts accordingly, e.g: is spriteX colliding with spriteY? Ok, so destroy spriteY. We can hook into this functionality to get the effect we want, by continually calling the incrementScore function which will add 1 to the score, and removing 1 from the scoreBuffer. So each time the update method is called, the score will increase by 1 towards our destination score.

We haven’t create the incrementScore function yet though, so let’s do that now.

Add the following function to your main state:

    incrementScore: function(){

        var me = this;

        //Increase the score by one and update the total score label text
        me.score += 1;   
        me.scoreLabel.text = me.score;      

    }

This function just increases the score by one and updates the text label accordingly. Now we’ve got the basic scoring system set up (with a little bit of juice already), we can start on the fun bit.

Animating New Scores to the Total Score

Now we’re going to generate the score labels that fly to, and are then added to, the total score. This creates a really cool effect but it also provides some visual feedback to the player, which can help them understand what’s going on and where their score is.

To handle all of this, we are going to create one more function called createScoreAnimation which will allow us to trigger the animation from any coordinates in the game, add a message that will be displayed to the user, and provide the score to be added to the main score.

Add the following function to your main state:

    createScoreAnimation: function(x, y, message, score){

        var me = this;

        var scoreFont = "90px Arial";

        //Create a new label for the score
        var scoreAnimation = me.game.add.text(x, y, message, {font: scoreFont, fill: "#39d179", stroke: "#ffffff", strokeThickness: 15}); 
        scoreAnimation.anchor.setTo(0.5, 0);
        scoreAnimation.align = 'center';

        //Tween this score label to the total score label
        var scoreTween = me.game.add.tween(scoreAnimation).to({x:me.game.world.centerX, y: 50}, 800, Phaser.Easing.Exponential.In, true);

        //When the animation finishes, destroy this score label, trigger the total score labels animation and add the score
        scoreTween.onComplete.add(function(){
            scoreAnimation.destroy();
            me.scoreLabelTween.start();
            me.scoreBuffer += score;
        }, me);
    },

First we create a new text label to show the message, and we add it at the coordinates provided. Then we create a tween that will move that label from where it currently is to the total score label.

We also add a callback for when that tween finishes. When it does finish we destroy the label, add the score to the scoreBuffer, and trigger the total score labels grow and shrink animation that we created before.

Testing the New Scoring System

The great thing about this scoring system is that it can basically be dragged and dropped into most games. All you have to do is trigger the createScoreAnimation function at specific coordinates in the world. So although this suits puzzles games very well, you could even use it for platformers and other games (just trigger the animation from where the player killed an enemy for example).

We’ve currently got no way to test it out yet though because we don’t really have a game, so let’s add a bit of code that will allow us to click around the screen to generate random scores.

Add the following code to the end of the create method in your main state:

        var seed = Date.now();
        me.random = new Phaser.RandomDataGenerator([seed]);

        me.game.input.onUp.add(function(pointer){

            var newScore = me.random.integerInRange(1, 30);
            me.createScoreAnimation(pointer.x, pointer.y, '+'+newScore, newScore);

        }, me);

In this example I’m just using a simple “+5” type message, but you could change that to any message you want like “WOW!” or “You got game!” and so on.

Summary

That about wraps up this tutorial, and I think the end result is really nice. With this system in place the game I’m working on is much more satisfying to play.

This is just one particular example of what you can do, I’d encourage you to experiment with your own games or even extend this example to add some more juiciness. Of course, it is possible to go overboard with too many animations and so on, but in the case of games I think that’s probably pretty hard to do as long as the animations look nice (just be careful on mobile, if you have too much going on it can lead to bad performance).

What to watch next...