Easy and fast HTML5 physics with Panda.js and p2.js physics library

Some days ago I blogged about Panda.js, a great HTML5 framework, in the post Look at Panda.js HTML5 game engine capabilities with a working game prototype.

Today I am showing you how to use p2.js JavaScript 2D physics library to add physics to Panda projects thanks to the p2.js plugin for Panda.js.

Once you downloaded both Panda and the plugin, all you have to do to make it work is to copy p2.js into src/plugins/ folder.

You’ll probably have to create plugins folder if it’s the first plugin you are installing.

Don’t worry about paths and filenames at this time: you will find everything in the project source code ready to be downloaded.

Have a look at what we are going to do:

Click on an empty space on the stage to create a box, and click on a box to remove it.

Although this may seem a simple demo (and actually it is), we have the all the basic features explained, such as:

* How to create a body
* How to destroy a body
* How to skin a body
* How to get the body given a world coordinate.

And this is the commented source of the only file you need to edit to edit, main.js.

game.module(
	"game.main"
)
.require(
	"engine.core",
	// the physics plugin
	"plugins.p2"
)
.body(function(){
	// landscape mode
	game.System.orientation = game.System.LANDSCAPE;
	// class defining the physics box
	Box = game.Class.extend({
		// flag to know if we have to remove the graphics attached to a body
		// I am sure there's a better way to do this, but I didn't find it at the moment :(
     	removeGraphics:false,
     	init: function(x,y) {
     		// creation of a rectangle shape, 100 x 100 pixels which will be translated to world coordinates
          	var boxShape = new game.Rectangle(100/game.scene.worldScale,100/game.scene.worldScale);
          	// the body itself, look how I set the mass and the position
          	// remember to manage vertical position upside down because physics vertical coordinates and
          	// stage vertical coordinates do not match
          	this.boxBody = new game.Body({
               	mass: 1,
               	position: [
                    	x/game.scene.worldScale,
                    	(game.system.height-y)/game.scene.worldScale
               	]
			});
			// adding the shape to the body
          	this.boxBody.addShape(boxShape);
          	// creation of a PIXI square to attach to the body
               this.graphics=new PIXI.Graphics();
			this.graphics.lineStyle(2/game.scene.worldScale,0x000000);
               this.graphics.beginFill(Math.random()*0xff0000);
			this.graphics.drawRect(-boxShape.width/2,-boxShape.height/2,boxShape.width,boxShape.height);
			this.update();
			// adding the body to the world
          	game.scene.world.addBody(this.boxBody);
          	// adding the square to the stage
               game.scene.container.addChild(this.graphics);
		},
		update: function() {
			// very unoptimized way to remove the graphics when a body is destroyed
			if(this.boxBody.world==null){
               	if(!this.removeGraphics){
                    	this.removeGraphics=true;
               	}
               	else{
					game.scene.container.removeChild(this.graphics);
                    	game.scene.removeObject(this);
                    }
			}
			// update graphics
          	else{
               	this.graphics.position.x = this.boxBody.position[0];
               	this.graphics.position.y = this.boxBody.position[1];
               	this.graphics.rotation = this.boxBody.angle;
			}
		},
	});
	SceneGame = game.Scene.extend({
		backgroundColor: 0x888888,
		// worldScale! you should remember it if you are a Box2D user
		worldScale: 50,
		init: function(){
			this.container = new game.Container();
			this.container.position.x = 0;
			this.container.position.y = game.system.height;
			this.container.scale.x = this.worldScale;
			// look, inverting y scale
			this.container.scale.y = -this.worldScale;
			this.stage.addChild(this.container);
			// world creation
			this.world = new game.World();
			// adding a plane which will represent the ground
			var planeShape = new game.Plane();
			var planeBody = new game.Body({
				position: [0, 0]
			});
			planeBody.addShape(planeShape);
			this.world.addBody(planeBody);
		},
          click:function(event){
          	// detecting bodies under the mouse, if any
			var bodyUnderMouse = this.world.hitTest([event.global.x/game.scene.worldScale,(game.system.height-event.global.y)/game.scene.worldScale],this.world.bodies,5);
          	// if we have bodies under the mouse, remove them
			if(bodyUnderMouse.length>0){
               	while(bodyUnderMouse.length>0){
               		var touchedBody=bodyUnderMouse.shift();
					this.world.removeBody(touchedBody);
				}
			}
			// if we don't have bodies under the mouse, create a new one
			else{
				var x = event.global.x;
				var y = event.global.y;
				var box = new Box(x,y);
				this.addObject(box);
			}
          }
	});
	game.start();
});

I am tempted to make a small game 100% Panda.js powered. Stay tuned.

Download the source code of the entire project

Get the most popular Phaser 3 book

Through 202 pages, 32 source code examples and an Android Studio project you will learn how to build cross platform HTML5 games and create a complete game along the way.

Get the book

214 GAME PROTOTYPES EXPLAINED WITH SOURCE CODE
// 1+2=3
// 100 rounds
// 10000000
// 2 Cars
// 2048
// A Blocky Christmas
// A Jumping Block
// A Life of Logic
// Angry Birds
// Angry Birds Space
// Artillery
// Astro-PANIC!
// Avoider
// Back to Square One
// Ball Game
// Ball vs Ball
// Ball: Revamped
// Balloon Invasion
// BallPusher
// Ballz
// Bar Balance
// Bejeweled
// Biggification
// Block it
// Blockage
// Bloons
// Boids
// Bombuzal
// Boom Dots
// Bouncing Ball
// Bouncing Ball 2
// Bouncy Light
// BoxHead
// Breakout
// Bricks
// Bubble Chaos
// Bubbles 2
// Card Game
// Castle Ramble
// Chronotron
// Circle Chain
// Circle Path
// Circle Race
// Circular endless runner
// Cirplosion
// CLOCKS - The Game
// Color Hit
// Color Jump
// ColorFill
// Columns
// Concentration
// Crossy Road
// Crush the Castle
// Cube Jump
// CubesOut
// Dash N Blast
// Dashy Panda
// Deflection
// Diamond Digger Saga
// Don't touch the spikes
// Dots
// Down The Mountain
// Drag and Match
// Draw Game
// Drop Wizard
// DROP'd
// Dudeski
// Dungeon Raid
// Educational Game
// Elasticity
// Endless Runner
// Erase Box
// Eskiv
// Farm Heroes Saga
// Filler
// Flappy Bird
// Fling
// Flipping Legend
// Floaty Light
// Fuse Ballz
// GearTaker
// Gem Sweeper
// Globe
// Goat Rider
// Gold Miner
// Grindstone
// GuessNext
// Helicopter
// Hero Emblems
// Hero Slide
// Hexagonal Tiles
// HookPod
// Hop Hop Hop Underwater
// Horizontal Endless Runner
// Hundreds
// Hungry Hero
// Hurry it's Christmas
// InkTd
// Iromeku
// Jet Set Willy
// Jigsaw Game
// Knife Hit
// Knightfall
// Legends of Runeterra
// Lep's World
// Line Rider
// Lumines
// Magick
// MagOrMin
// Mass Attack
// Math Game
// Maze
// Meeblings
// Memdot
// Metro Siberia Underground
// Mike Dangers
// Mikey Hooks
// Nano War
// Nodes
// o:anquan
// One Button Game
// One Tap RPG
// Ononmin
// Pacco
// Perfect Square!
// Perfectionism
// Phyballs
// Pixel Purge
// PixelField
// Planet Revenge
// Plants Vs Zombies
// Platform
// Platform game
// Plus+Plus
// Pocket Snap
// Poker
// Pool
// Pop the Lock
// Pop to Save
// Poux
// Pudi
// Pumpkin Story
// Puppet Bird
// Pyramids of Ra
// qomp
// Quick Switch
// Racing
// Radical
// Rebuild Chile
// Renju
// Rise Above
// Risky Road
// Roguelike
// Roly Poly
// Run Around
// Rush Hour
// SameGame
// SamePhysics
// Save the Totem
// Security
// Serious Scramblers
// Shrink it
// Sling
// Slingy
// Snowflakes
// Sokoban
// Space Checkers
// Space is Key
// Spellfall
// Spinny Gun
// Splitter
// Spring Ninja
// Sproing
// Stabilize!
// Stack
// Stick Hero
// String Avoider
// Stringy
// Sudoku
// Super Mario Bros
// Surfingers
// Survival Horror
// Talesworth Adventure
// Tetris
// The Impossible Line
// The Moops - Combos of Joy
// The Next Arrow
// Threes
// Tic Tac Toe
// Timberman
// Tiny Wings
// Tipsy Tower
// Toony
// Totem Destroyer
// Tower Defense
// Trick Shot
// Tunnelball
// Turn
// Turnellio
// TwinSpin
// vvvvvv
// Warp Shift
// Way of an Idea
// Whack a Creep
// Wheel of Fortune
// Where's my Water
// Wish Upon a Star
// Word Game
// Wordle
// Worms
// Yanga
// Yeah Bunny
// Zhed
// zNumbers