flash on 2013-4-27
source code from nutsu a great master of code
http://nutsu.com/blog/2008/082521_as_box2d_first.html
Box2Dなテスト
@author nutsu
♥0 |
Line 115 |
Modified 2013-05-02 05:50:01 |
MIT License
archived:2017-03-20 07:50:18
ActionScript3 source code
/**
* Copyright alexnotkin ( http://wonderfl.net/user/alexnotkin )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/a5Ec
*/
//source code from nutsu a great master of code
// http://nutsu.com/blog/2008/082521_as_box2d_first.html
package
{
import Box2D.Collision.b2AABB;
import Box2D.Common.Math.b2Vec2;
import Box2D.Dynamics.b2World;
import Box2D.Dynamics.b2BodyDef;
import Box2D.Collision.Shapes.b2PolygonDef;
import Box2D.Collision.Shapes.b2CircleDef;
import Box2D.Dynamics.b2Body;
import Box2D.Collision.Shapes.b2Shape;
import Box2D.Collision.Shapes.b2CircleShape;
import Box2D.Dynamics.b2DebugDraw;
import flash.geom.Rectangle;
import flash.display.MovieClip;
import flash.events.Event;
import flash.events.MouseEvent;
/**
* Box2Dなテスト
* @author nutsu
*/
public class TestWorld extends MovieClip
{
private var world:b2World;
private var WORLD_SCALE:Number = 100; // 100pixel/m
private var VIEW_RECT:Rectangle;
private var half_width:Number;
private var half_height:Number;
private var circles:Array;
public function TestWorld()
{
super();
VIEW_RECT = new Rectangle( 0, 0, stage.stageWidth/WORLD_SCALE, stage.stageHeight/WORLD_SCALE );
half_width = stage.stageWidth * 0.5;
half_height = stage.stageHeight * 0.5;
//動的オブジェクト用の配列 :b2CircleShape[]
circles = [];
//とりあえずワールドつくる
initWorld();
//静的なオブジェクト(四方壁)をつくる
initObjects();
//テストドローな設定
initDraw();
//とりあえず1こオブジェクトつくる
addCircle( VIEW_RECT.width*0.5, VIEW_RECT.height*0.5 );
addEventListener( Event.ENTER_FRAME, onEnterFrame );
stage.addEventListener( MouseEvent.CLICK, onClick );
stage.quality = "low";
}
private function initWorld():void
{
//物理計算エリア? お約束らしい
var aabb:b2AABB = new b2AABB();
aabb.lowerBound.Set( -1000, -1000 );
aabb.upperBound.Set( 1000, 1000 );
//重加速度。後でマウス位置で変えるので0にしとく
var gravity:b2Vec2 = new b2Vec2( 0, 0 );
//力が作用してないオブジェクトをスリープするか否か。今回はずっと動いてるのでfalse
var dosleep:Boolean = false;
//ワールドつくる
world = new b2World( aabb, gravity, dosleep );
}
private function initObjects():void
{
//四方壁つくる
//大きさの単位はメートルなそうな
var wall_size:Number = 0.025;
//ShapeなDef(形状決め)
var wall_side_shape:b2PolygonDef = new b2PolygonDef();
wall_side_shape.SetAsBox( wall_size, VIEW_RECT.height * 0.5 );
wall_side_shape.density = 0; //静的な物体は0なそうな
var wall_vt_shape:b2PolygonDef = new b2PolygonDef();
wall_vt_shape.SetAsBox( VIEW_RECT.width*0.5, wall_size );
wall_vt_shape.density = 0;
//BodyなDef(位置決め)
var wall_left:b2BodyDef = new b2BodyDef();
var wall_right:b2BodyDef = new b2BodyDef();
var wall_bottom:b2BodyDef = new b2BodyDef();
var wall_top:b2BodyDef = new b2BodyDef();
//set position
wall_left.position.Set( wall_size, VIEW_RECT.height * 0.5 );
wall_right.position.Set( VIEW_RECT.width - wall_size, VIEW_RECT.height * 0.5 );
wall_bottom.position.Set( VIEW_RECT.width * 0.5 , VIEW_RECT.height - wall_size);
wall_top.position.Set( VIEW_RECT.width*0.5 , wall_size);
//worldに入れてく
world.CreateBody( wall_left ).CreateShape( wall_side_shape );
world.CreateBody( wall_right ).CreateShape( wall_side_shape );
world.CreateBody( wall_bottom ).CreateShape( wall_vt_shape );
world.CreateBody( wall_top ).CreateShape( wall_vt_shape );
}
private function initDraw():void
{
//デバッグ用のドロー設定
var debug_draw:b2DebugDraw = new b2DebugDraw();
debug_draw.m_sprite = this;
debug_draw.m_drawScale = WORLD_SCALE;
debug_draw.m_fillAlpha = 1;
debug_draw.m_lineThickness = 0;
debug_draw.m_drawFlags = b2DebugDraw.e_shapeBit;
world.SetDebugDraw( debug_draw );
}
private function addCircle( ax:Number, ay:Number ):void
{
//任意の位置にCircleオブジェクト追加してく
//手順 ShapeなDef→BodyなDef→worldで実体をつくる感じ
var s:b2CircleDef = new b2CircleDef();
s.density = 1;
s.restitution = 0.2;
s.radius = 0.2;
var b:b2BodyDef = new b2BodyDef();
b.position.Set( ax, ay );
var bb:b2Body = world.CreateBody( b );
var bs:b2Shape = bb.CreateShape( s );
bb.SetMassFromShapes();
//Shapeはあとでいじるので配列にいれとく
bs.m_userData = Number(0);
circles.push( b2CircleShape(bs) );
}
private function onClick( e:MouseEvent ):void
{
addCircle(mouseX/WORLD_SCALE, mouseY/WORLD_SCALE);
}
private function onEnterFrame( e:Event ):void
{
if ( world )
{
//マウス位置で重加速度変更
world.m_gravity.x = -2 * (half_width - mouseX) / half_width;
world.m_gravity.y = -2 * (half_height - mouseY) / half_height;
//円をうにょうにょ
for (var i:int = 0; i < circles.length ; i++)
{
var bs:b2CircleShape = circles[i];
bs.m_radius = 0.2 + Math.sin( bs.m_userData ) * 0.1;
bs.m_userData += 0.05;
}
//計算 Step(計算時間,計算精度) きびっとしたいので計算時間を長めにとる
world.Step(1/15, 4);
}
}
}
}