Wednesday, December 30, 2015

This is Why I Love Phaser

One of my stated goals when I started the Amphibian.com web comic was to include interactive experiences directly in the comics. My idea is that this kind of thing takes web comics more towards the web. It uses more of the browser as a medium. It's the next level of comics.

That means every so often, when the joke calls for it, I include some interactive or dynamic content in the comics. Today's comic has a game embedded in the third frame.

And that's why I love Phaser.

I had to take a break from working on my platformer to make today's hedge maze game, but thanks to Phaser it didn't take all that long. I only wrote somewhere around 150 lines of code and I have a small game playable in a desktop browser. When I first tried Phaser (making my 404 page game) I was a little skeptical. I am very careful about which frameworks I use for any of my projects, but at this point I am totally sold on Phaser as an HTML5 game development framework. It just saves me so much time. The way it works makes sense, and it performs very well. Prior "games" that I've put in the comics have taken a lot more time to develop and done a lot less than this hedge maze one today. Expect to see more like this in the future.

I don't mention it often anymore, but the entire source code for Amphibian.com is on GitHub, and that includes the JavaScript for the hedge maze game. Check it out here and use it to start making your own games!

Amphibian.com comic for 30 December 2015

Monday, December 28, 2015

More Levels, Fewer States

A New Level
Last week when I added a second level to my platformer, I used multiple Phaser State objects. I had one for each level plus one for the "select a level" mode. While this worked, I wasn't particularly happy with it because every one of the level's State object was identical. It seemed to me that there should have been a better way.

As is often the case with me, I work on these games late at night and usually only for an hour or so, and I don't think of what is later the obvious solution until I've been away from it for a while. Over the weekend, I came to the conclusion that I should only be using a single State for all the different levels and merely changing which map gets loaded by other means.

Here are those other means... First, I created some simple objects which contain the map and music asset keys for each level. I put them all in a map inside an object I called gameState. This is different from a Phaser State object - I use it to keep track of my own personal state information. So far, that means which map is being played and what background music to use. I pass this gameState object to the constructors for both the stage select and the playable stage.

var sandboxLevel = {
        map: "LevelSandbox",
        music: "Ouroboros"
};

var levelOne = {
        map: "Level1",
        music: "DangerStorm"
};

var gameState = {
        levels: [],
        currentLevel: "sb"
};

gameState.levels["sb"] = sandboxLevel;
gameState.levels["one"] = levelOne;

var theStage = stage(gameState);
var stageSelectState = selectStage(gameState);

var game = new Phaser.Game(width, height, Phaser.CANVAS, "gameArea");

game.state.add("stageSelect", stageSelectState, true);
game.state.add("level", theStage);

As you can see in my code snippets above, I now only have to add two States to the Game. Inside the update function for the stage select state, I simply manipulate my gameState object before switching the Phaser State to the playable level.

function update() {

    if (keys.s.isDown) {
        // sandbox level is selected...
        gameState.currentLevel = "sb";
        this.state.start("level");
    } else if (keys.o.isDown) {
        // level one is selected...
        gameState.currentLevel = "one";
     this.state.start("level");
    }

}

Once a new State is started, the create function gets called on it. In my create function, I use the gameState object to get the current level's map and background music.

function create() {

    mapKey = gameState.levels[gameState.currentLevel].map;
    musicKey = gameState.levels[gameState.currentLevel].music;

    // ... other stuff ...

    var map = this.add.tilemap(mapKey);
    var bgmusic = this.sound.add(musicKey);

    // ... other stuff ...

}

That's it. I like this much better than that first attempt. It should be trivial now to add as many stages as I want. I really only want 8. But anyway...

You can play the game at http://amphibian.com/eight-bit and you can view the complete source code on GitHub. Take a look at today's comic before you go. I brought back Science Frog doing tech support for the other frogs, because it's funny.

Amphibian.com comic for 28 December 2015

Friday, December 25, 2015

Merry Christmas!

This will be a short post today, and contain no significant content. I figure everyone will probably be doing something more important that reading my blog today, Christmas 2015.

Anyway, I hope you read and enjoyed my Amphibian.com version of A Christmas Carol. In the end, today's comic, the CEO frog decides to never give thoughtless gifts again. I feel like it's an important lesson for all of us today. But I was surprised to learn that it was an important lesson for us 100 years ago - a lesson that NO ONE LEARNED!

That's right, over a hundred years ago Eleanor Robson Belmont started the organization known as SPUG - the Society for the Prevention of Useless Giving. It was a response to what was seen as wasteful spending on gifts for the sake of gifts at Christmastime. Sound familiar? I guess some things never change. SPUG got a lot of attention back in the second decade of the twentieth century, but the outbreak of World War I took the focus off of revolutionizing the way Christmas was celebrated. The Society doesn't officially exist anymore.

Maybe it's time for a comeback?

In any event, have yourself a Merry Christmas. I'll post again on Monday with some more progress on my platformer and we'll all play it and be joyous as we await the start of 2016.

Amphibian.com comic for 25 December 2015

Wednesday, December 23, 2015

Adding More Stages to my Phaser Platformer

Last week I started getting my platformer set up to have more than just one stage. I created some State objects, one for the title screen and one for the sandbox stage. Today I wanted to continue that process by adding a second playable stage.

Let's call this new stage Stage 1. I think I'm going to number the stages by the bit positions, so we'll have Stage 1 (1), Stage 2 (10), Stage 4 (100), etc. For now, I'm going to leave the sandbox stage in there as Stage 0.

Because of the groundwork I laid over this past weekend, adding the additional stage was easy. If you remember, I created a playingState function which returned a Phaser State object representing the playable stage. Today, I modified that function and renamed it to stage. It now takes a single numeric argument and uses that to select which map and music will be loaded.

Here is a simplified example of my code:

function stage(n) {

    var thisLevel = n;

    // ... other variable declarations

    function preload() {
        this.load.pack("main", "assets/pack.json");
    }

    function create() {

        // load the map for thisLevel
        map = this.add.tilemap("stage" + thisLevel);

        // load the music for thisLevel
        bgmusic = this.sound.add("bgmusic" + thisLevel);

        // ... all the other stuff ...

    }

    // ... all the other functions ...

    return {
        preload: preload,
        create: create,
        update: update
    };

}

For the above code to work as expected, I had to add more game assets to my pack.json file. I now have two tilesets with keys stage0 and stage1, and two audio types with keys bgmusic0 and bgmusic1. Adding more stages is as simple as adding more tilesets and music to the asset pack.

In the game setup, I simply call stage twice. The first time to create the State object for the sandbox and the second time to create the State object for stage 1.

var stageSelectState = selectStage();

var sandboxStage = stage(0);
var stageOne     = stage(1);

var game = new Phaser.Game(width, height, Phaser.CANVAS, "gameArea",
  stageSelectState);

game.state.add("sandbox", sandboxStage);
game.state.add("one", stageOne);

While this works and was fairly simple, it bothers me a little bit. Since 99% of the stage is exactly the same (the only behavior that differs based on the input parameter is in the create function) I really hate calling the stage function more than once, each time creating a functionally identical closure. I think I'm going to optimize this a little more. Stay tuned.

As I've mentioned before, you can play the in-progress game at https://amphibian.com/eight-bit and you can check out the complete source code on GitHub. Leave a comment with any feedback, and don't forget to read today's comic. It's part 4 of my Christmas story and includes the third and final goat!

Amphibian.com comic for 23 December 2015

Monday, December 21, 2015

The Gift of No Gift

Merry Christmas!

I hope everyone is looking forward to Christmas this Friday for all the right reasons. It's gotten difficult to teach my children that Christmas isn't about providing a list of expensive items that will be purchased for them in exchange for good behavior. The Santa-Industrial Complex is working hard to convince us all that we need to buy stuff for everyone we love this time of year.

The series of comics I'm running right now at Amphibian.com is my attempt to poke fun at this modern tradition. Last week, the Goat of Christmas Past reminded the CEO frog that no matter how good presents might seem, they don't last. Odds are, you don't currently have many (if any at all) gifts you were given as a child that are still valuable to you today. In today's comic, the Goat of Christmas Present shows the frog that too many people are giving gifts that aren't really needed. How many coffee mugs do you really use?

Please don't think I'm some kind of villain worthy of mention in a Dickens story. I don't hate the giving of gifts on Christmas. I am just suggesting that as a society we should take a closer look at our motivations. Why do we go crazy and spend $59 bazillion between Thanksgiving and Christmas each year? Is it because we've all lost the ability to show our love for each other without enlisting the help of Wal-Mart and Target?

There is an aspect of the gift-giving craze that I suspect few people stop to consider. Many people don't feel loved when they are receiving gifts. At least that's what Gary Chapman wrote in his book about the Five Love Languages. While there seems to have been little research done to confirm his theories, I've read it and it does seems to fit extremely well with my experiences. Some people feel love by receiving gifts. But a bunch of other people don't, or at least not as much. So if our goal at Christmas is really to show our love for each other, shouldn't we desire to do that in the way the recipient will most feel love? There's a good chance that won't be a gift.

But if we're really just buying gifts because advertising agencies have fooled us into believing that we need to in order to conform to the Christmas rules, maybe we should stop.

Just something to think about.

Amphibian.com comic for 21 December 2015

Friday, December 18, 2015

Using Game States in Phaser

The game's (temporary) Title Screen
If you've tried playing the sandbox level for the 8-bit style platformer I've been building with Phaser, you have seen that it just drops you right into the stage. There's no splash screen or level selector or how-to-play instructions. It's just *BAM* do something! Today I decided to change that.

Making different types of screens with Phaser means working with different States. What is a State? In its simplest form, a State is just a set of functions - preload, create, update, and (optionally) render. When you first switch to a State, preload and create are called. Then update is called continuously until you do something to change the State. If you create a very simple game (like mine has been so far) you might only have one State and you might not even call it that - you can just pass in an anonymous State object when you create the game!

Here's what I mean... Look at this example of what my code was like before:

function preload() {
    // ... do preload stuff ...
}

function create() {
    // ... do create stuff ...
}

function update() {
    // ... do update stuff ...
}

// ... define a bunch of other functions and variables ...

var game = new Phaser.Game(width, height, Phaser.CANVAS, "gameArea", {
    preload: preload,
    create: create,
    update: update
});

Basically, I was creating a State object inline with the call to the Game constructor. It was a simple object that defined the 4 functions I mentioned previously. As soon as the Game was created, this State started running. It's possible to create multiple States using different combinations of globally-defined functions, like the code above, but that would get ugly fast. I know this isn't exactly OO, but I still want to practice good encapsulation. I want separation of concerns.

What did I do? I created two functions which generate the two different states! One for the simple title screen and one for the game as it has been up to this point. The title screen state just shows a single image and waits for the player to push the 'S' key. Once pushed, the update function in the title state changes the game state to the playable sandbox state.

Here's a much simplified version of the code:

/**
 * Creates the game state which defines the title screen.
 */
function titleState() {

    var keys;
    var splash;
    
    function preload() {
        this.load.pack("main", "assets/titlePack.json");
    }
    
    function create() {
        splash = this.add.image(0, 0, "title");
        keys = this.input.keyboard.addKeys({
            's'  : Phaser.KeyCode.S
        });
    }
    
    function update() {
        if (keys.s.isDown) {
            this.state.start("sandbox");
        }
    }
    
    return {
        preload: preload,
        create: create,
        update: update
    };
    
}

/**
 * Creates the game state which defines the playable level.
 */
function playingState() {

    // ... define private variables ...
    
    function preload() {
        this.load.pack("main", "assets/pack.json");
    }
    
    function create() {
        // ... all the game creation stuff ...
    }
    
    function update() {
        // ... all the game update stuff ...
    }
    
    return {
        preload: preload,
        create: create,
        update: update
    };
    
}

// Now we create the states and the game

var title = titleState();
var sandbox = playingState();

var game = new Phaser.Game(width, height, Phaser.CANVAS, "gameArea", title);

game.state.add("sandbox", sandbox);

The "main" game setup is much simpler now - it just creates the state objects and then the Game. The game starts with title as the running state, but adds the sandbox state with the key "sandbox." The key is important because that's what you have to use when you want to switch states.

The other thing to note is that in the State preload, create, and update functions, the this variable will refer to the Game object. That fact becomes important when you are creating in-game objects in these functions.

Check out the game with its fancy new title screen here: http://amphibian.com/eight-bit/, and visit the project page on GitHub if you'd like to see the complete source code. Over at Amphibian.com, today is Chapter 2 of my Christmas story - give it a quick read!

Amphibian.com comic for 18 December 2015

Wednesday, December 16, 2015

Let's Add More Weapons to my Phaser Platformer

After adding the health meter earlier this week, the playable sandbox level for my platformer built with Phaser was looking much more complete. There are just a few more things I need to add before I switch my focus to level design and make a legitimate game out of it. One of those things is more weapons.

My plan for the game is to make it similar to a classic 8-bit Mega Man game. In those, after defeating one of the bosses, Mega Man could use the weapon from that boss. To make that happen in my game, I'd have to expand the weapons capability. I needed to add the ability to switch to different weapons that each had different qualities.

To begin, I defined an array of weapon objects. Each object would have its own name, velocity attributes, and power to damage enemies. For each of these weapon types, I will create a Phaser Group to manage them. All the weapon groups will be added as children of an overall weapons group. Look at this code from my create function:

function create() {

    // ... other stuff ...

    weaponsGroup = game.add.group();
    weapons = [];
    weapons.push({
       name: 'pencil',
       lifespan: 1500,
       velocity: {
           x: 500,
           y: -400
       },
       spin: 50,
       power: 10
    });

    weapons.push({
        name: 'flask',
        lifespan: 1500,
        velocity: {
            x: 600,
            y: -600
        },
        spin: 50,
        power: 20
     });

    weapons.push({
        name: 'hammer',
        lifespan: 1500,
        velocity: {
            x: 600,
            y: -400
        },
        spin: 50,
        power: 30
     });

    weapons.push({
        name: 'brace',
        lifespan: 1500,
        velocity: {
            x: 800,
            y: -200
        },
        spin: 80,
        power: 40
     });

    for (var w = 0; w < weapons.length; w++) {
        var wg = game.add.group();
        wg.createMultiple(3, weapons[w].name, 0, false);
        weapons[w].sprites = wg;
        weaponsGroup.add(wg);
    }

    // ... other stuff ...

}

The overall group, weaponsGroup, is created first. Then I set up an array of 4 weapon types. The name is important because I have it set up to match the sprite asset key for that weapon. I then loop over the weapons array and create a group just for a set of those weapons. I set that group as the sprites field on the weapon object - I'll need to reference it later. Also, those groups are added as children of the weaponsGroup.

At this point I have a group of weapons groups. Any of these can be use to strike an enemy, so they must be checked for enemy collisions. A slight change in my update function takes care of that. The overlap function can take an array of groups in addition to a single group, and the children field of a Group object is the array of child groups!

function update() {

    // ... other collision checks ...

    game.physics.arcade.overlap(enemies, weaponsGroup.children, hurtEnemy, null, this);

    // ... other stuff ...

}

Okay, so how do I have the frog throw a particular type of weapon? First, I added a variable to the game called weaponIndex. It is set to the index of whatever weapon is currently active. So far, I have 4 weapons which means that the index can be 0, 1, 2, or 3. Then in my throwSomething function, I get the weapon object out of the weapons array using the index and use its properties to perform the toss.

function throwSomething() {

    // has it been long enough? can we throw something yet?
    if (game.time.now > nextFire) {

        nextFire = game.time.now + FIRE_RATE;

        // see if a weapon is available from the group
        var weapon = weapons[weaponIndex].sprites.getFirstExists(false);
        if (weapon) {

            weapon.exists = true;
            weapon.anchor.setTo(0.5, 0.5);
            weapon.reset(frog.body.position.x+20, frog.body.position.y-20);
            game.physics.arcade.enable(weapon);

            weapon.lifespan = weapons[weaponIndex].lifespan;
            weapon.body.angularVelocity = weapons[weaponIndex].spin;
            weapon.body.velocity.y = weapons[weaponIndex].velocity.y;
            weapon.power = weapons[weaponIndex].power;
            if (frog.scale.x == 1) {
                weapon.body.velocity.x = weapons[weaponIndex].velocity.x;
            } else{
                weapon.body.velocity.x = -weapons[weaponIndex].velocity.x;
            }
            
        }

    }

}

This code is very similar to what I had before, when the only weapon was the pencil. The differences are that the sprite, lifespan, velocity, and power are pulled from the weapon object in the weapons array instead of always being hard-coded to the same values.

One final change was to the function that handles hurting the enemies when there is a collision between a weapon and an enemy. Previously, I used a fixed damage value for the enemy. Now, the damage to the enemy is based on the power field of the particular weapon that is hitting it. For example, it takes 4 hits with a pencil to kill a toad but only 1 hit from a curly brace.

function hurtEnemy(e, w) {

    if (!e.immune) {
        e.immune = true;
        e.alpha = 0.5;

        // damage to enemy = power of weapon
        e.damage(w.power);

        w.exists = false;

        game.time.events.add(200, function() {
            e.immune = false;
            e.alpha = 1;
        }, this);
    }

}

The hurtEnemy function is what gets called when overlap is detected between a sprite in the enemies group and a sprite in one of the weapons groups. The first parameter e will be the enemy object and the second parameter w will be the weapon that hit it. Since my throwSomething function set the power field on the weapon sprite to match the power field on the weapon definition, I can read that property here to control the amount of damage to the enemy.

Want to give it a try for yourself? Play the game here: http://amphibian.com/eight-bit/. Just hit 1 through 4 on the keyboard to switch between the different weapons. If you'd like to see the complete source code, it's on GitHub.

As for comics today, this is the first of a 5-part Christmas story. It roughly follows the pattern of Dicken's A Christmas Carol, but...well, you'll see. They're a bit longer than the normal ones, but don't take too much longer to read. I hope you enjoy them!

Amphibian.com comic for 16 December 2015

Monday, December 14, 2015

Putting a Health Meter in my Phaser Game

As some of you may have noticed, I haven't been making much progress on my 8-bit style platformer lately. A business trip to Texas, Christmas decorating, kids' school Christmas programs, and some minor surgery took away all of my spare time. This kind of thing happens sometimes (well, except for the surgery part - that was the first surgery I've ever had) and I don't mind at all. Getting ready for Christmas and hearing my children sing at school will always be more important than making games with Phaser.

But that surgery thing...I can certainly do without that. I'd much rather makes games with Phaser.

However, since all that stuff is done and I am sitting here recovering from the surgery, I might as well work on my game some more! Today I added the frog's health meter to the screen.

The health meter (or life bar, health bar, or whatever you like to call it) has been missing from the game so far. The frog could take a certain amount of damage but you could never tell just how much more he could take. I wanted to add a simple bar-of-color health meter to the screen so players could get some idea of how close they were to a Game-Over.

I ended up doing this by drawing colored rectangles in the game. It wasn't too difficult, but was a little different than putting image-based sprites on the screen. I had to create some Bitmap Data.

The Health Meter, showing that this frog has taken a little damage.

What exactly is Bitmap Data in Phaser? The Phaser.BitmapData object gives you the ability to draw graphics much like you would in a traditional HTML5 Canvas. You can think of it as lower-level access to the graphics, but you can also think of it as an alternative source of a Sprite's image. Instead of PNG image data, you could manually create an image using BitmapData.

Here's what I mean:
function createHealthBar() {

    meters = game.add.group();

    // create a plain black rectangle to use as the background of a health meter
    var meterBackgroundBitmap = game.add.bitmapData(20, 100);
    meterBackgroundBitmap.ctx.beginPath();
    meterBackgroundBitmap.ctx.rect(0, 0, meterBackgroundBitmap.width, meterBackgroundBitmap.height);
    meterBackgroundBitmap.ctx.fillStyle = '#000000';
    meterBackgroundBitmap.ctx.fill();

    // create a Sprite using the background bitmap data
    var healthMeterBG = game.add.sprite(10, 10, meterBackgroundBitmap);
    healthMeterBG.fixedToCamera = true;
    meters.add(healthMeterBG);

    // create a red rectangle to use as the health meter itself
    var healthBitmap = game.add.bitmapData(12, 92);
    healthBitmap.ctx.beginPath();
    healthBitmap.ctx.rect(0, 0, healthBitmap.width, healthBitmap.height);
    healthBitmap.ctx.fillStyle = '#FF0000';
    healthBitmap.ctx.fill();

    // create the health Sprite using the red rectangle bitmap data
    health = game.add.sprite(14, 14, healthBitmap);
    meters.add(health);
    health.fixedToCamera = true;

}

In this function, I create the health meter. It is essentially a black rectangle with a slightly smaller red rectangle inside of it. The size of the red rectangle will shrink as the frog's health decreases. First, I create a Phaser Group for these meters, then I create the bitmap data that will be used for the back of the meter. The call to game.add.bitmapData(20, 100) creates a BitmapData object 20 pixels wide and 100 pixels tall. The next 4 lines draw a filled rectangle which takes up the entire size of the bitmap. These lines are pretty much the same as you would use if you were working directly with the HTML5 Canvas context. After creating that bitmap, I create a Sprite using it as the key. If you were creating a sprite with an image file, this parameter would be the name of the image's key in the set of game assets - but here I can use the bitmap data directly instead. I now have a black rectangular health meter background sprite that I can fix to the camera and add to the meters group.

The next block of code does basically the same thing, but for a slightly smaller rectangle with red fill. I called this Sprite health because it represents the health of the frog, and it will be updated throughout the game.

Now take a look at just how the update occurs. In my game's main update function, I call the following function, updateHealthBar.

function updateHealthBar() {

    var m = (100 - frog.health) / 100;
    var bh = 92 - (92 * m);
    var offset = 92 - bh;

    health.key.context.clearRect(0, 0, health.width, health.height);
    health.key.context.fillRect(0, offset, 12, bh);
    health.key.dirty = true;

}

The first 3 lines just do some simple calculations to determine how tall the health meter should be and a vertical offset for it (so it looks like the bottom is 0 instead of the top). Then it gets weird. I have to access the key of my health sprite in order to get the reference to the bitmap data object. Once I have that, I can once again do some rectangle clearing and drawing commands directly on the bitmap's context. This is low-level, like drawing directly to the Canvas. But it works perfectly, and the health meter displays and functions properly in the game.

Remember, you can view the complete source code for the game on GitHub, and you can play the latest version here: http://amphibian.com/eight-bit/. And as always, don't forget to take a look at the latest comic! It's almost Christmas!

Amphibian.com comic for 14 December 2015

Friday, December 11, 2015

Residual Traffic from my Ad

Remember about a month ago when my ad for Amphibian.com finished its run on TopWebcomics.com? I wrote about how I was tracking its effectiveness using a special URL and a cookie:
Tracking Visitors from Ads with Express Middleware
Today I was curious just how many comics are still being viewed because of the ad almost a month later. I ran my database queries again and found that over the past 3 weeks (all outside of the ad's run) there have been 183 visits to the main page of Amphibian.com by people who have the cookie.

While not an astounding number, I'm still pleased with it. It means there are quite a number of new people coming to read the comics that would not be had I not run the ad.

In related news, I'm having a lot of trouble staying in the top 100 this month. Voting is fierce in December, I suppose. I could use a few more votes if you have a second. Just click here.

Remember to take a look at today's comic, even if you never clicked on the ad or visited TopWebcomics.com. It doesn't matter to me why you look at them. Just do it!

Amphibian.com comic for 11 December 2015

Wednesday, December 9, 2015

Christmas Decorations

Like the frogs of Amphibian.com, I have also been decorating for Christmas. My family's Christmas tree is adorned with ornaments collected over the years that have a special meaning to us.

This first one actually opens up. It originally had the engagement ring I gave to my future wife back on December 21st, 2001. Inside it today is still a little bit of the wrapping paper from the box.


We picked up this Union Jack ornament on one of our trips to the United Kingdom back before we had children.


I love this Pac Man arcade machine ornament. It plays the music from the game if you push the buttons. We got this back when I was buying classic arcade machines.


I picked up this rustic squirrel ornament on clearance at a Meijer store in central Ohio after Christmas. We used to travel there in January every year to celebrate post-Christmas with my mother's family. It reminds me of those trips.


I got this Octocat ornament from GitHub earlier this year with my winnings from the GitHub Game Off 2015. I've been waiting 9 months to hang this thing up!


There are so many more on the tree; I can't show pictures of them all. But they all have a story. Here's the big picture (the whole tree):


And let's not forget about my outdoor decorations...


That's all I have to share today. I know, two posts in a row with no code to share. It's a busy time of year. The frogs have been busy as well, so be sure to check out all their decorating work in today's comic.

Amphibian.com comic for 9 December 2015

Monday, December 7, 2015

More Froggy Pictures from Texas

I'm back home from another week in Texas! Since I've basically done nothing but cut down a Christmas tree and hang up some lights since Friday, there's no software-related material to share today. Instead, how about some more pictures of my daughter's stuffed frog who accompanied me on my trip?

This past week was Froggy's 5th trip to the Dallas area.

Froggy gets a snack in the Philadelphia
airport while we wait on our plane.
We split a sandwich for dinner the first night.
Who photo-bombed who?
Froggy gets more sleep than I do on these trips.
Cooking dinner in the hotel room.
Froggy only knows how to make macaroni and cheese.
We found this nice fountain while walking around one evening.
And we found this weird statue.
It's outside the State Farm Operations Center.
Froggy also likes soup.
Froggy took his pets for a walk.
They are a giraffe, a cow, and a stegosaurus.
We had to get up really early to get our flight home.
Froggy slept at the airport.
I apologize if you actually follow this blog and were expecting more substance today. Sometimes, this is my life. My daughters all enjoy these pictures that I send home. The people who watch me take them probably think I'm some sort of weirdo. They're correct, of course.

On a completely unrelated topic, I'm starting the Christmas-themed comics this week! Be sure to read today's:

Amphibian.com comic for 7 December 2015

Friday, December 4, 2015

Better Encapsulation of Enemy Logic

Remember on Wednesday when I wrote about adding some actual behavior to the enemies in the platformer I'm making with Phaser? I said that it bothered me how the code which defined the toad jumping behavior was applied to everything in the enemies group. It prohibited me from adding different kinds of enemies. I couldn't stop thinking about it, and came up with a solution.

What I needed was better encapsulation of the enemy logic. Instead of the update function having to know how to deal with all different types of enemies, the enemies should know how to deal with themselves. I shouldn't need a jumpToad function global to my game - I should just need to add a jump function to the toad objects. Not all enemies will jump...but all enemies will be updated. The answer: make sure all enemies are given an update function that does whatever makes sense for that enemy. With Phaser, the game loop automatically calls update (if defined) on all Sprite objects. So I have to do is to add enemy update functions and everybody takes care of themselves.

Let's take a look at it. First, I added the setupToad function that will take a Phaser Sprite object and add in the toad-specific functions. This must include update, but can be whatever else is needed - private variables, other functions, etc. If I add another type of enemy, let's say moles, I would add a setupMole function that gives Sprites mole-specific stuff.

function setupToad(obj) {

    game.physics.enable(obj, Phaser.Physics.ARCADE);
    obj.body.setSize(60, 25, 0, 38);

    obj.jumping = true;

    obj.jump = function() {
        this.frame = 1;
        this.body.velocity.y = -600;
        this.jumping = true;
    };

    // will be called by Phaser with each 
    // game loop update
    obj.update = function() {

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

    };

}

As you can see above, I give toad objects an update function, as well as a jump function. I also give them a jumping flag. The update function uses that flag and other Phaser functions to call jump under certain conditions. All this code was spread around before, but now it is all contained right here.

The process of creating toads looks much simpler:

function create() {

    // ... other stuff ...

    var toads = game.add.group();
    map.createFromObjects('others', 6571, 'toad', 0, true, false, toads);

    toads.forEach(function(t) {
        setupToad(t);
    }, this);

    enemies.addMultiple(toads);

    // ... other stuff ...

}

The best part is that I can create more types of enemies and the update function won't change at all. The game plays exactly the same as it did before, which you can prove to yourself by playing it here: http://amphibian.com/eight-bit/. You can also view the complete source code on GitHub.

Also, you should look at today's comic.

Amphibian.com comic for 4 December 2015

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

Monday, November 30, 2015

Adding Emoji to a Web Page

I've decided that emoji are the 21st century version of cave wall drawings. What ever happened to using words?
I draw frog pictures online.
Emoji set designed and offered free by Emoji One
Anyway, I wanted to do a comic where the frogs talked to each other using emoji, but I quickly encountered several problems. The native emoji on Windows look terrible, and are incomplete. And knowing exactly what my mobile users would see was impossible due to inconsistencies between the different phone emoji sets. Additionally, I would have to make some code changes to Amphibian.com's editor because it destroys the extended Unicode character values that are required to write in emoji. As it turns out, emoji on the desktop web is a legitimate problem.

But there is a solution! I found Emoji One, open-source emoji engineered for the web. This is a great project that made adding emoji support to Amphibian.com extremely simple.

First, they provide their JavaScript and CSS files via CDN, so I didn't have to really install anything directly into my web application. Just a few lines of code into my header template...

<script
  src="//cdn.jsdelivr.net/emojione/1.5.2/lib/js/emojione.min.js">
</script>

<link rel="stylesheet"
  href="//cdn.jsdelivr.net/emojione/1.5.2/assets/css/emojione.min.css"
/>

Once that was done, I had a few options. They provide functions for converting both Unicode and shorthand (such as :frog:) into pictures. I decided to go with the shorthand version for my site, mainly because it allowed me to more easily write the comics from my desktop browser (Chrome on Windows).

When I write some lines for a frog's speech bubble, I can type

:pizza: + :bowling: @ :clock730: :question:

which is then converted to emoji when the page loads. It's not 100% automatic, though. I had to add a few lines of JavaScript to my site but it was really simple.

// Emojis! (See http://emojione.com/developers)
$(function() {

    $('.bubble, .free-text').each(function() {
        var origText = $(this).html();
        var eText = emojione.shortnameToImage(origText);
        $(this).html(eText);
    });

});

The above code relies on jQuery, which I use on my site. As soon as the page is done loading, it finds every element on the page that has a class of bubble or free-text (the classes I use for speech bubbles and floating text areas) and converts the contents to include emoji images. It happens fast enough that I haven't been able to catch the shorthand text in there, but there could theoretically be some flicker. If I was more serious about this I could do the conversion on the server side instead...but this is just for a comic about frogs.

Make sure you read today's emojinal comic so that you can appreciate all the work I had to do for it. I'm not sure if I'll use emojis in the future, but you never know...

Amphibian.com comic for 30 November 2015

Friday, November 27, 2015

More Features for your Jade Templates

If you've seen Amphibian.com today you might notice the Christmas lights hanging from the header. I wanted to decorate the site a little, but I was worried that I might forget to take them down at the end of December. I think I left the lights up on my house until March last year. It was really cold and I didn't want to go outside.


To prevent this from happening to my website, I decided to add some code which will check the date and automatically display the lights only during the Christmas season. Since the HTML for Amphibian.com is generated by the Jade template system and Express, conditionally including some lights could be accomplished by putting a date check in the template for the comic page. The problem? The check for the Christmas season is a little more complicated than I cared to cram into a Jade template. And Jade/Express doesn't provide any utility libraries by default that help in this situation.

Fortunately, it's rather simple to add your own modules that can be used in your templates.

First, I made a holiday module that I can use to determine if we are currently in the Christmas season.

module.exports = function() {

    return {

        /*
         * Returns a Date object that represents Thanksgiving (US)
         * for this year. The fourth Thursday in November.
         */
        thanksgiving: function() {

            var d = new Date();

            d.setDate(1);
            d.setMonth(10);

            while (d.getDay() != 4) {
                d.setDate(d.getDate()+1);
            }

            d.setDate(d.getDate()+21);

            return d;

        },

        /*
         * This function returns true during the Christmas season.
         * I define that as Thanksgiving through the end of December.
         */
        isChristmasSeason: function() {

            var monthToday = (new Date()).getMonth();
            var dateToday = (new Date()).getDate();

            return (monthToday == 11 || (monthToday == 10 && dateToday >= this.thanksgiving().getDate()));

        }

    };

};

This is a standard Node module that exports an object containing two functions. One returns a Date object for Thanksgiving in the current year. In the United States, Thanksgiving is the 4th Thursday in November, so the function finds the first Thursday and then adds 3 weeks. The second function returns true if the current date falls within the Christmas season. I have personally defined that as Thanksgiving (hence the need for the first function) through the end of December.

Now to enable this module in Jade templates, you just need to add it to the locals object in the Express app. Here's an example of how to do that with this particular module:

var express = require('express');

var app = express();

app.locals.holiday = require('./holiday')();

Any fields on the locals object are available in Jade templates. In my comic page template, I can now do do this:

doctype html
html
 include head
 body
  include header
  if holiday.isChristmasSeason()
   include holidayHeader
  div#comicArea
   include comic
  include footer
  include js

The holiday object can be used anywhere it's legal to use JavaScript expressions in the template. I use it in the if block to see if I need to include the special holiday header.

You can use this technique to add whatever module you want to locals and then use them inside your templates. While Jade is not perfect, this capability adds a lot of flexibility to the framework.

Please continue to enjoy this Christmas season by viewing today's comic, which is, appropriately, about the Christmas season.

Amphibian.com comic for 27 November 2015

Wednesday, November 25, 2015

Small But Important Game Update

Today I took a break from adding any more serious capabilities to my Phaser platformer so that I could focus on a small but important change - the Science Frog images!

I said from the beginning that this was supposed to be a Science Frog game, but so far Science Frog has not been seen. That's because I re-used the frog spritesheet from the soccer game just so I could get stuff working in the code. Drawing the images always takes me a while and I prefer to get the coding first. At some point, though, I have to stop and fix the images.

I did sneak in a few minor code tweaks along with the new images. First of all, I am using half as many images as I was before. I only have pictures of Science Frog facing right. Instead of switching to a reverse animation sequence when he turns around, I am flipping the sprite by setting the scale.x value to be -1 or 1 depending on which direction he is facing.

frog.anchor.setTo(0.5, 0);

// normal direction for the sprites
frog.scale.x = 1;

// reverse direction for the sprites
frog.scale.x = -1;

The important thing here is that for the scale flip to work, the anchor of the sprite has to be 0.5 on the x-axis. Otherwise, the image gets drawn someplace you don't expect!

The other change is to use stop the animation and use only a certain frame when Science Frog is jumping or falling. This stops the effect of him flailing his arms and legs if you hold the arrow keys down while jumping. That just looked weird. For that, I just check to see if the y-velocity is non-zero and then set the sprite's frame accordingly.

function setAnimation(f) {

    if (f.body.velocity.y === 0) {

        // frog is on the ground

        if (f.body.velocity.x === 0) {

            // no animation, the frog is still
            f.animations.stop(null, true);

        } else {

            if (f.body.velocity.x > 0) {
                f.scale.x = 1;
            } else if (f.body.velocity.x < 0) {
                f.scale.x = -1;
            }
            f.animations.play("run");

        }

    } else {  // frog is jumping up or falling down

        // no animation, use a fixed frame
        f.animations.stop(null, true);
        
        if (f.body.velocity.y < 0) {
            f.frame = 1;
        } else if (f.body.velocity.y > 0) {
            f.frame = 2;
        }

    }

}

That's all for today! Remember, you can play the game here, and view the complete source code on GitHub. Have a Happy Thanksgiving, and be sure to read today's comic before you prepare your turkey.

Amphibian.com comic for 25 November 2015

Monday, November 23, 2015

Attacking Enemies in my Phaser Platformer

Tossing Pencils
After adding some evil toads to my 8-bit style platformer last week, there were finally some things to avoid while jumping around in the game. Unfortunately, there was no way to defeat the toads. Typically, most enemies in these kinds of games can be killed in some way. This weekend I decided to add an attack capability to the game.

After debating an attack style for a little while, I decided that the basic attack capability should be for the frog to throw pencils. This is supposed to be Science Frog's game, but I haven't updated the frog sprite yet. As a basic attack, I think Science Frog would toss pencils.

Adding some attack pencils to the game turned out to be fairly simple. Phaser really does make game development easy!

The first step was to add a group of weapons to the game, along with a new key tracker to use for firing them off. I also added a variable called nextFire to limit how fast weapons can be thrown.

var weapons;

var FIRE_RATE = 250;
var nextFire;

function create() {

    // ... other stuff ...

    weapons = game.add.group();
    weapons.createMultiple(3, 'pencil', 0, false);

    // ... other stuff ...

    fire = game.input.keyboard.addKey(Phaser.Keyboard.CONTROL);
        
    nextFire = game.time.now + FIRE_RATE;

}

The createMultiple function on Phaser.Group objects takes 4 parameters. The first is the number of sprites to create. The second is the name of the sprite image to use. I added a "pencil" image to my assets for this purpose. The third parameter is the sprite frame to use, but my pencil only has one frame. The fourth parameter indicates if the sprite should exist. I set this one to false. Why would I create sprites that don't exist? How do I use them if they don't exist? Well, sprite "existence" really indicates if the sprite is currently interacting with the rest of the game. You can set a sprite's existence to false in order to temporarily disable it - and then re-use it later. That's exactly what I'll be doing.

The nextFire variable is set to a time in the future. That gets used later on, keep reading.

function update() {

    game.physics.arcade.collide(frog, layer);
    game.physics.arcade.collide(enemies, layer);
    game.physics.arcade.overlap(frog, enemies, hurtFrog, null, this);

    // see if weapons are hitting enemies
    game.physics.arcade.overlap(enemies, weapons, hurtEnemy, null, this);
    
    // ... other stuff ...

    if (fire.isDown) {
     throwSomething();
    }
    
    // ... other stuff ...

}

I added another overlap check, this time between the enemies group and the weapons group. If a weapon is overlapping an enemy, the hurtEnemy function will be called.

The other new piece of the update function is the check to see if the fire key is being held down. I used the CTRL key for this. If it is down, the throwSomething function is called.

First, the hurtEnemy function:

function hurtEnemy(e, w) {
    
    if (!e.immune) {
        e.immune = true;
        e.alpha = 0.5;
        e.damage(0.1);
        
        w.exists = false;
        
        game.time.events.add(200, function() {
            e.immune = false;
            e.alpha = 1;
        }, this);
    }
    
}

This function is very similar to the hurtFrog function I added last week. Here, the first parameter will be the enemy and the second will be the weapon that hit it. Just like I did for the frog, I use an immune flag to make sure the enemies can't get hurt too fast, and if they are hit there is a change to their alpha channel. After 200 milliseconds, the immune flag goes off and the enemy can get hurt again. The big difference between this and the hurtFrog function is the line that sets exists to false for the weapon. This will immediately make the weapon disappear so it can be recycled by the throwSomething function. And speaking of that function. here it is:

function throwSomething() {

    if (game.time.now > nextFire) {

        nextFire = game.time.now + FIRE_RATE;
        
        var weapon = weapons.getFirstExists(false);
        if (weapon){
            weapon.exists = true;
            weapon.anchor.setTo(0.5, 0.5);
            weapon.lifespan = 1500;
            weapon.reset(frog.body.position.x+20, frog.body.position.y-20);
            game.physics.arcade.enable(weapon);
            weapon.body.velocity.y = -400;
            weapon.body.angularVelocity = 50;
            if(frog.direction == 1){
                weapon.body.velocity.x = 500;
            }else{
                weapon.body.velocity.x = -500;
            }
            
        }

    }

}

It seems like there's a lot going on here, but it's really very simple. First, the whole thing is wrapped in a check to see if the current game time is greater than the next fire time. If not, nothing happens. This ensures that the fire rate is constrained. If firing is allowed, the nextFire time is reset to some time in the future and then the fun happens.

The call to weapons.getFirstExists(false) gets the first weapon from the group that doesn't currently exist. Remember, the weapons will get set to not exist after they hit an enemy. If we have a weapon in that state, it gets set to exist again. It also gets a lifespan set on it, so that it will automatically set itself to not exist even if it doesn't hit an enemy after a certain amount of time. Its position gets reset to around the middle of the frog (since he's supposed to be throwing it), and it gets some velocity given to it. That's what makes it fly through the air. I set both x and y velocity so that it moves in a kind of arc motion. I may give different types of weapons different motion attributes at some point.

With those simple additions to the game, you can now throw pencils at frogs. Give it a try for yourself at http://amphibian.com/eight-bit or browse the complete source code on GitHub.

Also remember to check out today's comic! Science Frog doesn't throw any pencils in it.

Amphibian.com comic for 23 November 2015

Friday, November 20, 2015

Enemy Collisions in my Phaser Platformer

Earlier in the week I added some enemies to my 8-bit style Phaser platformer, but they were basically just images in the level. Bumping in to them didn't really do any damage. There was a little more work I had to do in order for them to become proper enemies.

If you read my post from Wednesday, you'd know that I created all the enemies from data in an object layer in the map. When I did that, I put all the enemy objects in a group called enemies. All of that took place in the game's create function. Checking collisions and hurting the frog takes place in the update function.

Here's what I wanted to happen. If the frog touches an enemy, he should get hurt. How much should probably vary by enemy but that's not extremely important at the moment. When the frog gets hurt, there should be some kind of visual indicator. For now, I've decided to set the frog's alpha channel to 50% for 500 milliseconds to indicate damage. For those 500 milliseconds, the frog can't be hurt again, and he should be thrown away from the enemy that inflicted the damage.

First, I added some fields to the frog object when I create it.

function createFrog() {

    // ... other stuff ...

    f.immune = false;
    f.health = 3;

    // ... other stuff ...    
    
}

The immune field is just something I made up that should indicate if the frog is currently in that 500 millisecond period where he can't get hurt again. He's immune from further damage. The health field is actually provided by Phaser. You can assign a health value to a sprite, and then change it by calling damage or heal. When health reaches 0, the sprite is killed. The maximum value is arbitrary, so I set it to 3 for now.

Now in the update function, I add some more collision checks. First, I added a collision check between the enemies and the layer object. This will make the enemies sit on the ground and logs and stuff just like the frog does. Then I added an overlap check between the frog and the enemies. Why overlap instead of collision? If I checked for collision, the frog would push against the enemies and possibly even move them. I wanted encounters with enemies to only impact the frog. Checking for overlap allows me to call a function when two sprites are in collision but Phaser takes no action to remove the sprites from the collision state - I'll handle that manually. That's why I give the third parameter, hurtFrog, to the overlap function. The hurtFrog function will be called when overlap is detected. Here are the important parts of the update function:

function update() {

    game.physics.arcade.collide(frog, layer);
    game.physics.arcade.collide(enemies, layer);
    game.physics.arcade.overlap(frog, enemies, hurtFrog, null, this);

    if (!frog.immune) {
        frog.body.velocity.x = 0;
    }

    // ... other stuff ...

    if (!frog.immune) {
        if (cursors.left.isDown) {
            frog.body.velocity.x = -150;
        } else if (cursors.right.isDown) {
            frog.body.velocity.x = 150;
        }
    }

    // ... other stuff ...

}

The other changes to update are to only set the frog's velocity if the frog is not in that immune state. This is basically to override the player's control over the frog. I'm going to essentially toss the frog out of the way regardless of what key the player might be holding down.

...Which brings us to the the hurtFrog function. This is where the action is!

function hurtFrog(f, e) {
    
    if (!f.immune) {
        f.immune = true;
        f.alpha = 0.5;
        f.damage(0.1);
        if (f.body.position.x < e.body.position.x) {
            f.body.velocity.x = -300;
        } else {
            f.body.velocity.x = 300;
        }
        game.time.events.add(500, function() {
            f.immune = false;
            f.alpha = 1;
        }, this);
    }
    
}

Remember, this function will be called by Phaser when the frog overlaps with an enemy. The first parameter passed in will be the frog object and the second will be the enemy. This is the same order that they object are specified in when calling overlap. In this function, I first check to see if the frog is currently in that immune state. If he is, I do nothing. But if he isn't, I set the immune flag, set the alpha channel to 0.5, and do a little damage. Then comes the frog-tossing! To throw the frog out of the way of whatever enemy he just hit, I check to see where he is in relation to the enemy. If he's on the left side, I give him some velocity to toss him to the left. If he's on the right, I toss him to the right. Finally, I set that 500 millisecond timer. When time's up, the immune flag goes off and the alpha channel goes back to 100%. At this point, the frog can get hurt again.

You can give the game a try for yourself and let me know what you think. I am still playing around with the numbers for the toss velocity and such. The whole point of this sandbox level is to get the right feel for the game before I start making the real levels. The complete source code is on GitHub as well, if you want a closer look.

Also, don't forget to have a closer look at today's comic!

Amphibian.com comic for 20 November 2015