Box2D Vs Nape: Hello both worlds

Nape is an open source physics engine written I Haxe by Luca Deltodesco which is also available for AS3 as swc library and is going to generate some interest about it.

In this post, I am creating a simple Hello World for both engines, with a dynamic square falling over a static floor, and explain the difference between the scripts.

Box2D

This is the script:

package {
	import flash.display.Sprite;
	import flash.events.Event;
	import Box2D.Dynamics.*;
	import Box2D.Collision.*;
	import Box2D.Collision.Shapes.*;
	import Box2D.Common.Math.*;
	public class MainBox2D extends Sprite {
		private var world:b2World=new b2World(new b2Vec2(0,10),true);
		private var worldScale:Number=30;
		public function MainBox2D() {
			var debugDraw:b2DebugDraw = new b2DebugDraw();
			var debugSprite:Sprite = new Sprite();
			addChild(debugSprite);
			debugDraw.SetSprite(debugSprite);
			debugDraw.SetDrawScale(worldScale);
			debugDraw.SetFlags(b2DebugDraw.e_shapeBit);
			debugDraw.SetFillAlpha(0.5);
			world.SetDebugDraw(debugDraw);
			var bodyDef:b2BodyDef=new b2BodyDef;
			bodyDef.position.Set(320/worldScale,460/worldScale);
			var polygonShape:b2PolygonShape=new b2PolygonShape();
			polygonShape.SetAsBox(320/worldScale,20/worldScale);
			var fixtureDef:b2FixtureDef=new b2FixtureDef();
			fixtureDef.shape=polygonShape;
			var staticFloor:b2Body=world.CreateBody(bodyDef);
			staticFloor.CreateFixture(fixtureDef);
			bodyDef.position.Set(320/worldScale,0/worldScale);
			bodyDef.type=b2Body.b2_dynamicBody;
			polygonShape.SetAsBox(25/worldScale,25/worldScale);
			fixtureDef.shape=polygonShape;
			var dynamicBox:b2Body=world.CreateBody(bodyDef);
			dynamicBox.CreateFixture(fixtureDef);
			addEventListener(Event.ENTER_FRAME, update);
		}
		private function update(e:Event):void {
			world.Step(1/30,10,10);
			world.ClearForces();
			world.DrawDebugData();
		}
	}
}

and this is the result:

Here we go with next engine:

Nape

This is the script:

package {
	import flash.display.Sprite;
	import flash.events.Event;
	import nape.geom.Vec2;
	import nape.phys.Body;
	import nape.phys.BodyType;
	import nape.shape.Polygon;
	import nape.space.Space;
	import nape.util.ShapeDebug;
	public class MainNape extends Sprite {
		private var world:Space=new Space(new Vec2(0,500));
		private var debug:ShapeDebug=new ShapeDebug(640,480,0x00ff00);
		public function MainNape() {
			addChild(debug.display);
			var staticFloor:Body=new Body(BodyType.STATIC,new Vec2(320,460));
			staticFloor.shapes.add(new Polygon(Polygon.box(640,40)));
			staticFloor.space=world;
			var dynamicBox:Body=new Body(BodyType.DYNAMIC,new Vec2(320,0));
			var block:Polygon=new Polygon(Polygon.box(50,50));
			dynamicBox.shapes.add(block);
			dynamicBox.space=world;
			addEventListener(Event.ENTER_FRAME, update);
		}
		private function update(e:Event):void {
			debug.clear();
			world.step(1/30,10,10);
			debug.draw(world);
			debug.flush();
		}
	}
}

and this is the result

Now, let’s see the differences:

World creation

Box2D: everything is managed by a b2World object, which wants the gravity in the constructor.

private var world:b2World=new b2World(new b2Vec2(0,10),true);

Nape: the world is a Space object, which wants the gravity in the constructor:

private var world:Space=new Space(new Vec2(0,500));

Vec2 is basically the same as b2Vec2. Also notice gravity is defined using different scales, I personally prefer Box2D approach as it’s intended as real world gravity.

Debug Draw

Box2D: debug draw in Box2D allows great customization, including what to display (shapes, joints, and so on), scale and fill alpha, but you’ll have to write some lines of code:

var debugSprite:Sprite = new Sprite();
addChild(debugSprite);
debugDraw.SetSprite(debugSprite);
debugDraw.SetDrawScale(worldScale);
debugDraw.SetFlags(b2DebugDraw.e_shapeBit);
debugDraw.SetFillAlpha(0.5);
world.SetDebugDraw(debugDraw);

Nape: debug draw in Nape is easier to setup but it does not allow customization. Just declare a variable defining the viewport and the main color:

private var debug:ShapeDebug=new ShapeDebug(640,480,0x00ff00);

and then you are ready to add debug draw to Display List:

addChild(debug.display);

I’m personally finding Box2D debug draw more elegant, thanks to filled shapes.

Adding a simple box

Box2D: even adding a box can be quite a task for beginners, you have to create a body definition, then shape, then a fixture to attach the shape to the body.

var bodyDef:b2BodyDef=new b2BodyDef;
bodyDef.position.Set(320/worldScale,460/worldScale);
var polygonShape:b2PolygonShape=new b2PolygonShape();
polygonShape.SetAsBox(320/worldScale,20/worldScale);
var fixtureDef:b2FixtureDef=new b2FixtureDef();
fixtureDef.shape=polygonShape;
var staticFloor:b2Body=world.CreateBody(bodyDef);
staticFloor.CreateFixture(fixtureDef);

Not the most intuitive thing, but it allows a lot of customization. Also, Box2D works in meters and you will have to convert it to pixels.

Nape: basic shapes are really easy to crate with Nape you just need to define a body and a shapes.

var staticFloor:Body=new Body(BodyType.STATIC,new Vec2(320,460));
staticFloor.shapes.add(new Polygon(Polygon.box(640,40)));
staticFloor.space=world;

And as you can see it works with pixels.

World update

Updating the world is a critical process as it renders the world in our Flash movie

Box2D: in three lines we make the simulation run and draw:

world.Step(1/30,10,10);
world.ClearForces();
world.DrawDebugData();

The core lies in Step method which runs in this case the simulation at 1/30 seconds at time.

Nape: it’s basically the same, step method handles the simulation.

debug.clear();
world.step(1/30,10,10);
debug.draw(world);
debug.flush();

And that’s all at the moment. As you can see, there isn’t that much difference between these two engines when dealing with basic projects. During next days I’ll show you something more complicated.

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

215 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
// Stairs
// 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