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