Box2DFlash 2.1a released – what changed

Some days ago Boris the Brave released the new version of the popular physics library.

There are some critical changes that won’t make old projects run in the new environment.

The most important ones are:

  • It is now not necessary to specify a size for your world, it’ll always be large enough.
  • Improved collisions system
  • You must specify if a body is dynamic, no matter if its mass is greater than zero
  • Fixtures now determine material properties of shapes, such as density, friction and so on

But I think an example will be more explicative than a thousand words, so I created a simple vehicle you can control with left and right arrow keys. It uses revolute joints and motors.

This is the code you would need in the old Box2D version

package {
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.KeyboardEvent;
	import Box2D.Dynamics.*;
	import Box2D.Collision.*;
	import Box2D.Collision.Shapes.*;
	import Box2D.Common.Math.*;
	import Box2D.Dynamics.Joints.*;
	public class car extends Sprite {
		public var world:b2World;
		public var car_body:b2Body;
		public var front_wheel:b2Body;
		public var rear_wheel:b2Body;
		public var front_motor:b2RevoluteJointDef = new b2RevoluteJointDef();
		public var rear_motor:b2RevoluteJointDef = new b2RevoluteJointDef();
		public var rear_motor_added:b2RevoluteJoint
		public var front_motor_added:b2RevoluteJoint
		public function car():void {
			// world setup
			var worldAABB:b2AABB = new b2AABB();
			worldAABB.lowerBound.Set(-100, -100);
			worldAABB.upperBound.Set(100, 100);
			world=new b2World(worldAABB,new b2Vec2(0,10.0),true);
			debug_draw();
			// variables used for bodies and motors
			var body:b2Body;
			var bodyDef:b2BodyDef= new b2BodyDef();
			var boxDef:b2PolygonDef = new b2PolygonDef();
			var circleDef:b2CircleDef= new b2CircleDef();
			var revoluteJointDef:b2RevoluteJointDef = new b2RevoluteJointDef();
			// adding the ground
			bodyDef.position.Set(250/30, 200/30);
			boxDef.SetAsBox(600/30, 20/30);
			boxDef.friction=1;
			boxDef.density=0;
			body=world.CreateBody(bodyDef);
			body.CreateShape(boxDef);
			body.SetMassFromShapes();
			bodyDef.position.Set(0/30, 200/30);
			boxDef.SetAsBox(50/30, 50/30);
			boxDef.friction=1;
			boxDef.density=0;
			body=world.CreateBody(bodyDef);
			body.CreateShape(boxDef);
			body.SetMassFromShapes();
			bodyDef.position.Set(500/30, 200/30);
			boxDef.SetAsBox(50/30, 50/30);
			boxDef.friction=1;
			boxDef.density=0;
			body=world.CreateBody(bodyDef);
			body.CreateShape(boxDef);
			body.SetMassFromShapes();
			// adding car body
			bodyDef.position.Set(250/30, 90/30);
			car_body=world.CreateBody(bodyDef);
			boxDef.density=1;
			boxDef.friction=1;
			boxDef.restitution=0.1;
			boxDef.SetAsBox(50/30, 10/30);
			car_body.CreateShape(boxDef);
			car_body.SetMassFromShapes();
			// adding wheels
			circleDef.radius=20/30;
			circleDef.density=1;
			circleDef.friction=5;
			circleDef.restitution=0.1;
			// front wheel
			bodyDef.allowSleep = false;
			bodyDef.position.Set(car_body.GetWorldCenter().x + 40/30, car_body.GetWorldCenter().y);
			front_wheel=world.CreateBody(bodyDef);
			front_wheel.CreateShape(circleDef);
			front_wheel.SetMassFromShapes();
			// rear wheel
			bodyDef.position.Set(car_body.GetWorldCenter().x - 40/30, car_body.GetWorldCenter().y);
			rear_wheel=world.CreateBody(bodyDef);
			rear_wheel.CreateShape(circleDef);
			rear_wheel.SetMassFromShapes();
			// front joint
			front_motor.enableMotor=true;
			front_motor.maxMotorTorque=10;
			front_motor.Initialize(car_body, front_wheel, front_wheel.GetWorldCenter());
			front_motor_added=world.CreateJoint(front_motor) as b2RevoluteJoint;
			// rear joint
			rear_motor.enableMotor=true;
			rear_motor.maxMotorTorque=1;
			rear_motor.Initialize(car_body, rear_wheel, rear_wheel.GetWorldCenter());
			rear_motor_added=world.CreateJoint(rear_motor) as b2RevoluteJoint;
			//
			addEventListener(Event.ENTER_FRAME, update);
			stage.addEventListener(KeyboardEvent.KEY_DOWN, key_down);
		}
		public function key_down(event:KeyboardEvent):void {
			switch (event.keyCode) {
				case 39 :
					rear_motor_added.SetMotorSpeed(10);
					front_motor_added.SetMotorSpeed(10);
					break;
				case 37 :
					rear_motor_added.SetMotorSpeed(-10);
					front_motor_added.SetMotorSpeed(-10);
					break;
			}
		}
		public function debug_draw():void {
			var m_sprite:Sprite;
			m_sprite = new Sprite();
			addChild(m_sprite);
			var dbgDraw:b2DebugDraw = new b2DebugDraw();
			var dbgSprite:Sprite = new Sprite();
			m_sprite.addChild(dbgSprite);
			dbgDraw.m_sprite=m_sprite;
			dbgDraw.m_drawScale=30;
			dbgDraw.m_alpha=1;
			dbgDraw.m_fillAlpha=0.5;
			dbgDraw.m_lineThickness=1;
			dbgDraw.m_drawFlags=b2DebugDraw.e_shapeBit;
			world.SetDebugDraw(dbgDraw);
		}
		public function update(e : Event):void {
			world.Step(1/30, 10);
		}
	}
}

Take a look at the compiler errors…

And this is the new one. All changes are commented.

package {
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.KeyboardEvent;
	import Box2D.Dynamics.*;
	import Box2D.Collision.*;
	import Box2D.Collision.Shapes.*;
	import Box2D.Common.Math.*;
	import Box2D.Dynamics.Joints.*;
	public class car extends Sprite {
		public var world:b2World;
		public var car_body:b2Body;
		public var front_wheel:b2Body;
		public var rear_wheel:b2Body;
		public var front_motor:b2RevoluteJointDef = new b2RevoluteJointDef();
		public var rear_motor:b2RevoluteJointDef = new b2RevoluteJointDef();
		// this is new!!!
		public var fixtureDef:b2FixtureDef = new b2FixtureDef();
		public var rear_motor_added:b2RevoluteJoint;
		public var front_motor_added:b2RevoluteJoint;
		public function car():void {
			// world setup
			/*var worldAABB:b2AABB = new b2AABB();
			worldAABB.lowerBound.Set(-100, -100);
			worldAABB.upperBound.Set(100, 100);*/
			world=new b2World(new b2Vec2(0,10.0),true);// was world=new b2World(worldAABB,new b2Vec2(0,10.0),true);
			debug_draw();
			// variables used for bodies and motors
			var body:b2Body;
			var bodyDef:b2BodyDef= new b2BodyDef();
			var boxDef:b2PolygonShape = new b2PolygonShape();// was var boxDef:b2PolygonDef = new b2PolygonDef();
			var circleDef:b2CircleShape=new b2CircleShape(20/30);// was var circleDef:b2CircleDef = new b2CircleDef();
			var revoluteJointDef:b2RevoluteJointDef = new b2RevoluteJointDef();
			// adding the ground
			bodyDef.position.Set(250/30, 200/30);
			boxDef.SetAsBox(600/30, 20/30);
			// this is new!!
			fixtureDef.shape=boxDef;
			fixtureDef.friction=1;// was boxDef.friction=1;
			fixtureDef.density=1;// was boxDef.density=0;
			body=world.CreateBody(bodyDef);
			body.CreateFixture(fixtureDef);// was body.CreateShape(boxDef);
			// remove: body.SetMassFromShapes();
			bodyDef.position.Set(0/30, 200/30);
			boxDef.SetAsBox(50/30, 50/30);
			fixtureDef.shape=boxDef;
			fixtureDef.friction=1;// was boxDef.friction=1;
			fixtureDef.density=1;// was boxDef.density=0;
			body=world.CreateBody(bodyDef);
			body.CreateFixture(fixtureDef);// was body.CreateShape(boxDef);
			// remove: body.SetMassFromShapes();
			bodyDef.position.Set(500/30, 200/30);
			boxDef.SetAsBox(50/30, 50/30);
			// this is new!!
			fixtureDef.shape=boxDef;
			fixtureDef.friction=1;// was boxDef.friction=1;
			fixtureDef.density=1;// was boxDef.density=0;
			body=world.CreateBody(bodyDef);
			body.CreateFixture(fixtureDef);// was body.CreateShape(boxDef);
			// remove: body.SetMassFromShapes();
			// adding car body
			bodyDef.position.Set(250/30, 90/30);
			// this is new!!
			bodyDef.type=b2Body.b2_dynamicBody;
			boxDef.SetAsBox(50/30, 10/30);
			// this is new!!
			fixtureDef.shape=boxDef;
			fixtureDef.density=1;// was boxDef.density=1;
			fixtureDef.friction=1;// was boxDef.friction=1;
			fixtureDef.restitution=0.1;// was boxDef.restitution=0.1;
			car_body=world.CreateBody(bodyDef);
			car_body.CreateFixture(fixtureDef);// was body.CreateShape(boxDef);
			// remove: car_body.SetMassFromShapes();
			// adding wheels
			// remove: circleDef.radius=20/30;
			fixtureDef.density=1;// was circleDef.density=1;
			fixtureDef.friction=5;// was circleDef.friction=5;
			fixtureDef.density=0.1;// was circleDef.restitution=0.1;
			// this is new!!
			fixtureDef.shape=circleDef;
			// front wheel
			bodyDef.allowSleep=false;
			bodyDef.position.Set(car_body.GetWorldCenter().x + 40/30, car_body.GetWorldCenter().y);
			front_wheel=world.CreateBody(bodyDef);
			front_wheel.CreateFixture(fixtureDef);// was front_wheel.CreateShape(circleDef);
			// remove: front_wheel.SetMassFromShapes();
			// rear wheel
			bodyDef.position.Set(car_body.GetWorldCenter().x - 40/30, car_body.GetWorldCenter().y);
			rear_wheel=world.CreateBody(bodyDef);
			rear_wheel.CreateFixture(fixtureDef);// was rear_wheel.CreateShape(circleDef);
			// remove: rear_wheel.SetMassFromShapes();
			// front joint
			front_motor.enableMotor=true;
			front_motor.maxMotorTorque=10;
			front_motor.Initialize(car_body, front_wheel, front_wheel.GetWorldCenter());
			front_motor_added=world.CreateJoint(front_motor) as b2RevoluteJoint;
			// rear joint
			rear_motor.enableMotor=true;
			rear_motor.maxMotorTorque=1;
			rear_motor.Initialize(car_body, rear_wheel, rear_wheel.GetWorldCenter());
			rear_motor_added=world.CreateJoint(rear_motor) as b2RevoluteJoint;
			//
			addEventListener(Event.ENTER_FRAME, update);
			stage.addEventListener(KeyboardEvent.KEY_DOWN, key_down);
		}
		public function key_down(event:KeyboardEvent):void {
			switch (event.keyCode) {
				case 39 :
					rear_motor_added.SetMotorSpeed(10);
					front_motor_added.SetMotorSpeed(10);
					break;
				case 37 :
					rear_motor_added.SetMotorSpeed(-10);
					front_motor_added.SetMotorSpeed(-10);
					break;
			}
		}
		public function debug_draw():void {
			var m_sprite:Sprite;
			m_sprite = new Sprite();
			addChild(m_sprite);
			var dbgDraw:b2DebugDraw = new b2DebugDraw();
			var dbgSprite:Sprite = new Sprite();
			m_sprite.addChild(dbgSprite);
			dbgDraw.SetSprite(m_sprite); // was dbgDraw.m_sprite=m_sprite;
			dbgDraw.SetDrawScale(30); // was dbgDraw.m_drawScale=30;
			//dbgDraw.SetAlpha(1); // was dbgDraw.m_alpha=1;
			dbgDraw.SetFillAlpha(0.5); // was dbgDraw.m_fillAlpha=0.5;
			dbgDraw.SetLineThickness(1); // was dbgDraw.m_lineThickness=1;
			dbgDraw.SetFlags(b2DebugDraw.e_shapeBit); // was dbgDraw.m_drawFlags=b2DebugDraw.e_shapeBit;
			world.SetDebugDraw(dbgDraw);
		}
		public function update(e : Event):void {
			world.Step(1/30,10,10);// was world.Step(1/30, 10);
			// this is new!
			world.ClearForces() 
			// this is new!!
			world.DrawDebugData();
		}
	}
}

Download the source code, new library included.

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