Hatena::Groupfukuoka-as

shikajiro.as このページをアンテナに追加 RSSフィード

2008-11-16

BOX2DをAIRで使う。

| 00:47 | BOX2DをAIRで使う。 - shikajiro.as を含むブックマーク はてなブックマーク - BOX2DをAIRで使う。 - shikajiro.as BOX2DをAIRで使う。 - shikajiro.as のブックマークコメント

物理エンジンAIRで動かしてみるよ!

Box2DでActionScript物理プログラミングを読みながらやるよ。

サンプルはSpriteをextendsしてるけど、AIRでは使えないからUIComponentをextendsするのがみそだよ!

<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication 
xmlns:mx="http://www.adobe.com/2006/mxml" 
layout="absolute"
xmlns:local="*"
windowComplete="addPudding()">
	<local:DropBox id="sprite" x="0" y="0" width="500" height="300" />
	<mx:Script>
		<![CDATA[
			import Box2D.Dynamics.b2DebugDraw;
			import Box2D.Dynamics.b2Body;
			import Box2D.Collision.Shapes.b2PolygonDef;
			import Box2D.Dynamics.b2BodyDef;
			import Box2D.Dynamics.b2World;
			import Box2D.Common.Math.b2Vec2;
			import Box2D.Collision.b2AABB;
			import mx.controls.Image;
			private var world:b2World;
			
			public function addPudding():void{
				stage.addEventListener(MouseEvent.CLICK, sprite.clickHandler);
			}
		]]>
	</mx:Script>
</mx:WindowedApplication>

package  {
	import Box2D.Collision.Shapes.b2PolygonDef;
	import Box2D.Collision.b2AABB;
	import Box2D.Common.Math.b2Vec2;
	import Box2D.Dynamics.b2Body;
	import Box2D.Dynamics.b2BodyDef;
	import Box2D.Dynamics.b2DebugDraw;
	import Box2D.Dynamics.b2World;
	
	import flash.events.Event;
	import flash.events.MouseEvent;
	
	import mx.core.Application;
	import mx.core.UIComponent;
	
	/**
	 * 床の上に箱を落とすFlash
	 */
	public class DropBox extends UIComponent {
		private var world:b2World;
		
		public function DropBox():void {
			trace("const");
			// イベントハンドラを登録する
//			Application.application.stage.addEventListener(MouseEvent.CLICK, clickHandler);
			addEventListener(Event.ENTER_FRAME, enterFrameHandler);
		}
		
		public function clickHandler(event:MouseEvent):void {
			trace("click");
			////////////////////////////////////////
			// 物理エンジンのセットアップ
			
			// 外枠を定義する
			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);
			
			////////////////////////////////////////
			// 床の設置
			// 床は画面の下のほうに設置します
			
			// 床の位置を左から2.5m、上から3mとする
			var floorBodyDef:b2BodyDef = new b2BodyDef();
			floorBodyDef.position.Set(2.5, 3);
			
			// 床の形を、幅4m、厚さ20cmとする
			// 指定するのはその半分の値
			var floorShapeDef:b2PolygonDef = new b2PolygonDef();
			floorShapeDef.SetAsBox(2, 0.1);
			
			// 床を動かない物体として作る
			var floor:b2Body = world.CreateBody(floorBodyDef);
			floor.CreateShape(floorShapeDef);
			
			////////////////////////////////////////
			// 箱の設置
			// 箱は床の上から落として、少しはねるようにします
			
			// 箱の位置を左から2.5m、上から1mとする
			var boxBodyDef:b2BodyDef = new b2BodyDef();
			boxBodyDef.position.Set(2.5, 1);
			
			// 箱の形を、幅60cm、高さ40cmとして45度ぐらい右に回す
			var boxShapeDef:b2PolygonDef= new b2PolygonDef();
			boxShapeDef.SetAsOrientedBox(0.3, 0.2, new b2Vec2(0, 0), 0.8);
			boxShapeDef.density = 1;        // 密度 [kg/m^2]
			boxShapeDef.restitution = 0.2;  // 反発係数、通常は0~1
			
			// 箱を動く物体として作る
			var boxBody:b2Body = world.CreateBody(boxBodyDef);
			boxBody.CreateShape(boxShapeDef);
			boxBody.SetMassFromShapes();
			
			////////////////////////////////////////
			// 描画設定
			
			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);
		}
		
		private function enterFrameHandler(event:Event):void {
			if (world == null) {
				return;
			}
			// Flashはデフォルトで秒間24フレームなので、
			// 物理シミュレーションを1/24秒進める
			world.Step(1 / 24, 10);
		}
	}
}

ゲスト



トラックバック - http://fukuoka-as.g.hatena.ne.jp/re_shikajiro/20081116