Drawing Graphics in Phaser (Part 3)

 

Lets explore how to take a create a sprite from a graphics object.

In the previous tutorial, we looked at creating primitives using Phaser’s Graphics class. Now, we’re goign to take one of those and generate a texture and apply it to a sprite.

Using the semi-circle from the previous tutorial, lets see how we create a texture from it. You can read up on the generate texture function from Phaser’s documentation


let graphics = this.game.make.graphics(0, 0);
graphics.lineStyle(1, 0xFFFFFF, 1);
graphics.arc(75, 75, 35, 0, Math.PI, false);
// creating the texture
let texture = graphics.generateTexture();

Now that we have a texture that we can manipulate how we like, we can simply use it by setting it as a sprites texture.


...
// creating the texture
let texture = graphics.generateTexture();
this.add.sprite(0, 0, texture);

To change a texture when your sprite has already been created, you can just simple change the texture property on the sprite.


let sprite = this.add.sprite(0, 0, 'my-asset');
let newTexture = graphics.generateTexture();
sprite.texture = newTexture;

Once the texture has been created and stored in memory, it is possible to use the ‘cache as bitmap’ function to help improve performance if it is a static sprite. I’ll go into more detail about this at a later date. It’s slightly outside of the scope for this tutorial.

Now we should look at making some more re-usable code for creating graphics and textures. Lets go ahead and create a function to draw some graphics and return a texture that we cna use.


drawHeart(ratio = 1) {
    let graphics = new Phaser.Graphics(250, 250);
    graphics.lineStyle(2, 0xFFFFFF, 1);
    graphics.moveTo(75 * ratio, 40 * ratio);
    graphics.bezierCurveTo(75 * ratio, 37 * ratio, 70 * ratio, 25 * ratio, 50 * ratio, 25 * ratio);
    graphics.bezierCurveTo(20 * ratio, 25 * ratio, 20 * ratio, 62.5 * ratio, 20 * ratio, 62.5 * ratio);
    graphics.bezierCurveTo(20 * ratio, 80 * ratio, 40 * ratio, 102 * ratio, 75 * ratio, 120 * ratio);
    graphics.bezierCurveTo(110 * ratio, 102 * ratio, 130 * ratio, 80 * ratio, 130 * ratio, 62.5 * ratio);
    graphics.bezierCurveTo(130  * ratio, 62.5 * ratio, 130 * ratio, 25 * ratio, 100 * ratio, 25 * ratio);
    graphics.bezierCurveTo(85 * ratio, 25 * ratio, 75 * ratio, 37 * ratio, 75 * ratio, 40 * ratio);

    return graphics.generateTexture();
}

Just as a bonus, I threw a ratio multiplier in there. If you are trying to generate graphics on a retina display, then it can be worth drawing it twice the size and shrinking it down to normal size. This is how you deal with high DPR screens. I’ll do a full tutorial on this as soon as I can.

Calling the function is easy and can even be done in a one liner.


let texture = this.drawHeart();
let sprite = this.add.sprite(100, 100, texture);
// one liner
let sprite = this.add.sprite(100, 100, this.drawHeart());

We can also create a class and add it to our utils so we don’t need to include these functions everywhere in our code.


export default class graphics {
    static heart(ratio = 1) {
    let graphics = new Phaser.Graphics(250, 250);
    graphics.lineStyle(2, 0xFFFFFF, 1);
    graphics.moveTo(75 * ratio, 40 * ratio);
    graphics.bezierCurveTo(75 * ratio, 37 * ratio, 70 * ratio, 25 * ratio, 50 * ratio, 25 * ratio);
    graphics.bezierCurveTo(20 * ratio, 25 * ratio, 20 * ratio, 62.5 * ratio, 20 * ratio, 62.5 * ratio);
    graphics.bezierCurveTo(20 * ratio, 80 * ratio, 40 * ratio, 102 * ratio, 75 * ratio, 120 * ratio);
    graphics.bezierCurveTo(110 * ratio, 102 * ratio, 130 * ratio, 80 * ratio, 130 * ratio, 62.5 * ratio);
    graphics.bezierCurveTo(130  * ratio, 62.5 * ratio, 130 * ratio, 25 * ratio, 100 * ratio, 25 * ratio);
    graphics.bezierCurveTo(85 * ratio, 25 * ratio, 75 * ratio, 37 * ratio, 75 * ratio, 40 * ratio);

       return graphics.generateTexture();
    }
}

// in boot state
import graphics from './../utils/graphics/;

export default class BootState extends Phaser.State {
    create {
        this.game.utils.graphics = graphics;
    }
}

// in game state
export default class Gamestate extends Phaser.State {
    create {
        this.add.sprite(0, 0, this.game.utils.graphics.heart());
    }
}

Twitter

Error code 89: Invalid or expired token.

Stay Updated