How to use Texture Atlas with TexturePacker

Olivier Biot edited this page Nov 13, 2015 · 23 revisions

featurecarousel_texturepacker

Using a texture Atlas will generally allow you to :

  • save memory, by packing all your sprites into a single texture
  • increase your framerate, by optimising the GPU usage
  • make your game start faster, by loading a single texture

In this tutorial we are going to see how to :

  • use TexturePacker to create a texture atlas
  • import the generated texture into a melonJS project
  • add a static renderable sprite
  • add a renderable animation

Create a Texture atlas

To create a new texture atlas, star by opening TexturePacker, and choose the melonJS data format (It works as well with the generic JSON Array data format but does not contain the optimizations and presets for melonJS). You should see a screen similar to the one below after you've installed TexturePacker:

create new project

Then drag & drop the directory containing your sprite images to the Sprites area of TexturePacker. TexturePacker will automatically load and lay out all image files. For this example we use the assets from the texture packer example here (see the cityscene folder).

imported files

After that use the file selection button to enter a Data file, name it cityscene.json and place it in the [img] folder (to follow the melonJS boilerplate structure), and do the same for the texture file by choosing cityscene.png in Texture file's file selector (also place it in the same folder).

Recommended settings :

  • use "Power of Two" size for the texture, especially if you do plan to use the webGL renderer, to optimize the use of GPU memory
  • we recommend not to use texture rotation when possible (although this usually increases the final texture size), as it forces melonJS to apply a default rotation angle when drawing sprites and, based on how many sprites are to be displayed, can impact performance.

Finally press the Publish sprite sheet button to create the sprite sheet, and we are done in TexturePacker !

Import the generated texture into a melonJS project

As this tutorial is focusing on using TexturePacker, we will assume that you are already familiar with melonJS and that you have at least a first project up & running. If you need help on starting with melonJS, we recommend you to first check either our platformer or space invaders tutorials.

Loading the texture atlas and sprite sheet in melonJS :

The first step is of course to add our two files to the list of assets to be loaded :

game.resources = [
    { name : "texture", type : "json",  src : "data/img/cityscene.json" },
    { name : "texture", type : "image", src : "data/img/cityscene.png" }
];

(Note that resources.js is automatically managed by our boilerplate, as it builds the resources list and exposes it to your app as game.resources (build/js/resources.js) when using the grunt serve task)

Then let's create a global reference of our Texture under the game namespace, so that we can reuse it later :

// load the texture atlas file
game.texture = new me.video.renderer.Texture(
    me.loader.getJSON("texture"),
    me.loader.getImage("texture")
);

Make sure of you course to do this after all resources have been preloaded (in our example we inserted this code into the loaded callback).

Add the static background

Adding a static background is pretty easy, and for that we will use the sprite from our texture called background. In your play screen onResetEvent callback :

// create the background object
var background = game.texture.createSpriteFromName("background");

// set position to the middle of the viewport
// (as the sprite anchorPoint is (0.5, 0.5)
background.pos.set(me.game.viewport.width / 2, me.game.viewport.height / 2, 1);

// add to the scene
me.game.world.addChild(background);

Note that as the default settings in TexturePacker is to use center as the anchorPoint, we also set the default position for the background to the center of the screen, but you can of course change it to top-left or whatever you need, and change the default position accordingly (that would be [0, 0] if top-left coordinates are used for the anchor point).

Also, note that melonJS 3.x provides an alternate and easier way of creating directly a me.Sprite using a texture atlas, as shown below :

// add the Background with default position to the middle of the viewport
var background = new me.Sprite(
    me.game.viewport.width / 2, 
    me.game.viewport.height / 2,
    {
        image : game.texture,
        region : "background.png"
    }
);

// add to the scene
me.game.world.addChild(background, 1);

Add the cap guy animation

Finally we are going to add a renderable animation for our CapGuy Entity.

In our example we use a very simple Entity, that is displayed in the middle of the screen and move along the x axis until it leaves the screen. To add the renderable component to our Entity, we just simply add the following to the Entity constructor :

// create an animation using the cap guy sprites, and add as renderable
this.renderable = game.texture.createAnimationFromName([
    "capguy/walk/0001", "capguy/walk/0002",
    "capguy/walk/0003", "capguy/walk/0004",
    "capguy/walk/0005", "capguy/walk/0006",
    "capguy/walk/0007", "capguy/walk/0008"
]);

We just use the default animation here, which contains all defined frames. Of course it's also possible to define other animations using the addAnimation function.

If you start the demo now you'll see CapGuy walking... but he's not yet moving. Let's add the following code block to entity.js

/**
 * manage the enemy movement
 */
update : function (dt) {

    // just manually change the guy position
    this.pos.x += 0.3*dt;

    // repeat once leaving the viewport
    if (this.pos.x >= me.game.viewport.width) {
        this.pos.x = 0;
    }

    // call the parent function
    this._super(me.Entity, "update", [dt]);

    return true;
}

This will moves CapGuy a bit to the right. (dt is the time difference between the last frame and the current frame, and we use this here as a base for the update keeps the animation speed constant). The if block resets CapGuy to the left border after he left to the right.

And voila !

Source code

Full source code of this example is available in our repository at : https://github.com/melonjs/melonJS/tree/master/examples/texturepacker