Wednesday, December 2, 2015

Enemies That Do Something

I'm in the Dallas area for work again this week, but I took a few minutes to work on the 8-bit style platformer I'm making with Phaser. The task today: make the enemies do something!

Up until now, those toads I added to the game just sit there. You can bump into them and get hurt, but they just sit there. I wanted the game's enemies to be slightly more dynamic than that, so I decided to make them jump every so often. This was not quite as easy as making Science Frog (the game's hero sprite) jump, but it wasn't too bad.

First, remember that the toads are actually added to the map using the map editor, Tiled, and then converted to sprites by the createFromObjects function. That's great, but how do I perform special operations on them after they are created? I settled on the following code:

function create() {

    // ... other stuff ...

    enemies = game.add.group();
    enemies.enableBody = true;

    map.createFromObjects('others', 6571, 'toad', 0, true, false, enemies);

    enemies.forEach(function(t) {

        t.jumping = false;
        game.physics.enable(t, Phaser.Physics.ARCADE);
        t.body.setSize(60, 25, 0, 38);

        game.time.events.add(5000, function() {
            jumpToad(t);
        }, this);

    }, this);

    // ... other stuff ...

}

First the toads are created from the map. Using the forEach function on the Phaser Group object, I then call an anonymous function which performs the special setup operations. In this case, those are setting a jumping flag to false, enabling physics, setting a custom bounding-box size, and finally, setting a timer to make the toad jump.

The timer sets the toads to jump after 5 seconds by calling the jumpToad function. This function is very simple:

function jumpToad(t) {

    t.frame = 1;
    t.body.velocity.y = -600;
    t.jumping = true;

}

It changes the toad's frame to 1, which is a new picture I drew of the toad jumping. It sets the y-velocity to -600, which makes the toad leap into the air. Finally, it sets the jumping flag to true. This flag is needed in the update function...

function update() {

    // ... other stuff ...

    enemies.forEach(function(t) {

        if (t.body.onFloor() && t.jumping) {
            t.jumping = false;
            t.frame = 0;
            game.time.events.add(5000, function() {
                jumpToad(t);
            }, this);
        }

    }, this);

    // ... other stuff ..

}

Again using the forEach function on the enemies group, I check to see if the toads are currently on the ground but have their jumping flags set to true. If so, this indicates that they've jumped in the air and have already landed. When that happens, I set their frame back to 0 (the sitting frame), reset the jumping flag to false, and set the timer to make them jump in another 5 seconds.

That all worked fairly well, which you can see for yourself if you play the test version of the game here: http://amphibian.com/eight-bit/. You can also see the complete source code on GitHub. This method is not perfect, however. I need to address how to handle different types of enemies soon, as I will want to add more than just toads. But that is an issue for another day! For now, entertain yourself with today's Amphibian.com comic!

Amphibian.com comic for 2 December 2015