Navigation

Part 7 - Rotated Frames

<div class="warning-box"> <strong class="title">Phaser CE</strong> All code shown here requires <a href="https://github.com/photonstorm/phaser/tree/master/v2-community">Phaser CE</a>, version 2.7.0 or above. </div>

The last feature we're going to discuss is Rotated Texture Frames.

Some 3rd party tools like Texture Packer have the option to rotate the atlas frames, in order to save more space in the atlas, and perform more efficient frame packing.

If you haven't realized it by now, Texture Packer truly is one of the most indispensable tools you can buy to go with your game development. There hasn't been a single commercial HTML5 project I've worked on that didn't use it at some point. It pays for itself every single day. An no, I don't get any affiliate money from saying this, it's just a genuinely essential tool.

Enabling frame rotation

When starting Texture Packer be sure to pick either the JSON (Hash) or JSON (Array) formats, and not the Phaser format, or the option will be hidden from you.

Add all the sprites to your atlas as usual.

And if you look in the "Layout" panel on the right, you'll notice a checkbox next to "Allow rotation". If you tick this box then the atlas will adjust to include rotated frames, where it felt they would fit better with rotation.

image

In the screen shot above you can hopefully make-out that the green bitmap font is rotated, as are some of the bottom-left sprites, and the pacman and Sonic sprite sheets.

Export the atlas and load it into Phaser as normal. You need do nothing more, Phaser will read the atlas json, see that the frame is rotated, and then 'un-rotate' it just before rendering.

The Rotation Code

For a Sprite rendering in Canvas mode, the code that un-rotates the frame before rendering can be found in the file src/pixi/display/Sprite.js. For WebGL the code can be found in src/pixi/renderers/webgl/utils/WebGLSpriteBatch.js. Although it's a Phaser feature, it is part of the rendering process, so we added it to our Pixi build.

The methods _renderCanvas and render, for Canvas and WebGL respectively, contain the logic. At the time of writing this is:

if (this.texture.rotated)
{
    var a = wt.a;
    var b = wt.b;
    var c = wt.c;
    var d = wt.d;
    var e = cw;

    // Offset before rotating
    tx = wt.c * ch + tx;
    ty = wt.d * ch + ty;

    // Rotate matrix by 90 degrees
    // We use precalculated values for sine and cosine of rad(90)
    wt.a = a * 6.123233995736766e-17 + -c;
    wt.b = b * 6.123233995736766e-17 + -d;
    wt.c = a + c * 6.123233995736766e-17;
    wt.d = b + d * 6.123233995736766e-17;

    // Update cropping dimensions.
    cw = ch;
    ch = e;
}

It takes the world transform (wt), translates it, applies the rotation and sets the crop values rendering for the next stage of the rendering process.

The WebGL code has an extra step, in that it also updates and inverts the UV coordinates.

As you can see it involves a little extra math, beyond that which an un-rotated texture frame requires, so it's up to you to decide if your game will benefit from this.

The calculations have to be applied to the transform every time it renders. So it may be deemed 'too expensive' in some situations. If the Sprite never actually moves (i.e. is game UI or a backdrop), then you could bake the transform data in to avoid the calculations, but that is an exercise left for you and the wider Phaser CE community. All games are different, so it's entirely possible that a little trade off in terms of processing is worth it, to create a smaller base texture.