Phaser and Physics: Polygonal Collisions Primer

Notice the sprite on the left, it has a default collision body. This sprite is irregularly shaped and this will make for unwanted or confusing collisions. Sometimes, you want a sprite to have a collision area that isn't just a box, like the sprite on the right. Using Phaser's P2JS physics system, I'm going to show you how.

See the Pen Phaser & P2 Physics: Working with Polygon Colliders by Jeremy Dowell (@codevinsky) on CodePen.

1. Start with a sprite image

First, we need an irregularly shaped image to use as our sprite texture. I made this quickly in photoshop:

check

2. Create the physics data using PhysicsEditor

If you don't already have the free PhysicsEditor app, go download it at once: http://www.codeandweb.com/physicseditor

This handy little tool is great for editing sprite physics and polygons and it's a lot more powerful than what we're going to talk about today.

Open up physics editor and let's get going.

  1. Add a sprite image to the shape list
    You can simply just drop the image in to the shape list on the left like so:
    step-1 2.Use the magic wand to create a simple polygon
    Fiddle around with the tolerance level until you have a polygon that roughly matches your shape.
    step-2

  2. Set the Exporter to the "Lime + Corona (JSON)" Exporter
    step-3

  3. Click the publish button.

That's it.. We now have our body definition. Let's apply it to a sprite.

3. Write the code

var game, DemoState;
function DemoState() {}
DemoState.prototype.preload = function() {
  game.load.crossOrigin = "Anonymous"; //required to load assets for codepen
  game.load.image('check', 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/75580/check_1.png');
  game.load.physics('physicsData', 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/75580/physics_1.json');
}

DemoState.prototype.create = function() {
  // start the P2JS physics system
  game.physics.startSystem(Phaser.Physics.P2JS);

  //set some initial gravity
  game.physics.p2.gravity.y = 500;


  // add our simple Box Collider Sprite
  // and give it physics
  var simpleCollisionSprite = game.add.sprite(128,128,'check');  
  game.physics.p2.enableBody(simpleCollisionSprite,true);

  // add our polygon collider sprite
  // and give it physics
  var polygonCollisionSprite = game.add.sprite(400,128,'check');  
  game.physics.p2.enableBody(polygonCollisionSprite,true);

  // remove all of the current collision shapes from the physics body
  polygonCollisionSprite.body.clearShapes();

  // load our polygon physics data
  polygonCollisionSprite.body.loadPolygon('physicsData', 'check');


  // create a group for easy modification
  // and add the sprites
  // NOTE: this is not required, it's just handy.
  var checkGroup = game.add.group();
  checkGroup.add(simpleCollisionSprite);
  checkGroup.add(polygonCollisionSprite);

  // add text for display
  scoreText = game.add.text(10, 10, 'Hit Space to Restart Demo');
  scoreText.font = 'Arial Black';
  scoreText.fontSize = 16;
  scoreText.stroke = '#000';
  scoreText.strokeThickness = 3;
  scoreText.fill = '#fff';

  // setup our keyboard handler
  var spacebar = game.input.keyboard.addKey(Phaser.Keyboard.SPACEBAR);
  spacebar.onDown.add(function() {
    checkGroup.forEachExists(function(sprite) {
      sprite.reset(sprite.x, 128);
      sprite.body.angle = 0;
    });
  });
}

// Game Bootstrapper
window.onload = function () {
  game = new Phaser.Game(600, 300, Phaser.AUTO, 'polygon-example');
  game.state.add('demo', DemoState);
  game.state.start('demo');


};

See the Pen Phaser & P2 Physics: Working with Polygon Colliders by Jeremy Dowell (@codevinsky) on CodePen.

Questions? Comments? Hit me up on twitter: (http://twitter.com/codevinsky) or in the #phaser.io chat