In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

b2BoundaryListener Tutorial

Creating too much instances of b2Body does no good
on performances. You should clean up discarded objects.
By implementing b2BoundaryListener, you can easily detect
when an object has gone outside of the world. 

@see http://www.box2d.org/manual.html#world_boundary
Get Adobe Flash player
by 9re 19 Oct 2009
/**
 * Copyright 9re ( http://wonderfl.net/user/9re )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/rnRe
 */

package  
{
	import Box2D.Collision.b2AABB;
	import Box2D.Collision.Shapes.b2PolygonDef;
	import Box2D.Collision.Shapes.b2ShapeDef;
	import Box2D.Common.Math.b2Vec2;
	import Box2D.Dynamics.b2Body;
	import Box2D.Dynamics.b2BodyDef;
	import Box2D.Dynamics.b2World;
	import flash.display.Sprite;
	import flash.display.StageAlign;
	import flash.display.StageScaleMode;
	import flash.events.Event;
	import flash.events.TimerEvent;
	import flash.text.TextField;
	import flash.text.TextFormat;
	import flash.utils.Timer;
	import net.hires.debug.Stats;
	/**
	 * Creating too much instances of b2Body does no good
	 * on performances. You should clean up discarded objects.
	 * By implementing b2BoundaryListener, you can easily detect
	 * when an object has gone outside of the world. 
	 * 
	 * @see http://www.box2d.org/manual.html#world_boundary
	 */
	[SWF(frameRate="30")]
	public class b2BoundaryListenerTutorial extends Sprite
	{
		private var _itemLayer:Sprite;
		private var _size:int;
		private var _sw:int;
		private var _timer:Timer;
		private var _tf:TextField;
		private var _world:b2World;
		
		public function b2BoundaryListenerTutorial() 
		{
			addChild(_itemLayer = new Sprite);
			addChild(_tf = new TextField);
			addChild(new Stats);
			
			stage.align = StageAlign.TOP_LEFT;
			stage.scaleMode = StageScaleMode.NO_SCALE;
			
			_sw = Math.max(465, stage.stageWidth);
			var sh:int = Math.max(464, stage.stageHeight);
			_size = Math.max(_sw, sh);
			
			_tf.width = _sw;
			_tf.y = 100;
			_tf.defaultTextFormat = new TextFormat("_sans", 12, 0xff0000);
			_tf.mouseEnabled = _tf.selectable = false;
			
			
			var worldAABB:b2AABB = new b2AABB;
			worldAABB.lowerBound.Set( -20, -20);
			worldAABB.upperBound.Set(_size / 10 + 10, _size / 10 + 10);
			
			_world = new b2World(worldAABB, new b2Vec2(0, 9.8), true);
			// set the boundary listner
			_world.SetBoundaryListener(new MyBoundaryListener);
			
			var shapeDef:b2PolygonDef = new b2PolygonDef;
			shapeDef.vertexCount = 3;
			shapeDef.vertices[0].Set(0, -2);
			shapeDef.vertices[1].Set(_sw / 20, 1);
			shapeDef.vertices[2].Set( -_sw / 20, 1);
			
			var bodyDef:b2BodyDef = new b2BodyDef;
			bodyDef.position.Set(_sw / 20, sh / 10 - 2);
			
			var body:b2Body = _world.CreateBody(bodyDef);
			body.CreateShape(shapeDef);
			
			_timer = new Timer(200);
			_timer.addEventListener(TimerEvent.TIMER, onTimer);
			_timer.start();
			
			
			addEventListener(Event.ENTER_FRAME, enterFrameHandler);
		}
		
		private function onTimer(e:TimerEvent):void 
		{
			var r:Number = 1 + Math.random();
			var pos:b2Vec2 = new b2Vec2(_sw / 10 * Math.random(), -r);
			var bc:BlackCircle = BlackCircle.createBody(r, pos, _world).GetUserData();
			bc.x = pos.x * 10;
			bc.y = pos.y * 10;
			_itemLayer.addChild(bc);
			_tf.text = "the number of bodies created: " + _world.GetBodyCount();
		}
		
		private function enterFrameHandler(e:Event):void 
		{
			_world.Step(1 / 30, 8);
			var bc:BlackCircle;
			var ud:*;
			for (var i:b2Body = _world.GetBodyList(); i; i = i.GetNext()) {
				ud = i.GetUserData();
				if (ud is BlackCircle) {
					bc = ud as BlackCircle;
					bc.x = i.GetWorldCenter().x * 10;
					bc.y = i.GetWorldCenter().y * 10;
					// Destroy the body when destroy flag is set
					if (bc.destroyFlag) {
						_itemLayer.removeChild(bc);
						_world.DestroyBody(i);
					}
				}
			}
		}
	}
}

import Box2D.Collision.Shapes.b2CircleDef;
import Box2D.Dynamics.b2Body;
import Box2D.Dynamics.b2BodyDef;
import Box2D.Dynamics.b2BoundaryListener;
import Box2D.Dynamics.b2World;
import flash.display.Sprite;

class BlackCircle extends Sprite {
	public var destroyFlag:Boolean = false;
	public function BlackCircle($radius:int) {
		graphics.beginFill(0);
		graphics.drawCircle(0, 0, $radius);
		graphics.endFill();
	}
	
	public static function createBody($radius:Number, $position:Box2D.Common.Math.b2Vec2, $world:b2World):b2Body {
		var shapeDef:b2CircleDef = new b2CircleDef;
		shapeDef.radius = $radius;
		shapeDef.density = 3;
		shapeDef.restitution = 0.3;
		
		var bodydef:b2BodyDef = new b2BodyDef;
		bodydef.position.SetV($position);
		
		var body:b2Body = $world.CreateBody(bodydef);
		body.CreateShape(shapeDef);
		body.SetMassFromShapes();
		body.SetUserData(new BlackCircle($radius * 10));
		
		return body;
	}
}


/**
 * Deleting bodies in the callback Violation is not
 * recommended. Use flag and destroy bodies after
 * the physics time step instead.
 * 
 * @see http://www.box2d.org/manual.html#world_boundary
 */
class MyBoundaryListener extends b2BoundaryListener {
	override public function Violation(body:b2Body):void 
	{
		var ud:* = body.GetUserData();
		if (ud is BlackCircle) {
			var bc:BlackCircle = ud as BlackCircle;
			bc.destroyFlag = true;
		}
	}
}