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

wonderfl用Box2Dテンプレートを作ってみたい。Ver0.1

wonderfl用Box2Dテンプレートを作ってみたい。Ver0.1

最近少し忙しいのでちょこちょことやる予定。
Box2Dはいろいろ手続きが面倒すぎるので、楽しいところだけ弄れるようにしたい。

ここを大いに参考にしてるというか、ほぼそのまま・・・。
でも、ここからいろいろ拡張していきたい。できるのかは知らないけれど。
http://hokori.net/2009/02/18/box2dflashas3_base/
Get Adobe Flash player
by Hiiragi 03 Jul 2009
package  
{
	import flash.display.Sprite;
	import Box2D.Collision.*;
	import Box2D.Common.Math.*;
	import Box2D.Dynamics.*;
	import Box2D.Collision.Shapes.*;
	import flash.events.Event;

	/**
	 * wonderfl用Box2Dテンプレートを作ってみたい。Ver0.1
	 * 
	 * 最近少し忙しいのでちょこちょことやる予定。
	 * Box2Dはいろいろ手続きが面倒すぎるので、楽しいところだけ弄れるようにしたい。
	 * 
	 * ここを大いに参考にしてるというか、ほぼそのまま・・・。
	 * でも、ここからいろいろ拡張していきたい。できるのかは知らないけれど。
	 * http://hokori.net/2009/02/18/box2dflashas3_base/
	 */
	[SWF(width=465,height=465,frameRate=60,backgroundColor=0x000000)]
	public class Test extends Sprite
	{
		//固定プロパティ
		private var _world:b2World;
		private var _catalystObj:B2DCatalyst;
		
		//設定用プロパティ
		private const WIDTH:Number = 465;
		private const HEIGHT:Number = 465;
		private var _fps:Number = 60;
		private var _timeStep:Number = 1.0 / _fps;
		private var _scale:Number = 100;
		private var _gravity:Number = 10;
		
		//各自追加プロパティ
		private var cnt:Number = 0;
		
		public function Test() 
		{
			init();
		}
		
		private function init():void {
			_catalystObj = new B2DCatalyst(true, _fps, _scale, _gravity);
			this.addChild(_catalystObj);
			_world = _catalystObj.world;
			
			////////////////////////////////////////////////
			////////////	以下、設定用コード		////////////
			////////////////////////////////////////////////
			
			//床を作成
			_catalystObj.makeB2BodyBox(465, 30, 0, 435, 0, 0, 0.5, 0.5);
			
			
			////////////////////////////////////////////////
			////////////	以上、設定用コード		////////////
			////////////////////////////////////////////////
			_catalystObj.addEventListener(Event.ENTER_FRAME, onEnterFrameHandler);
		}
		
		private function onEnterFrameHandler(e:Event):void 
		{
			_world.Step(_timeStep, 10);
			
			////////////////////////////////////////////////
			////////////	以下、描画更新用コード	////////////
			////////////////////////////////////////////////
			
			
			if (cnt == 30) {
				create();
				cnt = 0;
			} else {
				cnt++;
			}
			
			
			////////////////////////////////////////////////
			////////////	以上、描画更新用コード	////////////
			////////////////////////////////////////////////
			
			//画面外に行ったオブジェクトを削除する
			var marginX:Number = 50;
			var marginY:Number = 50;
			for (var b:b2Body = _world.GetBodyList(); b; b = b.GetNext()) {
				var xPos:Number = b.GetWorldCenter().x * _scale;
				var yPos:Number = b.GetWorldCenter().x * _scale;
				if (xPos > WIDTH + marginX || xPos < -marginX || yPos > HEIGHT + marginY || yPos < -marginY){
					_world.DestroyBody(b);
				}
			}
		}
		
		
		
		private function create():void {
			_catalystObj.makeB2BodyCircle(50, Math.random() * 465, 0, 1, 0.2, 0.5);
			_catalystObj.makeB2BodyBox(50, 50, Math.random() * 465, 0, Math.random() * Math.PI * 2, 1, 0.2, 0.5);
		}
	}
	
}













//以下、媒介用クラス。なので、拡張する時以外、通常弄る必要なし・・・にしたい
//以下のURLをほぼ丸ごと。少しずつ拡張予定。
//http://hokori.net/2009/02/18/box2dflashas3_base/

import flash.display.Sprite;

import Box2D.Collision.*;
import Box2D.Common.Math.*;
import Box2D.Dynamics.*;
import Box2D.Collision.Shapes.*;

internal class B2DCatalyst extends Sprite
{
    //Box2Dのバージョンは2.0.2

    private var m_b2_world:b2World;
    //縮尺 1mを何ピクセルで表すか
    private var m_b2_physcale:Number = 10;  
    //演算制度 大きいと正確だけど、負荷が大きい
    private var m_b2_iterations:int = 10;   
    // 演算をfpsに合わせる
    private var m_b2_timeStep:Number = 24.0;  
    
	
    //constructor
    public function B2DCatalyst(debugModeFlag:Boolean = false, fps:int = 24, 
								physcale:Number = 10, gravity:Number = 10):void{
        
        //timestep設定
        this.m_b2_timeStep = 1.0 / fps;
        
        //スケール設定
        this.m_b2_physcale = physcale;
        
        //B2DBoxの世界生成
        this.createB2World(gravity);
		
		//debugMode
		if (debugModeFlag) startDebugMode();
    }

    //Box2D世界作成
    private function createB2World(gravity:Number):void {
        
        // Creat world AABB
        var worldAABB:b2AABB = new b2AABB();
        worldAABB.lowerBound.Set(-1000, -1000);
        worldAABB.upperBound.Set(1000, 1000);
        
        // Define the gravity vector
        var vec_gravity:b2Vec2 = new b2Vec2(0.0, gravity);
        
        // Allow bodies to sleep
        var doSleep:Boolean = true;
        
        // Construct a world object
        this.m_b2_world = new b2World(worldAABB, vec_gravity, doSleep);
    }
    
    
    /**
     * 長方形の物体作成
     * @param   int w (ピクセル 内部でB2DBox用に変換)
     * @param   int h (ピクセル 内部でB2DBox用に変換)
     * @param   Number x(ピクセル 内部でB2DBox用に変換)
     * @param   Number y(ピクセル 内部でB2DBox用に変換)
     * @param   Number angle 角度(360度 内部でラジアンに変換)
     * @param   density 密度 0にすると固定
     * @param   friction 摩擦 大きいと滑りにくい
     * @param   restitution 跳ね返り 大きいと、反発しやすい
     * @param   viewdata 表示用のSprite
     * @param   viewgroup 表示用のSpriteを入れるSprite
     * @return  b2Body
     */
    public function makeB2BodyBox(w:int, h:int,
                     x:Number, y:Number, angle:Number, 
                     density:Number,
                     friction:Number,
                     restitution:Number,
                     viewdata:Sprite = null,
                     viewgroup:Sprite = null) :b2Body {
		
        var b2_boxdef:b2PolygonDef = this.createB2BoxDef(w, h, density,
                                 friction, restitution);
        var b2_bodydef:b2BodyDef = this.createB2BodyDef(x, y, w, h, angle,
                                viewdata, viewgroup);
        
        var b2_body:b2Body = this.m_b2_world.CreateBody(b2_bodydef);
        b2_body.CreateShape(b2_boxdef);
        b2_body.SetMassFromShapes();
        
        return b2_body;
    }   
    
    
    /**
     * 円の物体作成
     * @param   diameter 直径(ピクセル 内部でメートルに変換)
     * @param   x (ピクセル 内部でメートルに変換)
     * @param   y(ピクセル 内部でメートルに変換)
     * @param   density 密度 0にすると固定 大きいと、ぶつかったとき強い
     * @param   friction 摩擦 大きいと滑りにくい
     * @param   restitution 跳ね返り 大きいと、反発しやすい
     * @param   viewdata 表示用のSprite
     * @param   viewgroup 表示用のSpriteを入れるSprite
     * @return  b2Body
     */
    public function makeB2BodyCircle(diameter:int, x:Number, y:Number, 
                    density:Number,
                    friction:Number,
                    restitution:Number,
                    viewdata:Sprite = null,
                    viewgroup:Sprite = null) :b2Body {
        
        var b2_boxdef:b2CircleDef = this.createB2CircleDef(diameter,
                            density, friction, restitution);

        var b2_bodydef:b2BodyDef = this.createB2BodyDef(x, y, 0, 0, 0,
                            viewdata, viewgroup);
        
        var b2_body:b2Body = this.m_b2_world.CreateBody(b2_bodydef);
        b2_body.CreateShape(b2_boxdef);
        b2_body.SetMassFromShapes();
        
        return b2_body;
    }
    
    
    /**
     * 長方形の性質設定(形状と素材)
     * @param   width (ピクセル 内部でメートルに変換)
     * @param   height (ピクセル 内部でメートルに変換)
     * @param   density
     * @param   friction
     * @param   restitution
     * @return
     */
    public function createB2BoxDef(width:int, height:int, 
                    density:Number,
                    friction:Number,
                    restitution:Number):b2PolygonDef {
        
        var boxdef:b2PolygonDef = new b2PolygonDef();
        //B2DBox用単位・中心座標からの距離のサイズに変換して作成
        boxdef.SetAsBox(width / 2 / this.m_b2_physcale,
                height/ 2 / this.m_b2_physcale);
        //密度 0だと動かない 大きいと、ぶつかったとき強い
        boxdef.density = density;     
        //摩擦 大きいと、滑りにくい
        boxdef.friction = friction;   
        //跳ね返り 大きいと、反発しやすい(ゴムっぽくなる)
        //小さいと、粘土っぽくなる
        boxdef.restitution = restitution;  
        
        return boxdef;
    }

    
    /**
     * 円の性質設定(形状と素材)
     * @param   diameter (ピクセル 内部でメートルに変換)
     * @param   height (ピクセル 内部でメートルに変換)
     * @param   density
     * @param   friction
     * @param   restitution
     * @return
     */
    public function createB2CircleDef(diameter:int, 
                    density:Number, 
                    friction:Number, 
                    restitution:Number):b2CircleDef {
        
        var cdef:b2CircleDef = new b2CircleDef();
        //メートル単位・中心座標からの距離のサイズに変換して作成
        cdef.radius = diameter / 2 / this.m_b2_physcale;  //半径
        //密度 0だと動かない
        cdef.density = density;     
        //摩擦 大きいと、滑りにくい
        cdef.friction = friction;   
        //跳ね返り 大きいと、反発しやすい(ゴムっぽくなる)
        //小さいと、粘土っぽくなる
        cdef.restitution = restitution;  
        
        return cdef;
    }
    
    
    /**
     * 配置設定
     * @param   x(ピクセル worldの中心から物体の中心の距離)
     * @param   y(ピクセル)
     * @param   angle 角度 (360度単位)
     * @param   viewdata  表示用Sprite
     * @param   viegroup  表示用Spriteを入れるSprite
     * @return  2BodyDef
     */
    public function createB2BodyDef(x:Number, y:Number, w:Number, h:Number, 
					angle:Number,viewdata:Sprite = null,viewgroup:Sprite = null):b2BodyDef {
        
        var bodydef:b2BodyDef = new b2BodyDef();
        //B2DBox用単位に変換して配置
        bodydef.position.Set((x+w*.5) / this.m_b2_physcale, (y+h*.5) / this.m_b2_physcale);
        bodydef.angle = (angle / 180) * Math.PI; //ラジアンに変換
        
        //動かないときはスリープ→止まったらイベント受け付けなくなるので起こす
        bodydef.allowSleep = true;  
        
        if(viewdata != null){
            bodydef.userData = viewdata;            
            bodydef.userData.width = viewdata.width;
            bodydef.userData.height = viewdata.height;
        
            //表示用に追加
            if(viewgroup != null){
                viewgroup.addChild(bodydef.userData);
            }
        }
        
        return bodydef;   
    }

    
    /**
     * 座標指定用のベクトル作成(単位をピクセルからメートルに変換)
     * @param   x
     * @param   y
     * @return  b2Vec2
     */
    public function createB2Vec(x:Number, y:Number):b2Vec2 {
        
        //単位をb2用に変換
        var vec:b2Vec2 = new b2Vec2(x / this.m_b2_physcale,
									y / this.m_b2_physcale); 
        return vec;
    }
    
	
	private function startDebugMode():void 
	{
		//DebugDrawを有効にする
		var debugDraw:b2DebugDraw = new b2DebugDraw();
		debugDraw.m_sprite = this;
		debugDraw.m_drawScale = m_b2_physcale;
		debugDraw.m_fillAlpha = .8;
		debugDraw.m_lineThickness = 1;
		debugDraw.m_drawFlags = b2DebugDraw.e_shapeBit;
		m_b2_world.SetDebugDraw(debugDraw);
	}
	
	
	
	
	//getter/setter
	public function get world():b2World { return m_b2_world; }
	
	public function set world(value:b2World):void 
	{
		m_b2_world = value;
	}
}