Phaser.io how to use atlasHash to your advantage.

Lately I have been using Phaser.io as a game framework/engine. And one thing that is quite tedius, is to manage your Sprites and animation frames, it is roughly 40% of your game development time.

However there is one tool that now -that officially supports Phaser- cuts down this time at least by 90%.

View more info or download TexturePacker here: https://www.codeandweb.com/texturepacker

The tool is named TexturePacker and allows the load of all your assets and combines them very conveniently into a single Spritesheet and exports that Spritesheet along with a .json file that “tells” Phaser where to find each frame (based on coordinates on the spritesheet), this is called an atlasJSONHash/atlasJSONArray.

I have attached a video showcasing a very rough export that I will use to create today’s codepen example (see below).

Here is the end result of our game.

See the Pen OPpgZw by Michael Dobekidis (@netgfx) on CodePen.

Continue to see details about creating a Player and animations with atlasJSONHash.

Now lets see how we export from the TexturePacker

Now we should have a .png file with all our sprites and one .json file with all our sprite coordinates.

So let’s start creating our example.

The Main Game

var reg = {};
var GameState = function(game) {
};

// Load images and sounds
GameState.prototype.preload = function() {
    this.game.load.image('ground', 'http://netgfx.com/trunk/games/zheeps/assets/middle.png');
    this.game.load.atlasJSONHash('mage', 'http://netgfx.com/trunk/games/zheeps/assets/mage_skill.png', null, mage_idle);
    var jsonObj = this.game.load.json("mage_","http://netgfx.com/trunk/games/zheeps/src/atlas/mage_skill.json");
};

// Setup the example
GameState.prototype.create = function() {
    // Set stage background to something sky colored
    this.game.stage.backgroundColor = 0x4488cc;
    createGround();
};

// The update() method is called every frame
GameState.prototype.update = function() {
    if (game.input.activePointer.isDown && reg.gun.animations.currentAnim.name !== "ability") {
       
    }
};

function createGround() {
    // Create some ground
    reg.ground = game.add.group();

    var groundRect = game.add.tileSprite(0, game.height - 64, game.width, 64, 'ground');
    //groundRect.scale.setTo(0.5,0.5);
    groundRect.width = game.width;
    reg.ground.add(groundRect);
}

var game = new Phaser.Game(848, 450, Phaser.CANVAS, 'game');
game.state.add('game', GameState, true);

Now we have created the main game and the “ground”.
You might note the I used:

atlasJSONHash('mage', 'http://netgfx.com/trunk/games/zheeps/assets/mage_skill.png', null, mage_idle);

And declared a JSON object instead of a file. This is a nice workaround since Phaser+Codepen doesn’t load JSON via crossdomain. So I converted the json into a .js file and added the json object as a variable.
This is quite convenient way to include either .JSON files or JSON objects into the atlasJSONHash function.

Adding the Player

We add

createPlayer();

To the create function.

And add the actual function below.

function createPlayer() {
    // Create an object representing our gun
    reg.gun = game.add.sprite(220, game.height - 95, 'mage', 'Mage-Idle__000');

    reg.gunBase = game.add.sprite(270, game.height - 195);
    reg.gunBase.width = 200;
    reg.gunBase.height = 200;
    reg.gunBase.anchor.setTo(1, 0.5);

    // scale it down a bit
    reg.gun.scale.setTo(0.3, 0.3);

    reg.gun.animations.add('idle', Phaser.Animation.generateFrameNames('Mage-Idle__', 0, 23, '', 3), 24, true, false);
    reg.gun.animations.add('ability', Phaser.Animation.generateFrameNames('Mage-Skill__', 0, 31, '', 3), 40, false, false);

    reg.gun.animations.currentAnim.onComplete.add(function () {
        reg.gun.animations.play('idle', 30, true);
    }, this);

    reg.gun.animations.play("idle");
    // Set the pivot point to the center of the gun
    reg.gun.anchor.setTo(0.5, 0.7);

    game.world.bringToTop(reg.gun);
}

What we do here is to declare the atlas from which the graphics will be loaded, that is “mage” and then at which frame we want it to begin with, we selected Mage-Idle__000 (this is the way it is described in the .JSON file)

Then we declare two sorts of animations: one named “idle” and one named “ability”.

After that you will see that we have attached an event listener of the onComplete event, this one is triggered when any animation ends its course (if not set to loop), so when ANY animation ends we want the player to play the idle animation.

And finally we initiate the “idle” animation and the player is good to go.

Adding some action

Now an idle player is nothing fancy so we might want to add some action into it.

This is how we capture the user input and initialize the “ability” animation. So in our “update” function we have this:

if (game.input.activePointer.isDown && reg.gun.animations.currentAnim.name !== "ability") {
               
}

This checks if the user has clicked/tapped and if the player is not currently doing an “ability” animation (we don’t want overlaps), and if those are true we add the following command.

reg.gun.animations.play("ability");

Pretty simple right? We just force the Player object to animate based on the “ability” animation we had declared. And when it will be done -since it is not set to loop- the “onComplete” event will launch and return him to the idle stance (which is looping to show an ongoing state).

I hope you found something interesting here, if yes make sure to comment!

Enjoy!

Facebooktwittergoogle_pluspinterestlinkedin
linkedin

Leave a Reply

Your email address will not be published. Required fields are marked *