Box2D

(サンプル一覧を表示する)


[ライセンスの種類: zlib License]

Box2D は 2 次元の物理エンジンライブラリです。
複雑な計算式を意識することなく、物同士がぶつかったり跳ね返ったりする表示を行うことができます。


・AS3 Flash Physics Engine Box2DFlashAS3 2.0.1
http://box2dflash.sourceforge.net/
(ページのタイトルには 2.0.1 と書いてありますが、2.0.2 もリリースされています。)

・Box2D v2.0.2 User Manual
http://www.box2d.org/manual.html/

・asdoc 形式のドキュメント (英語)
http://hkpr.info/flash/lib/doc/box2d-2.0.2/

・Box2D(Box2DFlashAS3)によるActionScript物理シミュレーション | Flash | HapHands
http://www.haphands.com/sw_flash/tech/box2d/index.html

Flash の実行画面
Box2D

Flashプレーヤーが入っていないか、JavaScriptが無効になっているようです。

Get Adobe Flash player

Box2D
画面をクリックしてみてください。

ソースコード

package 
{
	import Box2D.Collision.b2AABB;
	import Box2D.Collision.Shapes.b2CircleDef;
	import Box2D.Collision.Shapes.b2PolygonDef;
	import Box2D.Common.Math.b2Vec2;
	import Box2D.Dynamics.b2Body;
	import Box2D.Dynamics.b2BodyDef;
	import Box2D.Dynamics.b2DebugDraw;
	import Box2D.Dynamics.b2World;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.text.TextField;
	import flash.text.TextFieldAutoSize;
	
	/**
	 * Box2D のサンプル
	 * @author Hikipuro
	 */
	public class Main extends Sprite 
	{
		/**
		 * Box2D の物理エンジン
		 */
		private var world:b2World;
		
		/**
		 * 画面からはみ出たボールの管理用
		 */
		private var circleArray:Array;
		
		/**
		 * ボールの個数表示用テキストフィールド
		 */
		private var textField:TextField;
		
		/**
		 * コンストラクタ
		 */
		public function Main():void 
		{
			if (stage) init();
			else addEventListener(Event.ADDED_TO_STAGE, init);
		}
		
		/**
		 * 初期化メソッド
		 * @param	e
		 */
		private function init(e:Event = null):void 
		{
			removeEventListener(Event.ADDED_TO_STAGE, init);
			// entry point
			
			// 変数の準備
			circleArray = new Array();
			
			// 外枠の準備
			var worldAABB:b2AABB = new b2AABB();
			worldAABB.lowerBound.Set(-100, -100);
			worldAABB.upperBound.Set(100, 100);
			
			// 重力を下方向に 10m/s^2 とする
			var gravity:b2Vec2 = new b2Vec2(0, 10);
			
			// 外枠と重力を指定して、物理エンジン全体をセットアップする
			world = new b2World(worldAABB, gravity, true);
			
			// ななめになっている床を設置
			addRectangleShape(1.3, 0.6, 1.2, 0.05, 2);
			addRectangleShape(1.9, 1.2, 1.2, 0.05, -2);
			addRectangleShape(1.3, 1.8, 1.2, 0.05, 2);
			
			// 左右の端にある壁の設置
			addRectangleShape(0.05, 1.2, 0.05, 1.2, 0);
			addRectangleShape(3.15, 1.2, 0.05, 1.2, 0);
			
			// 描画設定
			// 自分で作ったビットマップ画像も表示可能なようですが、
			// このサンプルでは Box2D ライブラリ内のデバッグ用画面を使用しています。
			var debugDraw:b2DebugDraw = new b2DebugDraw();
			debugDraw.m_sprite = this;
			debugDraw.m_drawScale = 100;	// 1m を 100 ピクセルにする
			debugDraw.m_fillAlpha = 0.3;	// 不透明度
			debugDraw.m_lineThickness = 1;	// 線の太さ
			debugDraw.m_drawFlags = b2DebugDraw.e_shapeBit;
			world.SetDebugDraw(debugDraw);
			
			// テキストフィールドの準備
			textField = new TextField();
			textField.autoSize = TextFieldAutoSize.LEFT;
			textField.textColor = 0xFFFFFF;
			textField.x = 11;
			textField.y = 220;
			addChild(textField);
			
			// イベントハンドラを登録する
			stage.addEventListener(MouseEvent.CLICK, onClick);
			addEventListener(Event.ENTER_FRAME, onEnterFrame);
		}
		
		/**
		 * 画面がクリックされた時のイベント
		 * @param	e
		 */
		private function onClick(e:MouseEvent):void 
		{
			var x:Number = Math.random() * 2 + 0.2;
			var y:Number = 0;
			
			// 画面にボールを追加
			var body:b2Body = addMovableCircle(
									x,		// 初期 X 座標
									y,		// 初期 Y 座標
									0.1,	// 半径
									1,		// 密度 kg/m^2
									0.6);	// 反発係数 (通常 0 から 1)
			
			// 画面からはみ出た時にチェックするために、配列に保存しておく
			circleArray.push(body);
		}
		
		/**
		 * フレーム開始イベント
		 * @param	e
		 */
		private function onEnterFrame(e:Event):void
		{
			if (world == null) {
				return;
			}
			
			// 物理シミュレーションを 1/30 秒進める
			world.Step(1 / 30, 10);
			
			// 画面からはみ出たボールを取り除く
			for (var key:String in circleArray)
			{
				var body:b2Body = circleArray[key];
				var vec2:b2Vec2 = body.GetPosition();
				if (vec2.y > 2.4) {
					world.DestroyBody(body);
					circleArray.splice(key, 1);
				}
			}
			
			textField.text = "画面に表示されている個数: " + circleArray.length;
		}
		
		/**
		 * 移動不可能な四角形を追加する
		 * @param	x		初期 X 座標
		 * @param	y		初期 Y 座標
		 * @param	width	横幅
		 * @param	height	縦幅
		 * @param	rotate	回転角度 (0 から 360)
		 * @return	作成された四角形
		 */
		private function addRectangleShape(
			x:Number, 
			y:Number, 
			width:Number, 
			height:Number, 
			rotate:Number):b2Body 
		{
			// 初期位置のセット
			var bodyDef:b2BodyDef = new b2BodyDef();
			bodyDef.position.Set(x, y);
			
			// 四角形を準備
			var polygoDef:b2PolygonDef = new b2PolygonDef();
			polygoDef.SetAsOrientedBox(width, height, new b2Vec2(0, 0), rotate * Math.PI / 180);
			
			// 四角形を動かない物体として作る
			var body:b2Body = world.CreateBody(bodyDef);
			body.CreateShape(polygoDef);
			
			return body;
		}
		
		/**
		 * 移動可能な円を追加する
		 * @param	x				初期 X 座標
		 * @param	y				初期 Y 座標
		 * @param	radius			半径
		 * @param	density			密度 kg/m^2
		 * @param	restitution		反発係数 (通常 0 から 1)
		 * @return	作成された円
		 */
		private function addMovableCircle(
			x:Number, 
			y:Number, 
			radius:Number, 
			density:Number, 
			restitution:Number):b2Body 
		{
			// 初期位置のセット
			var bodyDef:b2BodyDef = new b2BodyDef();
			bodyDef.position.Set(x, y);
			
			// 円を準備
			var circleDef:b2CircleDef= new b2CircleDef();
			circleDef.radius = radius;
			circleDef.density = density;
			circleDef.restitution = restitution;
			
			// 円を動く物体として作る
			var body:b2Body = world.CreateBody(bodyDef);
			body.CreateShape(circleDef);
			body.SetMassFromShapes();
			
			return body;
		}
	}
}
		


FlashDevelop で外部ライブラリを使用するときは、 lib フォルダに SWC ファイルを追加した後、右クリックして "Add To Library" を選択してください。

ライブラリの設定 1


ライブラリ名が青くなったら、ビルド時に使用されるようになります。

ライブラリの設定 2

外部リンク