Box2Dでサンプルアプリを作ってみました。

Box2Dでサンプルアプリを作ってみました。
こんな感じ。
http://moeten.info/flex/20080926_moetenBox2DTest/bin-release/

まだ、使ってない機能がたくさんあるので勉強です。
ソースは右クリックかこちら↓

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
    layout="absolute" creationComplete="init()"
    backgroundAlpha="0.5" backgroundColor="0xffffff"
    backgroundGradientAlphas="[1,1]" backgroundGradientColors="[0xffffff,0x000000]"
    horizontalScrollPolicy="off" verticalScrollPolicy="off" viewSourceURL="srcview/index.html">
<mx:Script>
<![CDATA[
[Bindable]private var server:String = "moeten.info";
[Bindable]private var site:String   = "maidcafe";
private function init():void{
    if( this.parameters.site )  site   = this.parameters.site;
    if( this.parameters.server )server = this.parameters.server;
    hts.send({"tid":13,"cid":1});
    htsTid.send({"tid":"list"});
    htsCid.send({"cid":"list",
                "tid":13
    });
    pBar.visible = true;
}
private function onHtsResult():void{
    initBox2D();
}
private function onTidChange():void{
    htsCid.send({
            "tid":tidBox.selectedItem.tid,
            "cid":"list"
    });
    hts.send({"tid":tidBox.selectedItem.tid});
    pBar.visible = true;
}
private function onCidChange():void{
    pBar.visible = true;
    hts.send({
            "tid":tidBox.selectedItem.tid,
            "cid":cidBox.selectedItem.cid
    });
}
//HTTP結果イベント
private function onTidResult():void{
    showCidBox.play([tidBox]);
    pBar.visible = false;
    var len:int = htsTid.lastResult.item.length();
    for( var i:int = 0 ; i < len ; i ++ ){
//        trace( htsTid.lastResult.item[i].tid );
        if( htsTid.lastResult.item[i].tid == 13 ){
            tidBox.selectedIndex = i;
            return;
        }
    }
    return;
}
private function onCidResult():void{
    showCidBox.play([cidBox]);
    pBar.visible = false;
}
private function onResult():void{
    initBox2D();
    pBar.visible = false;
}
//フルスクリーン
private function setFullscreen():void{
    switch(stage.displayState) {
        case "normal":
            stage.displayState = StageDisplayState.FULL_SCREEN;
            break;
        case "fullScreen":
        default:
            stage.displayState = "normal";
        break;
    }
}
/* ******************************
    Box2D
****************************** */
import Box2D.Collision.*;
import Box2D.Collision.Shapes.*;
import Box2D.Common.Math.*;
import Box2D.Dynamics.*;
import Box2D.Dynamics.Joints.*;
import General.*;
private function initBox2D():void{
    //Box2D初期化
    setWorld();
    //自分のメイン部分
    //オブジェクト作成
    setAllCircle();
    //壁作成
    setAllWall();
    //描画+デバッグ
    setSprite();
//    setDebug();
    this.addEventListener(Event.ENTER_FRAME , EnterFrame );
}
private var m_world:b2World;
private var m_iterations:int  = 10;
private var m_timeStep:Number = 1.0/14.0;
public var m_physScale:Number = 30;
private function setWorld():void{
    m_sprite = new Sprite();
    var len:Number = myUI.numChildren;
    for( var i:int = 0 ; i < len  ; i ++ ){
        myUI.removeChildAt(i);
    }
    //ワールドを定義する
    //--ワールドの広さ。この範囲の外に出たオブジェは物理演算されなくなる--
    var worldAABB:b2AABB = new b2AABB();
    worldAABB.lowerBound.Set(-100.0, -100.0);
    worldAABB.upperBound.Set( 100.0,  100.0);
    //-- 重力の強さ、方向の設定 --
    var gravity:b2Vec2 = new b2Vec2(0.0, 10.0);
    //-- 一定時間動きがない場合スリープにするかどうか --
    var doSleep:Boolean = true;
    //-- ワールド定義 --
     m_world = new b2World(worldAABB, gravity, doSleep);
}
private var onMouse:Boolean = false;
private function setGround():void{
    //--------------------------------------------
    //          地面を作る
    //--------------------------------------------
    var bodyDef:b2BodyDef;
    bodyDef = new b2BodyDef();  //Bodyの定義
    bodyDef.position.Set(0, this.height/m_physScale);  //位置(座標)
    var boxDef:b2PolygonDef;
    boxDef = new b2PolygonDef();  //Polygonの定義
    boxDef.SetAsBox(this.width/m_physScale, 3);  //形状
    boxDef.friction = 0.3; //摩擦力
    boxDef.density  = 0;  //静的な物体を作る場合は密度を0に
    var body:b2Body;
    body = m_world.CreateBody(bodyDef);
    body.CreateShape(boxDef);  //boxDefをBodyに設定する(無いと貫通する)
    body.SetMassFromShapes(); //形状と密度から物体の質量を定義
}
private function setAllWall():void{
    //--------------------------------------------
    //          壁を作る
    //--------------------------------------------
    setWall( 0 , this.height - 50, this.width ,40);
    setWall(10,10,100,this.height-110);
    setWall(this.width-10,10,100,this.height-110);
    setWall( 410, 180 ,10 ,20);
    setWall( 490, 180 ,10 ,20);
    setWall( 450, 220 ,50 ,10);
}
private function setWall( x:Number , y:Number , w:Number , h:Number ):void{
    //--------------------------------------------
    //          壁を作る
    //--------------------------------------------
    var bodyDef:b2BodyDef;
    bodyDef = new b2BodyDef();  //Bodyの定義
    bodyDef.position.Set(x/m_physScale, y/m_physScale);  //位置(座標)
    var boxDef:b2PolygonDef;
    boxDef = new b2PolygonDef();  //Polygonの定義
    boxDef.SetAsBox( w/m_physScale, h/m_physScale);  //形状
    boxDef.friction = 0.3; //摩擦力
    boxDef.density  = 0;  //静的な物体を作る場合は密度を0に
    var body:b2Body;
    body = m_world.CreateBody(bodyDef);
    body.CreateShape(boxDef);  //boxDefをBodyに設定する(無いと貫通する)
    body.SetMassFromShapes(); //形状と密度から物体の質量を定義
}
private function setAllCircle():void{
    //--------------------------------------------
    //          円を作る
    //--------------------------------------------
    var len:int = hts.lastResult.item.length();
    for( var i:int = 0 ; i < len ; i ++ ){
        setCircle( i , hts.lastResult.item[i].shopname , hts.lastResult.item[i].image.image1 );
    }
}
private function setCircle( i:int , shopname:String ,  fname:String):void{
    //--------------------------------------------
    //          円を作る
    //--------------------------------------------
    var sp:Sprite = new Sprite();
    var dsf:DropShadowFilter = new DropShadowFilter(0,0);
    var gf:GlowFilter        = new GlowFilter( 0xffffff,1,6,6,10);
//    sp.filters = [gf,dsf];
//    var r:int = int( Math.random() * 20 ) + 10;
    var r:int = 30;
    var myMask:Sprite = new Sprite();
    myMask.graphics.beginFill(0xeeeeee,1);
    myMask.graphics.drawCircle(0,0,r);
    myMask.graphics.endFill();
    sp.name = shopname;
    sp.addChild( myMask );
    var loader:Loader = new Loader();
    loader.load( new URLRequest( fname ) );
    loader.contentLoaderInfo.addEventListener(Event.COMPLETE , function ():void{
        var bd:BitmapData = new BitmapData( 2*r , 2*r );
        var mat:Matrix = new Matrix();
        mat.scale(0.5,0.5);
        bd.draw( loader.content , mat );
        var bm:Bitmap = new Bitmap( bd );
        bm.cacheAsBitmap = true;
        bm.x = -r;
        bm.y = -r;
        sp.addChild( bm );
        bm.mask = myMask;
    });
    //動く円形オブジェクトを作成
    var circleDef:b2CircleDef=new b2CircleDef();
    // 大きさ、密度、摩擦力、反発力などを設定。
    circleDef.radius      = r / m_physScale;
    circleDef.density     = 1.0;
    circleDef.friction    = 1.0 ;
    circleDef.restitution = 0.2 ;
    // Bodyを入れる箱を用意。位置はここで指定
    var circleBD:b2BodyDef=new b2BodyDef();
    circleBD.position.Set( Math.random()*this.width/m_physScale , Math.random()*200 /this.height/ m_physScale );
    // 円を保存
    circleBD.userData        = sp;
    circleBD.userData.width  = 2*r;
    circleBD.userData.height = 2*r;
    circleBD.userData.name   = "" + i + "_"  + shopname;
    m_sprite.addChild(circleBD.userData);
    // Bodyを生成して、Box2Dのworldに落とし込む
    var circle:b2Body=m_world.CreateBody( circleBD );
    circle.CreateShape( circleDef );
    circle.SetMassFromShapes();
    circleArr[i] = circleBD;
     sp.addEventListener(MouseEvent.ROLL_OVER , function( e:Event ):void{
         onMouse = true;
         myName.text = e.target.name
        myName.visible = true;
     });
    sp.addEventListener(MouseEvent.ROLL_OUT , function( e:Event ):void{
        onMouse = false;
        myName.visible = false;
     });
     sp.doubleClickEnabled = true;
    sp.addEventListener(MouseEvent.DOUBLE_CLICK , function( e:Event ):void{
        dg.dataProvider = hts.lastResult.item[i];
        dg.visible = true;
    });
     sp.addEventListener(MouseEvent.MOUSE_MOVE , function( e:Event ):void{
         myName.visible = true;
         if( onMouse ){
            myName.x = (myUI.mouseX) - 20;
            myName.y = (myUI.mouseY) - 50;
        }
     });
}
private var circleArr:Array = new Array();
//--------------------------------------------
//          EnterFrameで物理演算を処理する
//--------------------------------------------
private function EnterFrame(event:Event):void{
    UpdateMouseWorld();
    MouseDrag();
    m_world.Step(m_timeStep, m_iterations);   //物理演算の更新
    // 実際の描写作業
    for (var bb:b2Body = m_world.m_bodyList; bb; bb = bb.m_next) {
        if(bb.m_userData is Sprite) {
            bb.m_userData.x = (bb.GetPosition().x)* m_physScale;
            bb.m_userData.y = (bb.GetPosition().y)* m_physScale;
            bb.m_userData.rotation = bb.GetAngle()*(180/Math.PI);
            if( Math.abs(bb.m_userData.x - 450) < 3 && Math.abs(bb.m_userData.y - 180 ) < 3 ){
                if( nowname != bb.m_userData.name ){
                    var i:int = int( String(bb.m_userData.name).split( "_")[0]);
                       nowname = bb.m_userData.name;
                       dg.dataProvider = hts.lastResult.item[i];
                       dg.visible = true;
                }else{
                }
            }
        }
    }
}
private var nowname:String = null;
private var m_sprite:Sprite = new Sprite(); //グラフィック表示用のSpriteを作成
private function setSprite():void{
    //--------------------------------------------
    //           ラインで表示する(デバッグ描写の使用)
    //--------------------------------------------
    var dbgDraw:b2DebugDraw = new b2DebugDraw(); //b2DebugDrawクラスの定義
    dbgDraw.m_sprite = m_sprite; //デバッグを描くSpriteを設定
    dbgDraw.m_drawScale = 30.0; //画面に描く倍率
    dbgDraw.m_fillAlpha = 0.3; // 塗りの透明度
    dbgDraw.m_lineThickness = 1.0; // ラインの太さ
    dbgDraw.m_drawFlags = b2DebugDraw.e_shapeBit | b2DebugDraw.e_jointBit; // 物体、ジョイントを表示するかどうか
    m_world.SetDebugDraw(dbgDraw);
    myUI.addChild(m_sprite); //表示用のSpriteをステージの表示リストに追加
    m_input = new InputFlex(m_sprite); // マウス状態を取得するクラス
}
//-------------マウス操作。以下はTestクラスから引用---------------------
private var m_input:InputFlex;
private var mousePVec:b2Vec2 = new b2Vec2();
private var mouseXWorldPhys:Number; // ワールド内でのマウス座標
private var mouseYWorldPhys:Number; // ワールド内でのマウス座標
private var mouseXWorld:Number; //m_sprite内でのマウス座標
private var mouseYWorld:Number; //m_sprite内でのマウス座標
private var m_mouseJoint:b2MouseJoint;
//======================
// Update mouseWorld
//======================
private function UpdateMouseWorld():void{
    mouseXWorldPhys = (InputFlex.mouseX)/m_physScale;
    mouseYWorldPhys = (InputFlex.mouseY)/m_physScale;
    mouseXWorld = (InputFlex.mouseX);
    mouseYWorld = (InputFlex.mouseY);
//    trace(Input.mouseX , Input.mouseY)
}
//======================
// Mouse Drag
//======================
private function MouseDrag():void{
    //trace(Input)
    // mouse press
    if (InputFlex.mouseDown && !m_mouseJoint){
        var body:b2Body = GetBodyAtMouse();
        if (body)
        {
            var md:b2MouseJointDef = new b2MouseJointDef();
            md.body1 = m_world.m_groundBody;
            md.body2 = body;
            md.target.Set(mouseXWorldPhys, mouseYWorldPhys);
            md.maxForce = 300.0 * body.m_mass;
            md.timeStep = m_timeStep;
            m_mouseJoint = m_world.CreateJoint(md) as b2MouseJoint;
            body.WakeUp();
        }
    }
    // mouse release
    if (!InputFlex.mouseDown){
        if (m_mouseJoint)
        {
            m_world.DestroyJoint(m_mouseJoint);
            m_mouseJoint = null;
        }
    }
    // mouse move
    if (m_mouseJoint)
    {
        var p2:b2Vec2 = new b2Vec2(mouseXWorldPhys, mouseYWorldPhys);
        m_mouseJoint.SetTarget(p2);
    }
}
//======================
// GetBodyAtMouse
//======================
private function GetBodyAtMouse(includeStatic:Boolean=false):b2Body{
    // Make a small box.
    mousePVec.Set(mouseXWorldPhys, mouseYWorldPhys);
    var aabb:b2AABB = new b2AABB();
    aabb.lowerBound.Set(mouseXWorldPhys - 0.001, mouseYWorldPhys - 0.001);
    aabb.upperBound.Set(mouseXWorldPhys + 0.001, mouseYWorldPhys + 0.001);
    // Query the world for overlapping shapes.
    var k_maxCount:int = 10;
    var shapes:Array = new Array();
    var count:int = m_world.Query(aabb, shapes, k_maxCount);
    var body:b2Body = null;
    for (var i:int = 0; i < count; ++i)
    {
        if (shapes[i].m_body.IsStatic() == false || includeStatic)
        {
            var tShape:b2Shape = shapes[i] as b2Shape;
            var inside:Boolean = tShape.TestPoint(tShape.m_body.GetXForm(), mousePVec);
            if (inside)
            {
                body = tShape.m_body;
                break;
            }
        }
    }
    return body;
}
// デバッグ用の関数
public function setDebug():void{
    var dbgDraw:b2DebugDraw = new b2DebugDraw();
    var dbgSprite:Sprite = new Sprite();
    myUI.addChild(dbgSprite);
    dbgDraw.m_sprite=dbgSprite;
    dbgDraw.m_drawScale=m_physScale;
    dbgDraw.m_fillAlpha=0.5;
    dbgDraw.m_lineThickness=0;
    dbgDraw.m_drawFlags=0xFFFFFFFF;
    m_world.SetDebugDraw(dbgDraw);
}
]]>
</mx:Script>
<mx:HTTPService id="hts" url="{'http://'+server+'/'+site+'/?m=api&amp;type=shop'}"
    resultFormat="e4x" result="onResult()"/>
<mx:HTTPService id="htsTid" url="{'http://'+server+'/'+site+'/?m=api&amp;type=shop'}"
    resultFormat="e4x" result="onTidResult()"/>
<mx:HTTPService id="htsCid" url="{'http://'+server+'/'+site+'/?m=api&amp;type=shop'}"
    resultFormat="e4x" result="onCidResult()"/>
<mx:Sequence id="showCidBox">
    <mx:WipeRight/>
    <mx:Glow alphaFrom="1" alphaTo="0" blurXFrom="20" blurYFrom="20" blurXTo="0" blurYTo="0" color="0xffffff"/>
</mx:Sequence>
<mx:UIComponent id="myUI" width="100%" height="100%"/>
<mx:ProgressBar themeColor="#666666" indeterminate="true" id="pBar" label="" trackHeight="10" width="100%" visible="false"/>
<mx:TextInput id="myName" cornerRadius="5" backgroundAlpha="0.8" backgroundColor="0x333333"
    borderColor="0x000000" borderStyle="solid" borderThickness="3" color="0xffffff"
    editable="false" visible="false" mouseEnabled="false"/>
<mx:ComboBox id="tidBox" x="20"  y="26" width="142" prompt="都道府県" rowCount="10"
    dataProvider="{htsTid.lastResult.item}" labelField="todouhuken" change="onTidChange()"
    />
<mx:ComboBox id="cidBox" x="170" y="26" width="150" prompt="カテゴリー" rowCount="10"
    dataProvider="{htsCid.lastResult.item}" labelField="category" change="onCidChange()"
    />
<mx:TileList id="dg" x="20" y="100" width="300" height="508" itemRenderer="shopDetail" visible="false" backgroundAlpha="0.8"
    cornerRadius="5" borderColor="0x333333" borderStyle="solid" borderThickness="3" showEffect="WipeUp" hideEffect="WipeUp"
    selectable="false"/>
</mx:Application>