Skip to main content
GameDev.net gamedev.net

PRO Tired of ads? Read GameDev.net ad-free and help keep the community independent with GameDev Pro — $3/month.

Box2D in Flash

Box2D in Flash

dx elliot
dx elliot
Journal of dx elliot · · 5 min read
2,149 0
I finished the development of Xmas sliders a couple weeks ago and submitted it to to the Apple store. It is awaiting a review.

My experience submitting a game for the iPhone/iPad is a bit sour, though the development was fairly easy. I have heard that the process to submit a finished app has improved, but it took many long and painful hours sifting through outdated documentation to make it this far.

Anyways, in the meantime I coded up this simple demo in Action Script 3 using Box2DFlash. It is only 150 lines of code. I did the art myself, as inspired by some recent games like Angry Birds:

//===========================================================================// Elliot Pace// This software code uses the zlib License - http://en.wikipedia.org/wiki/Zlib_License// This software uses the Box2D physics library for Action Script "Box2DFlashAS3" - http://sourceforge.net/projects/box2dflash/// Box2DFlashAS3 is a physics library for Flash built from Eric Catto's Box2D library under the zlib license - http://www.box2dflash.org///// Copyright (c) 2010 Elliot Pace http://www.elliotpace.com// *// * This software is provided 'as-is', without any express or implied// * warranty.  In no event will the authors be held liable for any damages// * arising from the use of this software.// * Permission is granted to anyone to use this software for any purpose,// * including commercial applications, and to alter it and redistribute it// * freely, subject to the following restrictions:// * 1. The origin of this software must not be misrepresented; you must not// * claim that you wrote the original software. If you use this software// * in a product, an acknowledgment in the product documentation would be// * appreciated but is not required.// * 2. Altered source versions must be plainly marked as such, and must not be// * misrepresented as being the original software.// * 3. This notice may not be removed or altered from any source distribution.//===========================================================================package {	import Box2D.Collision.b2AABB;	import Box2D.Collision.Shapes.b2MassData;	import Box2D.Collision.Shapes.b2PolygonDef;	import Box2D.Collision.Shapes.b2PolygonShape;	import Box2D.Common.Math.b2Vec2;	import Box2D.Dynamics. b2Body;	import Box2D.Dynamics.b2BodyDef;	import Box2D.Dynamics.b2World;	import flash.display.Bitmap;	import flash.display.Sprite;	import flash.events.Event;	import flash.geom.Matrix;	import flash.geom.Matrix3D;		public class Main extends Sprite {		// This will "embed" these assets into the swf file - which means once you build the swf flash file, you will not		// need to include these files!		[Embed(source = '../data/bg.jpg')]				private var imgBG:Class;		[Embed(source = '../data/box.jpg')]				private var imgBox:Class;				// There may be functions available for this elsewhere, but multiply angles by these to convert them		private static const m_todegrees:Number = 57.2957795;		private static const m_toradians:Number = 0.0174532925;				// I like to just hard code the width and height rather than access it by some other means.		// These values never change on runtime anyways.		// The location of the top left of the window is (0,0).  The bottom right is (m_width, m_height).		private static const m_width:Number = 512;		private static const m_height:Number = 512;		private var m_dt:Number = 1.0 / 50.0;				private var m_world:b2World;		// Total time in seconds since we initialized.		private var m_time:Number = 0.0;		private var m_bodies:Array = new Array();				public function Main():void {			// The game begins here!!			if (stage) Init();			else addEventListener(Event.ADDED_TO_STAGE, Init);		}				// Creates a Box2D rigid body (of type b2Body) and includes a reference to the bitmap instance for rendering.		private function createBody(_x:Number, _y:Number, _width:Number, _height:Number, _density:Number, _visible:Boolean, _bitmap:Class):b2Body		{						var bodyDef:b2BodyDef = new b2BodyDef();			bodyDef.position.Set(_x, _y);						var body:b2Body = m_world.CreateBody(bodyDef);			var shapeDef:b2PolygonDef = new b2PolygonDef();			shapeDef.SetAsBox(_width * 0.5, _height * 0.5);			shapeDef.density = _density;			shapeDef.friction = 0.6;			shapeDef.restitution = 0.5;			body.CreateShape(shapeDef);			body.SetMassFromShapes();						if (_visible) {				var graphic:Bitmap = new _bitmap();				addChild(graphic);				body.SetUserData(graphic);			}						m_bodies.push(body);						return body;		}				private function Init(_event:Event = null):void {			// Create the background first so it gets displayed first.  Everything else			// gets drawn on top.			addChild(new imgBG());						// Create world that all the physics objects will be contained in.			// In some games, multiple worlds may be a good idea.			var worldAABB:b2AABB = new b2AABB();			worldAABB.lowerBound.Set(-1000.0, -1000.0);			worldAABB.upperBound.Set(1000.0, 1000.0);			var gravity:b2Vec2 = new b2Vec2(0.0, 100.0);			m_world = new b2World(worldAABB, gravity, false);						var body:b2Body;			body = createBody(m_width / 2.0, m_height - 50.0, m_width, 8.0, 0.0, false, null);			body = createBody(-4, m_height * 0.5, 8, m_height, 0.0, false, null);			body = createBody(m_height+4, m_height*0.5, 8, m_height, 0.0, false, null);						body = createBody(m_width / 2.0, 100.0, 64.0, 64.0, 1.0, true, imgBox);			body.SetAngularVelocity(Math.random() * 4.0);						body = createBody(m_width / 2.0 + 100, 100.0, 64.0, 64.0, 1.0, true, imgBox);			body.SetAngularVelocity(Math.random() * 4.0);						body = createBody(m_width / 2.0 - 100, 100.0, 64.0, 64.0, 1.0, true, imgBox);						removeEventListener(Event.ADDED_TO_STAGE, init);			addEventListener(Event.ENTER_FRAME, Tick);		}				private function Tick(_event:Event = null):void {			var i:int;			var body:b2Body;			var sprite:Bitmap;						for (i = 0; i < m_bodies.length; i++) {				body = m_bodies;				sprite = body.GetUserData();				if (sprite != null) {					var matrix:Matrix = new Matrix();					// Offset so origin is at center of box.  Then it makes sense to rotate, and then translate.					// This is necessary because the position of a Bitmap is actually the top left corner.					matrix.translate( -sprite.bitmapData.width*0.5, -sprite.bitmapData.height*0.5 );					matrix.rotate(body.GetAngle());					matrix.translate(body.GetPosition().x, body.GetPosition().y);					sprite.transform.matrix = matrix;				}			}						// Integrate the physics objects.			// * Change the 2.0 to anything if you want to make the physics simulation run faster.			//   Yes, it is incorrect for me to be running the physics simulation at twice the speed, but it is an approximation of the real world anyways.			// * Change the 5 to an integer greater if you want to improve the reliability of the physics simulation at the cost of performance.			m_world.Step(m_dt * 2.0, 5);			m_time += m_dt;		}	}}




physicstest.swf

Download: physicstest.zip

The project file can be opened with FlashDevelop, which is an Action Script editor. I installed a trial version of Adobe Flash for the FLEX SDK and then I installed Flash Develop. It worked for me, I hope it works for you. Sometimes the boxes vibrate.. anyone know a fix for that? Anyways, let me know if you have any questions or troubles.

Discussion

Loading comments...