Showing posts with label games. Show all posts
Showing posts with label games. Show all posts

Monday, April 25, 2016

Review of Xgaming's NES-style Wireless Gamepad

Late last week I received my new Bluetooth wireless gamepad from Xgaming. I was really excited about this new product. I've had one of their arcade joysticks for years and found it to be an excellent piece of hardware that fully lives up to the high expectations set for it on their web site. I was certain that this new wireless gamepad, a bit of a departure from their existing product line, would not disappoint me.


So, what do I think now that I've had a few days to play with it?

Let's start with my initial impressions. It was a little smaller than I had expected it to be. It doesn't really give dimensions anywhere on Xgaming's site (as far as I could tell) but the unit is only 5.125 inches wide and 2.5 inches tall. It's slightly over half an inch thick (not counting the sticks and buttons). For me, the small size makes hitting both sets of top trigger buttons awkward but maybe I just need to get used to it. Most games I play only need one set of top triggers anyway. Besides that, the position of all the buttons and sticks is excellent. It weighs only 3 ounces, but feels very solid. The buttons and D-pad are very firm and have a wonderful feel to them.

Technically, it has been functioning very well. I had no problems pairing it to my Windows 10 PC as a Bluetooth game controller, but it did seem to lose its pairing once (there are colored LED lights on the bottom which indicate things like that - flashing blue means ready to pair). I'm not sure if it was the device's fault or mine - I may have been holding down one of the settings buttons inadvertently while powering it on. I'll withhold judgement on that issue until I see if it repeats. There were no issues setting up button mappings in my emulator software either. It all worked very well.

Playing games with it has been very enjoyable so far. The button response is much better than my old SNES-style USB game controller. I honestly haven't liked a PC game controller this much since my Gavis PC GamePad.

The device is currently selling for about $45. If you love playing emulated NES and SNES games as much as I do, I believe you'll find it to be well-worth the money.

The only question left might be, does it work in web-based HTML5 games such as the 8-bit style platformer I've been working on? The answer is...maybe. Web browser gamepad support is still weird. Phaser has an API for it, but so far I've found it difficult to work with. I'll keep trying and maybe have something to report next week.

Until then, I've got more comics for you to enjoy!

Amphibian.com comic for 25 April 2015

Wednesday, March 2, 2016

Using "shutdown" to Save State in Phaser

Today is the comic that I've been working on in all my spare time for the past week, but have been thinking about for about a year. For such a long time, I've wanted to work a Dragon Warrior parody into a comic. That game was such a major part of my childhood. I played it for countless hours on my NES, along with its sequels.

If you're not as familiar with it as I am (my wife had never heard of it), it was the game that introduced console turn-based RPGs to the American market. You play a warrior trying to save a princess and slay a dragon by defeating various monsters to gain gold and experience. The gold gets you better armor and weapons, while the experience ups your level for more strength, magic, etc. As you walk around the world, a battle starts randomly. You and the monster take turns hitting each other until one of you dies. Assuming you win, the game returns to the map screen and you walk around some more.

If you haven't seen the comic yet, take a look at it. My parody of the game is embedded in the 3rd frame, and is completely playable.

The walking-around game state.

When I implemented this in Phaser, I made the walking-around-on-the-map one game state and the fighting-a-monster (or a printer in my case) another game state. After the fight ends, I wanted to go back to the walking-around state but put the frog at the same map position he was before the fight started - not reset everything in the state back to the default. But the way Phaser works is that when you start a game state, the create function is always called. How could I ensure that the frog ended up back where he belonged each time that happened?

The fighting state. Kick that printer!

The answer is to make use of the shutdown function on the state. I hadn't used this one before; my game state objects never defined it. But it is important if you wanted to save the current values of anything in your game before switching states, as it is called by Phaser when one state is being stopped but before another starts. I used it to save the frog's current position, which I then used the next time create was called.

Here is a sample of the code, to help in the explanation.

function walkAround() {

    // default frog's position
    var fPos = { x: 200, y: 500 };

    function create() {

        // create the frog wherever fPos says to put him
        frog = this.add.sprite(fPos.x, fPos.y, "frog", 0);

        // ... other stuff ...

    }
    
    function shutdown() {
        
        // save the frog's current position to use
        // next time create is called.
        fPos.x = frog.position.x;
        fPos.y = frog.position.y;
        
    }

    return {
        create: create,
        shutdown: shutdown
    };

}

function fight() {

    // ... all the stuff for the fighting state ...

    return {
        // an actual state object
    };

}

var s1 = walkAround();
var s2 = fight();
 
var game = new Phaser.Game(width, height, Phaser.CANVAS, "cell-2");
 
game.state.add("walking",  s1);
game.state.add("fighting", s2);

game.state.start("walking");

The fPos variable gets a default value when it is initialized. This is the value used the very first time create is called. But after shutdown is called, fPos changes. Since the state object isn't ever destroyed, fPos retains its value and the next time create is called, the frog is put in his last known location.

This technique will work for anything in your game state that you'd like to save and restore, such as when your player switches to a menu state and then returns to play.

Make sure you check out the comic and play the game! If you'd like to see the complete source code for the game (or anything else on the comic) you can find the repo on GitHub.

Amphibian.com comic for 2 March 2016

Friday, February 26, 2016

"Loading" Screens in Phaser Games

I noticed an annoying thing when playing my Phaser platformer on Amphibian.com - it was taking a really long time to start the levels. The problem was mainly that I was re-loading the game assets every time a level was started, and that I wasn't pre-loading them way back before the title screen.

Loading...

I wanted to fix this issue and add a "Loading" screen at the beginning before the main stage select menu was available. The way to do this is to add a few more states to the game.

First, I added a boot state. All this state will do is load the title background image and an image that says "Loading." This happens in the preload function, and should go fairly quickly. In the create function for this state, which will be called as soon as preload completes, it will immediately start the next state - the real preloader. Check out the following code from the game (remember, the full source code is available on GitHub):

var boot = {
  
    preload: function() {
        this.game.load.image("title", "assets/images/title.png");
        this.game.load.image("title-loading", "assets/images/title-loading.png");
    },
    
    create: function() {
        this.state.start("preloader");
    }
        
};

The second state I added was called preloader. This will serve as the game's real preloader. I moved the asset pack loading from my other two existing states (the menu and the playable level) to the preload function of this state. But before I start loading assets, I display the two assets I loaded in the boot state's preload. I can use those assets here because they were loaded before this function - even though this is a preload function it's not the first one. Basically, you can use assets in preload as long as they've already been loaded by a previous state's preload. This will show the player the nice title screen and let them know that the game is loading. After all the assets are loaded, the create function is called for this state, which changes to the stageSelect state.

var preloader = {
  
    preload: function() {
        
        this.add.image(0, 0, "title");
        this.loadingText = this.add.image(450, 200, "title-loading");
        
        this.load.pack("main", "assets/pack.json");

    },
    
    create: function() {
        this.state.start("stageSelect");
    }
        
};

Now when I set up my game, I add all 4 states and then start the boot state.

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

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

game.state.start("boot");

It still takes a while to load all the assets, but at least now you know what's going on. And once you make it to the menu, all the levels will start immediately for you. Much better. The process of loading assets still takes a while because the background music files are so large. I'll probably fix that by reducing their quality a little. Don't worry, you won't notice.

You might notice something wrong with today's comic, however...

Amphibian.com comic for 26 February 2016

Wednesday, February 24, 2016

Swimming in a Phaser Platformer

The theme for Level 7 of my 8-bit style Phaser platformer has been selected - Liquid Cooled! It's a water level with a name that also describes a high-performance computer needing more than just a normal CPU fan.

But a water level means the frog has to swim through it, instead of jump. I had to make a few changes to my code in order to support an optional "swim mode" behavior. I handled this by putting a water flag in my level objects. When true, it means the physics should be more...liquid.

The swimming level. All platformers should have at least one.

To start, the gravity needed to be adjusted. I have the normal gravity set to 1500 in my game, but I played around with different numbers and 250 seemed most appropriate for a swimming effect. In real life, gravity doesn't decrease when you're in water...but the effect of your body's buoyancy makes it seem as if it does. Same thing here.

function create() {

    // ... other stuff ...

    if (waterLevel) {
        this.physics.arcade.gravity.y = 250;
    } else {
        this.physics.arcade.gravity.y = 1500;
    }

    // ... other stuff ...

}

The other thing that needed to change was the jump behavior. On land, the frog can't start a new jump while still in mid-air. But in the water, doing so gives the impression of swimming. Also, the amount of upward thrust supplied by a jump should be lessened under water. The speed at which the frog moves left and right should also be reduced.

function update() {

    // ... other stuff ...

    var xVel = waterLevel ? 100 : 150;
    var yVel = waterLevel ? -250 : -400;
    var jumpFrames = waterLevel ? 26 : 31;
    
    if (spacebar.isDown) {

        if ((frog.body.onFloor() || frog.locked || waterLevel) && jumpTimer === 0) {
            // jump is allowed to start
            jumpTimer = 1;
            frog.body.velocity.y = yVel;
            frog.cancelLock();
            jumpSound.play();
        } else if (jumpTimer > 0 && jumpTimer < jumpFrames && !frog.body.blocked.up && !frog.body.touching.up) {
            // keep jumping higher
            jumpTimer++;
            frog.body.velocity.y = yVel + (jumpTimer * 7);
        } else if (frog.body.blocked.up || frog.body.touching.up) {
            // permanently end this jump
            jumpTimer = 999;
        }

    } else {
        // jump button not being pressed, reset jump timer
        jumpTimer = 0;
    }

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

    // ... other stuff ...

}

Lines 5-7 in the code snippet above set the values for x-velocity, y-velocity, and length of a jump (in frames). These used to be hard-coded to the non-water values, but now there's a water option. In the check to see if a jump can start, line 11, I've added the condition that if this is a water level, jumps can start even if the frog is not on the ground or locked to a floating platform. The jump sets the y-velocity to the appropriate value, and the cursor keys set the x-velocity.

With these relatively simple adjustments in place, it really feels like the frog is swimming through Level 7. You can play it yourself on Amphibian.com, and make sure you also check out today's comic while you're there! If you're more interested in the complete source code for the game, you can find that on GitHub. But seriously, read the comic. It's funny. Most of the time.

Amphibian.com comic for 24 February 2016

Monday, February 22, 2016

Setting Up Level Bosses with Phaser

I've reached the phase of my development on my Phaser platformer where I refactor everything. This weekend, it was the level bosses. If you looked at much earlier versions of the game or read my blog posts from a couple months ago, you might remember that I had one sandbox level with a dinosaur as the boss at the end. He was pretty much hard-coded in there, so adding different bosses for each level was difficult.

To make it better, I added a field to my level objects called boss. I assign a function to that field, which creates the boss Sprite. I can assign different "boss" functions to each level.

function beaver(game, group, frog) {
    // ... set up the boss beaver
}

function dinosaur(game, group, frog) {
    // ... set up the boss dinosaur
}

var levelOne = { // Vector Factory
        map: "Level1",
        music: "assets/audio/Ouroboros.mp3",
        background: "#141414",
        boss: beaver
};

var levelTwo = { // Binary Trees
        map: "Level2",
        music: "assets/audio/Club_Diver.mp3",
        background: "#000066",
        boss: dinosaur
};

// ... define other levels here ...

var gameState = {
        levels: [],
        currentLevel: -1,
        lives: 3
};

// populate the levels array (add more the same way)    
gameState.levels[0] = levelOne;
gameState.levels[1] = levelTwo;

In my game's create function, I call the boss function of whatever level is currently being played. I then add the kill behavior to the boss Sprite, which is to end the level and return to the stage select screen.

function create() {

    // ... other stuff ...

    // create a group for all the enemies
    enemies = this.add.group();

    // create our hero sprite
    frog = createFrog();

    // --------------- set up the boss for this level
        
    var theBoss = gameState.levels[gameState.currentLevel].boss(this, enemies, frog);
    theBoss.events.onKilled.add(function() {
        // this level is complete! change state!
        this.state.start("stageSelect");
    }, this);

    // ... other stuff ...

}

Now it's fairly easy to add new bosses and even switch them around from one level to another. But you may wonder why I chose to always pass in those three parameters to the boss functions - game, group, and frog.

The first thing that the boss setup function must do is to create the boss Sprite, and to accomplish that I need the game object, the group in which to place this boss, and a reference to the frog object so the boss's behavior can change based on attributes such as the frog's proximity or other such things.

// function create the boss beaver
function beaver(game, group, frog) {

    // create this boss:
    //     150 pixels from the far right edge of the level,
    //     100 pixels from the top of the level,
    //     using the spritesheet with the key of "beaver"
    var obj = game.add.sprite(game.world.width - 150, 100, "beaver", 0, group);

    // ... other stuff ...

    return obj;

}

If these little snippets of code aren't enough, you can see the game's complete source code on GitHub.

Try the game out for yourself at Amphibian.com, and also be sure to read today's comic while you're there (or go right to the comic with the link below!).

Amphibian.com comic for 22 February 2016

Friday, February 19, 2016

My Level Design, So Far

With most of the game mechanics getting pretty solid in my platformer, I've been devoting more time to the level design. Here's what I have so far.

There are going to be 8 levels, one for each bit in a byte. I want each one to have at least some loose tie-in with a software engineering technology, much like how the Tron arcade game's difficulty levels were (mostly) named after programming languages. Those were RPG, COBOL, BASIC, FORTRAN, SNOBOL, PL1, PASCAL, ALGOL, ASSEMBLY, OS, JCL, and USER, if you've forgotten. I've programmed in 4 of them. I won't tell you which ones.

But anyway, here are my levels so far:


Level 1 - Vector Factory. Kind of a dark, industrial feel.


Level 2 - Binary Trees. It's a forest. Lots of trees. And pits.


Level 3 - Silicon Dioxide Valley. A desert. Sand and stuff.


Level 4 - Cloud Computing. Also some ice. In the sky.


Level 5 - Containers. There are lots of boxes. And a dock.


Level 6 - Deployment Pipeline. You guessed it - pipes.

I don't really have anything for 7 or 8 yet. Leave a comment below if you have any suggestions. Also, you can check out the game's complete source code on GitHub or play the current unfinished version on Amphibian.com. You can also view today's comic there as well!

Amphibian.com comic for 19 February 2016

Wednesday, February 17, 2016

Hitting the Wall - The Difference Between "blocked" and "touching" in Phaser

I've made another small improvement to my 8-bit style Phaser platformer. Now that I have some more complete levels in place, I noticed that if the frog was jumping and hit his head on the jump wasn't ending. He would just kind of hover there, in collision with the overhead tile, until the jump timer was up (I discussed my use of a timer to control the jump behavior previously).

I wanted to cancel the upward motion in the event of an overhead collision. Phaser has two ways of detecting this kind of thing in the Arcade physics engine: blocked and touching. The blocked and touching fields on the Sprite physics body are objects which each contain four boolean values - one for each direction. When true, these values indicate a collision on that side of the Sprite.

if (sprite.body.blocked.right) {
    // running into a wall on the right
} else if (sprite.body.blocked.left) {
    // running into a wall on the left
} else if (sprite.body.blocked.up) {
    // hitting something above
} else if (sprite.body.blocked.down) {
    // on the ground. same as sprite.body.onFloor() ??
} 

if (sprite.body.touching.right) {
    // hitting another sprite on the right
} else if (sprite.body.touching.left) {
    // hitting another sprite on the left
} else if (sprite.body.touching.up) {
    // hitting another sprite above
} else if (sprite.body.touching.down) {
    // hitting another sprite below
} 

So what's the difference? The blocked object refers to the Sprite colliding with a Tile. Since I am using a Tilemap for each level in my game, blocked will tell me if the frog is hitting some part of the environment. The touching object refers to the Sprite touching another sprite. I could use that field to determine if the frog hits an overhead enemy, for example.

For now, I've updated my jump control algorithm to take the Tile collision case into account.

function update() {

    // ... other stuff ...

    if (spacebar.isDown) {
    
        if ((frog.body.onFloor() || frog.locked) && jumpTimer === 0) {
            // jump is allowed to start
            jumpTimer = 1;
            frog.body.velocity.y = -400;
            frog.cancelLock();
            jumpSound.play();
        } else if (jumpTimer > 0 && jumpTimer < 31 && !frog.body.blocked.up) {
            // keep jumping higher
            jumpTimer++;
            frog.body.velocity.y = -400 + (jumpTimer * 7);
        } else if (frog.body.blocked.up) {
            // permanently end this jump
            jumpTimer = 999;
        }
    
    } else {
        // jump button not being pressed, reset jump timer
        jumpTimer = 0;
    }

    // ... other stuff ...

}

The changes are minor, but important. If the player continues to hold down the spacebar, the jump will only keep going higher if the frog is not being blocked from above. If he is being blocked, I set the jumpTimer to a high value, to ensure that the jump is over - treated basically the same way that it would be if the player let go of the spacebar. If I don't do this, on the next frame the frog will have dropped a little bit and be out of collision, which will make the second branch of the nested if-else block true again and he'll move up some more. This causes the overhead collision to re-occur, and it's a viscous cycle until we get past 30 frames!

That's all I've changed for today, but that's actually good news. It means I'm much closer to being finished with the game, since I'm working on such small details. Maybe by the end of the month it will be complete. For now, you can view the source code on GitHub and play the game in its unfinished state here.

Be sure to read today's comic! It's about load balancers. Or see-saws. Or both.

Amphibian.com comic for 17 February 2016

Monday, February 15, 2016

Switching to Frame Based Tweens in Phaser

This weekend I was doing some more work on my 8-bit style Phaser platformer. I added another enemy (a rabbit) and made some changes which will make it easier to add even more enemies. But during my extensive play-testing I noticed that I was having a lot of trouble with my moving platforms. Both the ridable clouds and the collapsing platforms seemed to move away from the frog, and then the frog's motion became very choppy as it was repositioned.

Frogs can now battle rabbits in the dark forest.

After playing around with some things, I determined that the issue was caused by a slightly lagging frame rate. I had a bunch of other things running on my laptop and the game wasn't running quite as quickly as it was before. The physics engine, which controlled the frog's movements, was making updates based on how much time was elapsing between frames. The movement of the platforms was being handled by Tweens, which by default calculate their movement in constant time. When the frame rate dips below 60 per second, the two get out of sync. Normally this would not be that noticeable but in the situation where the two objects are tied together, it caused some issues.

To resolve these problems, I switched the Tweens into "frame based" mode. This is as easy as setting a boolean flag once in the create function.

function create() {
        
    // ... other stuff ...
     
    this.tweens.frameBased = true;

    // ... other stuff ...

}

When running in frame based mode, the Tweens will use the physics engine's update timer. When I switched to this mode, the frog and the platforms remain in sync much better when the frame rate dips a little. I did have to adjust the duration values in most of my Tweens, since in frame based mode the duration should represent number of frames instead of number of milliseconds. But it was a simple adjustment.

Remember, you can view the complete source code for the game on GitHub, and play the current version at this link: http://amphibian.com/eight-bit.

Before you go, be sure to read today's Amphibian.com comic - and give me a vote on TopWebcomics.com if you have an extra second!

Amphibian.com comic for 15 February 2016

Wednesday, February 10, 2016

Don't Fall Through - "Tile Bias" in Phaser

Despite getting a lot of good level design accomplished this weekend, and adding collapsing platforms to my Phaser platformer, my free time since Sunday has been extremely limited. I haven't been able to work on much else, so today's post will be short.

One thing I would like to address is the use of "tile bias" in Phaser. In one of my levels, I had an issue where if the frog jumped from a platform near the top of the screen he would fall through the ground instead of colliding with it. It wouldn't happen 100% of the time, but it was often enough. I'd seen this type of problem before, back when I wrote my own HTML5 game engines instead of using Phaser. It is a classic problem - when there is too much time lapsing between frames (for whatever reason - slow computer, too many background tasks, etc.) the physics engine can miss collisions. A fast-moving sprite can traverse such a great distance in the time between frame updates that its bounding box ends up completely on the other side of an object with which it should have collided.

When it comes to a sprite colliding with a tilemap in Phaser, the collision calculation can be tuned by changing the value of TILE_BIAS. This was exactly what I needed to do because the issue was the frog hitting (or in this case, not hitting) a ground tile.

The default value for TILE_BIAS appears to be 16. This means that for a 32x32 tile, there's a 48x48 box when it comes to collision checks. It doesn't mean that a colliding sprite is moved back an extra 16 pixels to get it out of collision, the value is only used for the collision check. So don't worry - a sprite can still appear to be right next to a tile! I tried changing the value from 16 to 32 and that solved the problem for me. If you have a similar issue in your game, you'll probably have to play around with the number to find what works in your situation.

I change the value in my create function, at the same time I set up the other physics stuff.

function create() {
        
    game.physics.startSystem(Phaser.Physics.ARCADE);
    game.physics.arcade.checkCollision.down = false;
    game.physics.arcade.TILE_BIAS = 32;
    game.physics.arcade.gravity.y = 1500;

    // ... other stuff ...

}

Remember, if you want to view the complete source code for the game it is available on GitHub. And remember to view today's comic. Both comics so far this week have dealt with lunch. Maybe I'm hungry when I'm writing these.

Amphibian.com comic for 10 February 2016

Monday, February 8, 2016

Collapsing Platforms in Phaser

I've been working on level design over the last few days for my Phaser platformer (view the complete source code on GitHub). I used my floating, ride-able cloud platforms (that I wrote about last week) in a few places, but I also found a few places where I wanted to use a collapsing platform. You know, one that falls after you stand on it for a little while.

The red-and-black platforms will fall after you jump on them.

To start, they are very similar to the riding platforms. The difference is in the custom collision callback function, shown below.

function fallPlatformSep(s, platform) {

    if (!s.locked) {
        s.lockTo(platform);
    }

    if (!platform.activated) {

        platform.activated = true;

        // save the original Y-value
        var origY = platform.position.y;

        platform.game.time.events.add(1000, function() {

            var t = platform.game.add.tween(platform.position);
            var dist = ((platform.game.world.height + 100) - platform.y);
            var time = dist * 2.25;
            t.to( { y: platform.position.y + dist }, time, Phaser.Easing.Quadratic.In, false, 0, 0, false);
            t.onComplete.add(function() {

                // after falling, wait 2 sec. before putting it back
                platform.game.time.events.add(2000, function() {
                 platform.activated = false;
                 platform.position.y = origY;
                 var t2 = platform.game.add.tween(platform);
                 t2.to({ alpha: 0.5 }, 100, Phaser.Easing.Linear.None, true, 0, 3, true);
                });

            });

            t.start();

        }, this);
        
    }
    
}

function update() {

    // ... other stuff ...

    this.physics.arcade.collide(frog, fallingPlatforms, fallPlatformSep, null, this);

    // ... other stuff ...

}

Since this function is called when the frog and the falling platform are colliding, the first step is to "activate" the platform, if it has not been activated already. This block should be entered the first time that the frog lands on the platform and won't be entered again no matter how long he stands on it.

The next step is to make a note of the original Y-value, so it can be put back a few seconds after it falls off the screen. The drop and restoration is handled by a few game timers and tweens. The first timer sets it up so that the platform will drop 1000 milliseconds after the first contact. Inside the timer function, I set up a Tween to move the platform down to a final position of 100 pixels below the world bounds. This makes sure that if the frog rides it to the bottom he will be complete off-world and trigger the kill function.

I'm using the Phaser.Easing.Quadratic.In easing function in the drop so that it gets off to a slow start. I actually found a very useful page with live demos of all the Phaser easing functions: just click here!

When the drop Tween completes, I set a second timer. Two seconds after the fall, the platform gets set back to its original Y-position and once again becomes inactive. Just to make it look nice, I use another Tween here to blink the alpha a few times.

But don't let your interest in my comics drop as fast as these platforms! Check out today's comic before you go to other parts of the Internet, or order lunch, or whatever.

Amphibian.com comic for 8 February 2016

Friday, February 5, 2016

Use Tiled's Custom Properties in Phaser

To make editing the maps for my Phaser platformer easier, I decided to make use of the custom properties Tiled lets you add to objects. These get directly translated to fields on the Sprite objects if you use the createFromObjects function to pull them from the map.

I used this technique on my moving cloud platforms. In the map editor, I select the object and then add two custom properties: direction and distance.

Adding two custom properties in Tiled

Once I saved my map, I could then use those properties when I set up my moving cloud platforms. In the create function, I make the platforms from the objects on the map. Look at the following code.

function create() {

    // ... other stuff ...

    platforms = this.add.group();
    platforms.enableBody = true;
    map.createFromObjects('others', 6573, 'cloud-blue', 0, true, false, platforms);
    platforms.forEach(function(p) {
        
        this.physics.enable(p, Phaser.Physics.ARCADE);
        p.body.allowGravity = false;
        p.body.immovable = true;
        
        var t = this.add.tween(p.position);

        // use the distance and direction custom properties
        // to set up the Tween
        var dist = (p.distance ? Number(p.distance) : 128);
        if (p.direction == "left") {
            t.to( { x: p.position.x - dist }, 3000, Phaser.Easing.Linear.None, true, 0, -1, true);
        } else if (p.direction == "right") {
            t.to( { x: p.position.x + dist }, 3000, Phaser.Easing.Linear.None, true, 0, -1, true);
        } else if (p.direction == "up") {
            t.to( { y: p.position.y - dist }, 3000, Phaser.Easing.Linear.None, true, 0, -1, true);
        } else if (p.direction == "down") {
            t.to( { y: p.position.y + dist }, 3000, Phaser.Easing.Linear.None, true, 0, -1, true);
        }
        
    }, this);

    // ... other stuff ...

}

As I iterate over them to perform their setup, I can read p.distance and p.direction in order to customize the movement Tween. I first check to see if distance is defined and use a default value if it is not. This way, the game doesn't fail if I forget to set the custom property. I then check the value of the direction field and set the Tween accordingly. If I forget to set direction on one of my objects, it just won't move because the to function will never be called on the Tween.

I like this method because it allows me to quickly and easily tweak the level in the map editor until I get the level design right. I don't have to go back to change any code when I want to move a platform's starting position, direction, or travel distance. I might add a third property set set the speed as well.

Remember, you can see the complete source code for the game on GitHub!

While you're here, why don't you take a few minutes and catch up on some comics that you may have missed - like today's! It deals with the first and best troubleshooting technique there is.

Amphibian.com comic for 5 February 2016

Wednesday, February 3, 2016

Ride Moving Platforms in a Phaser Game

Another staple of classic platformers that my Phaser game has been missing is the moving platform. You know, those floating platforms that go up and down or side to side and upon which you can ride? I had to add some. It wasn't that hard, but there were some tricks to it.

This is the frog's new cloud platform.

First, I had to add the sprites for the moving platforms. I did this by adding them to my map in Tiled as objects, the same way I added the enemies (see that blog post here).

platforms = game.add.group();
platforms.enableBody = true;
map.createFromObjects('others', 6573, 'cloud-blue', 0, true, false, platforms);
platforms.forEach(function(p) {
    
    game.physics.enable(p, Phaser.Physics.ARCADE);
    p.body.allowGravity = false;
    p.body.immovable = true;
    
    var t = this.add.tween(p.position);
    t.to({ y: p.position.y - 200 }, 3000, Phaser.Easing.Linear.None, true, 0, -1, true);
    
}, this);

Every object with id 6573 was assigned the "cloud-blue" sprite image key and put in the platforms group. Then I iterate over the group to set them all up with physics so they can collide with the frog. I turn off gravity on them so they don't fall off the screen, and I set body.immovable to true. This isn't to say that they can't move - it just means that they won't react to being pushed down when the frog lands on them. The movement of the platforms is controlled by Tweens. In the above code snippet, all of the platforms are given the same Tween. This one example Tween will move the platform up 200 pixels from its start position in 3 seconds and then loop forever. In my finished game I'll use different Tweens for different platforms.

After that, adding a collision check in the update function between the frog and the platforms group was all it took to make the platforms solid.

I now had moving platforms upon which the frog could land, but the behavior wasn't correct. As the platform moved up it would push the frog up with it, but on the way down the frog would keep falling and hitting the platform over and over again. It didn't look like he was riding it. The solution was to create a special collision callback function which "locks" the frog to the platform upon which he stands.

function platformSep(s, platform) {

    if (!s.locked) {
        s.locked = true;
        s.lockedTo = platform;
        s.body.velocity.y = 0;
    }

}

function update() {

    this.physics.arcade.collide(frog, platforms, platformSep, null, this);

    // ... other stuff ...

    if (frog.locked) {
        if (frog.body.right < frog.lockedTo.body.x || frog.body.x > frog.lockedTo.body.right) {
            frog.locked = false;
            frog.lockedTo = null;
        } else {
            frog.x += frog.lockedTo.deltaX;
            frog.y += frog.lockedTo.deltaY;
        }
    }

    // ... other stuff ...

}

Now, when the frog and a platform are in collision, the frog will get a locked flag set to true, and the lockedTo field will be set to the platform sprite on which he stands. The frog's y-velocity is also set to 0 here to stop any potential falling that might occur otherwise.

Once I had these additional fields, I could perform a check to see if the frog is currently locked to a platform. If he is, but his current position says that he's walked off of it, I cancel the lock and his behavior goes back to normal. Otherwise, the frog's position gets updated to match the movement deltas of the platform. This keeps him riding it, no matter which in direction it moves.

These moving platforms really add a lot of classic platformer feel to the game, and thanks to Phaser they weren't too difficult to add. Remember, you can see the complete source code to the game on GitHub and play the current version at this link!

There are some major upgrades going on in the comic today, so don't forget to read it!

Amphibian.com comic for 3 February 2016

Wednesday, January 20, 2016

A Match-3 Tile Game in Phaser

It's finally here! The day I release the comic containing my match-3 game! I've been working on this thing for way too long. When I had the idea to put one of those classic tile-matching games in a comic (you know, like Bejeweled) I had thought that it would be easy to put together. I used Phaser, course, but I was unprepared for just how much goes in to one of these things.

Getting this one simple game embedded in the 3rd frame of the comic came in at a couple hundred lines of code. Like everything else in my comic, you can see the complete source code on GitHub (this link goes directly to the game's .js file) so I won't bother to post the whole thing here. But one concept came up more than once during the development which I'd like to talk about.

Tile Matching game with Amphbian.com's frogs

The issue was that I needed to do Phaser Tween animations on possibly over 20 sprites at once, and then take some other action when they had all finished. Making a single Tween call a function when complete is rather straightforward, but what is the proper mechanism for firing off an event when a bunch of other asynchronous events have completed?

Here's an example of a Tween that calls a function when complete:

var tween = game.add.tween(sprite.scale);
tween.onComplete.add(someFunction);
tween.to( { x: 1, y: 1 }, 500,
    Phaser.Easing.Linear.None, true, 0, 0, false);

The above code creates a Tween that will change the x and y fields on sprite.scale both to 1 in 500 milliseconds. When complete, the function someFunction will be called.

Now what if I had 5 Tweens that all take different lengths of time to finish, and I don't want to execute a function until they are all done? Sure, I could just call the function when the longest one is complete, but what if they don't even all start at the same time? It could get messy. The solution is to make a little closure function that counts completions and then executes a callback function when the counter reaches a set level. Here is what I mean...

var num = 5;

var counter = function(total, callback) {
    var t = total;
    var c = 0;
    return {
        inc: function() {
            c++;
            if (c === t) {
                callback();
            }
        }
    };
}(num, someFunction);

var tween = game.add.tween(sprite.scale);
tween.onComplete.add(counter.inc);
tween.to( { x: 1, y: 1 }, 500,
    Phaser.Easing.Linear.None, true, 0, 0, false);

// now make 4 more Tweens here, with different lengths


Assuming I know how many Tweens I'm going to make, which is 5 in my example above, I can declare an anonymous function and then immediately call it passing in that number along with the function I want to use as the callback. That anonymous function creates a closure and returns an object (assigned to the variable counter) with a function inc. Every time counter.inc is called, it increments the internal counter and checks to see if it is equal to the expected total. If so, callback is executed - and here callback is someFunction. The onComplete event on the Tweens just has to call counter.inc and everything goes off like expected. Once all five are done, no matter how long it takes, someFunction will be called.

I ended up using this pattern in two different places in my match-3 game. My game certainly isn't the best example of a classic match-3 tile game but it's also meant to be a joke in a comic. If you're interested in how it works anyway, be sure to check out the source code. At the very least, look at the comic and match up some frogs!

Amphibian.com comic for 20 January 2016

Monday, January 18, 2016

A Phaser Game With Mouse/Touch Input

I'm back from Texas and have mostly recovered from the events of last week. I still have a bit of a cold, but I'm not letting it stop me from getting a simple game ready for inclusion in a comic this week. This game will use mouse/touch input instead of the keyboard like my last one did, so I had to figure out how to use sprite dragging in Phaser.


Like most things have been with Phaser so far, it took a few tries to get it all correct but in the end it all seems really simple. It revolves around enabling input on individual Sprites, enabling drag, and then optionally listening for drag-related events.

Here is the complete source code for a Sprite-dragging demo:

var init = function() {

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

    function selectFrog(sprite, pointer) {
        console.log("selected");
        sprite.frame = 1; // frog in the air
    }

    function releaseFrog(sprite, pointer) {
        console.log("released");
        sprite.frame = 0; // frog sitting
    }

    function preload() {
        this.load.spritesheet('frog', 'assets/sprites/frog.png', 79, 60);
    }

    function create() {

        this.stage.backgroundColor = "#999999";

        var frog = this.add.sprite(50, 50, "frog", 0);
        frog.inputEnabled = true;
        frog.input.enableDrag(true);
        frog.events.onDragStart.add(selectFrog, this);
        frog.events.onDragStop.add(releaseFrog, this);

    }

};

window.onload = function() {
    init();
};

The selectFrog and releaseFrog functions are the event handlers for the drag start and drag stop events. In this example, all they do is log something to the console and change the frame of the sprite. In my upcoming game, I do more in here such as tween animations and game logic.

When I make the frog sprite in the create function of my example, setting inputEnabled to true is the first step. Without this, you can't do anything with input to the individual sprite. Once that is done, you can set the specific input behaviors. The very next line, frog.input.enableDrag(true), turns on drag-ability. The single parameter passed to the function sets whether or not the Sprite should re-center itself to the cursor upon being drug. I passed true, which will cause the center of the sprite to jump to the position of the cursor when the drag starts. If this isn't what you want, you can also say false and drag from any part of the sprite - not just center.

When dragging is enabled, the sprite will fire off events for drags starting and stopping. I added the selectFrog and releaseFrog functions as event handlers using the onDragStart and onDragStop fields of the sprite's events field. Note the parameters that get passed to these event handlers when they fire. The first is the sprite object that was the subject of the drag and the second is the Pointer object. There's lots of information on the Pointer object about the state of the pointer if you want any of that to matter in your game.

If you've tried the code above and are using a mouse, you might be disappointed that the cursor changes to that text-select I-beam cursor thing while you drag the frog. If you'd like it to stay as the default cursor while you drag, no problem! You can simply override the cursor style in the create function. Just add this line:

this.game.canvas.style.cursor = "default";

Now the cursor will always be the default pointer regardless of what you are clicking or dragging in the game. If you'd like the cursor to turn into the click-here hand whenever it's over the frog (dragging or not), there's also the useHandCursor field on the input object. If you add this line to the create function instead...

frog.input.useHandCursor = true;

...it will turn the cursor into the hand when you mouse-over the frog. I didn't care for that personally, but it might be useful in certain situations.

Now that you've read all this, you probably want to see this sprite-dragging in action. Sorry, but the game I was making is not actually in today's comic. You have to wait until later in the week. Click the image or link below for today's comic.

Amphibian.com comic for 18 January 2016

Monday, January 11, 2016

Tweens in Phaser

I was playing around with another simple game-in-a-comic idea today and I started using Phaser's Tweens. No, Phaser doesn't actually have children between the ages of 10 and 12. Phaser's Tweens are a convenient way of updating one or more object properties over a specified time range.

I'd never used a Tween before, but after playing around with them for a little while I decided that I could use them to replace an effect I had been doing "the hard way" in my platformer. Recall that when the frog gets hurt, I temporarily set his alpha value to 0.5 and then start a timer to set it back. Along with the alpha value, I also set/unset an immune flag on the frog. I can do this same thing better using a Tween.

I've replaced my frog-hurting-alpha-adjusting code with the following...

var t = game.add.tween(frog);
t.onComplete.add(function() {
    frog.immune = false;
});
t.to( { alpha: 0.5 }, 50, Phaser.Easing.Linear.None, true, 0, 2, true);

On line 1, I create the Tween object using the familiar GameObjectFactory (game.add). When creating a Tween, you pass in the object on which it will work. In my case, that's the frog sprite.

Before starting any tweening, I add a listener for the onComplete event. I do this because I want to turn off the frog's immunity when the alpha animation is over.

The final step is to create and start the tween. The last line above calls the to function, creating a tween that moves the specified properties of the object TO the given values. The properties and the target values are given by the object that is the first argument to the function. In my example above, that's { alpha: 0.5 }, which means I want to move the frog.alpha property from whatever it is currently to 0.5. The second argument is 50, which means I want the transition to the new alpha value to take 50 milliseconds. The third argument specifies the easing function to use in the transition. The fourth argument specifies auto-start. I want this tween to start immediately upon creation, so I specified true. The 5th argument is start delay, which is none because I used 0. The 6th argument, which I have set to 2, is the number of times to repeat. The final argument, which I set to true, is the yoyo parameter. Turning on yoyo means that the tween with play backwards automatically at the end. This means that after reaching the alpha value 0.5, it will start transitioning back to the original alpha value. For me, this created a nice flashing effect.

So how long does the whole thing take? I specified 50 milliseconds, but that's just for the one-way transition from 1 to 0.5. Since I turned on yoyo, it doubles to 100 milliseconds. And I also set it for 2 repeats, so the whole flashing alpha thing should complete around 300 milliseconds after it starts. Just remember to do all that math if the length of time is important to you.

The frog's alpha flashes after being hit - thanks to Tweens!
Tweens give me the ability to do some nice things with animating Sprite properties which would be very difficult to do in other ways. I'm glad I discovered them. You can discover the complete source code for the game on GitHub. Just click on this link!

And speaking of discovering things, have you discovered how much you like reading my Amphibian.com comics yet? Look at today's, and maybe look at some other ones while you're there.

Amphibian.com comic for 11 January 2016

Friday, January 8, 2016

You Can't Play Forever

With my one hour of game development time this evening, I decided to finally add "lives" to my Phaser platformer. While I don't want to actually kill Science Frog, the concept of getting more than one life (or attempt) in a game is a fairly standard concept. So far, my game was once-and-done.

The glasses represent the number
of tries (or lives) you get in the game.
Keeping track of how many lives you currently have in the game was simple. I added a lives field to my gameState object. That's the one that I am using to keep track of aspects in the game that need to be shared between the two main game states - the picking a stage and the playing.

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

Now to use that... First, to display the number to the player I added an image of the frog's glasses next to some text beside it. I decided that the glasses would be a good representation of Science Frog. Maybe when he gets beat up too much his glasses will break and that's why he has to restart. That way, I don't have to say he gets killed. Anyway, those steps are simple.

var g = game.add.image(40, 15, "glasses", 0, meters);
g.fixedToCamera = true;

var livesText = game.add.text(78, 5, "x " + gameState.lives, {
    fontSize: 20,
    fill: "#FFFFFF",
    stroke: "#000000",
    strokeThickness: 3
}, meters);
livesText.fixedToCamera = true;

First, I add an Image to the game at position (40, 15). The key for the image is "glasses" which is what I assigned to this image in the asset pack. The 4th parameter, 0, is unused here because as an Image (as opposed to a Sprite) there is only one frame. The last parameter is the group to which this image is added. I am putting it in my meters group, the same one that contains the health bar. After creating it, I set it to be fixed to the camera. This way it doesn't scroll with the rest of the world.

Adding the text for the lives is also simple. Calling game.add.text is all it takes! The first two arguments are the X and Y coordinates. The third is the text itself. The fourth argument is the style object. Its fields define the style of the text. I set the size, fill, stroke, and stroke thickness. Since the background can be very light, putting a black border around the text makes it more readable. The fifth argument is once again the group to which this text should be added - again I use my meters group. Finally, this also gets fixed to the camera.

I've had an onKilled listener on my frog object for some time now, but it didn't do a whole lot. I expanded on that today to take advantage of the lives counter.

frog.events.onKilled.add(function() {
    dieSound.play();
    gameState.lives--;
    bgmusic.stop();
    if (gameState.lives === 0) {
        console.log("game over!");
        game.state.start("stageSelect");
    } else {
        console.log("try again!");
        game.state.restart();
    }
}, this);

The player's frog is killed by Phaser when its health reaches 0 (from colliding with enemies) or when it falls off the bottom of the map. This onKilled event listener is called when that happens. It plays the death sound, decrements the number of lives, and stops the music. If the player has no more lives, the game is returned to the stage select screen, but otherwise the current level just gets reset and the frog starts over back at the beginning.

I suppose this means I need to add in extra-life power-ups somewhere...

You can access the complete source code for this game on GitHub, and you can access the complete Amphibian.com comic on Amphibian.com! Or click on the picture below.

Amphibian.com comic for 8 January 2015

Monday, January 4, 2016

Falling Down - Disable Some Phaser World Bounds Checks

Since adding the ability to have more than one level in the platformer I'm building with Phaser, I actually created a second level. Like many platformers, it has...ummm...platforms. What I mean is that unlike my first test level that just had the ground and some boxes to jump on, this second level has no ground and is just a bunch floating clouds on which to jump. If you miss your platform and fall to the bottom of the world, you die.

Hey, you! Get off of my cloud!

Well, not really. The way the game worked was that the player just landed on the bottom of the world bounds and stood there. When I create the player's frog Sprite, I turn on collision with the world bounds. What are the world bounds? Basically that's the defined map. The world bounds collision check prevents the player from walking off the world on the far left and right, but it also prevents the player from falling through the bottom or jumping off the top.

var frog = group.create(50, 50, 'frog');
game.physics.enable(frog, Phaser.Physics.ARCADE);

// stay inside the world boundaries
frog.body.collideWorldBounds = true;

I had a hard time finding an example of what I wanted to do. I performed a great number of fruitless searches, which is fine because I wasn't really looking for fruit. I just wanted to find the easiest way to keep the left/right/top world collisions but turn off the bottom. I read some rather complex solutions that actually replaced the bounds check function on the Sprite, but the simplest solution turns out to be really...simple.

First, the player's frog object needs some minor settings adjusted.

frog.checkWorldBounds = true;
frog.outOfBoundsKill = true;

I already had collideWorldBounds set to true on the physics body, but I also need to set the checkWorldBounds property directly on the Sprite to true. By itself, this has no effect, but it is necessary if I also want to set the outOfBoundsKill property to true. Independent of the physics collisions, these two settings tell Phaser to check on each frame to see if the sprite in question is inside the bounds of the world, and if not, to kill it.

With just this change made to the frog, nothing seems any different. The player can't actually fall or walk off the world because collideWorldBounds is also set to true. It takes just one more line of code to turn off the bottom-of-the-world bounds check and allow the frog to fall to his death. Here it is, on line 6 below:

function create() {

    game.physics.startSystem(Phaser.Physics.ARCADE);

    // turn off the collision with the bottom of the world
    game.physics.arcade.checkCollision.down = false;

    // ... other stuff ...

}

As you can see, I make this adjustment immediately after starting the physics system. I only turn off the down collision checks, but you could just as easily turn off up, left, or right depending on your game's needs.

Now the frog can't walk off the left or right of the map but can fall in a hole or off a platform. If you want to see the complete source code for the game, it is freely available on GitHub. If you want to see today's Amphibian.com comic, it is also freely available. Just click on the image of the first frame below...

Amphibian.com comic for 4 January 2016

Friday, January 1, 2016

Particle Emitters in Phaser

Happy New Year!

I had a list of things I wanted to get done with the platformer I'm building with Phaser before 2016. One of them was to add bosses to the levels. Not like manager bosses. Bosses like the big enemy at the end of the stage.

The basics of adding a boss were the same as adding another type of "regular" enemy. I placed the enemy in the level editor, took note of the gid assigned to it by Tiled, and added a setup function to add specialized behavior. I wrote about this process in more detail previously (read those posts here and here).

The big addition here is that I want the boss to throw something at the frog. To accomplish this, I decided to use a Phaser Particle Emitter.

Phaser's Particle system is very nice. Using an Emitter, you can generate bursts of Sprites easily and with randomized attributes. In my game, I made a level boss dinosaur that throws plates off his tail. Those plates are the particles.

First, I had to define the image for the plate and put it in my asset pack. I did this and gave it a key of "dino-plate." After that, making an Emitter that throws the plates is simple. Look at this sample code from my game (you can see the complete source code of the game on GitHub):

var e = game.add.emitter(0, 0, 5);
e.makeParticles('dino-plate', 0, 5, true);
e.gravity = 30;
e.maxParticleSpeed.x = -700;
e.minParticleSpeed.x = -400;
e.maxParticleSpeed.y = -500;
e.minParticleSpeed.y = -300;

The first line creates the Emitter. The first two arguments to the function are the X and Y coordinates of the emitter. I don't have to worry about the real position right now because I'll move it every time I use it to be in the same position as the dinosaur. The third argument is the maximum number of particles this emitter will contain.

The second line calls the makeParticles function to actually create the particles that will be emitted. The first argument is the key for the image or spritesheet to use for the particle. The second argument is the frame of the sprite, but I'm using a single image so I just use 0. The third argument is again the number of particles to create. The fourth argument is set to true to enable physics bodies on the particles. I need this set to true because I want the particles to be able to collide with the frog.

The rest of the lines control the properties of the particles tossed out of this emitter. For this boss, I want the things thrown to have less gravity than the rest of the game. This makes them fall slower purely for dramatic effect, and is completely optional. The max and min speed settings define the bounds for the speed of the particles. Phaser will assign a random speed to each particle within these bounds.

When the time comes for the boss to attack, it's simple to start the emitter.

e.x = boss.position.x + 100;
e.y = boss.position.y;
e.start(true, 2000, null, 5);

Like I said above, I re-position the emitter before I start it each time to make it appear as though the particles are actually coming from the dinosaur's position. After that, calling start causes the Emitter to burst out the particles. The first argument to start is true because I want it to emit the maximum number of particles (in this case, 5) all at once. The second argument is the life of the particles in milliseconds. I want them to exist for 2 seconds. The third argument, which I set to null, is the frequency of the emissions. It's not used when the first argument is set to true, so I use null. The last argument is the quantity to emit. I use 5 so all the particles are thrown out.

The effect is very nice when you see it in action. The randomization of the various attributes makes the burst look natural and realistic. I captured an animation of it...



I like it. I hope you like the comic today, and the rest of the comics that will be coming this year.

Amphibian.com comic for 1 January 2016

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