forked from: flash on 2014-6-9
forked from flash on 2014-6-9 (diff: 13)
ActionScript3 source code
/**
* Copyright tepe ( http://wonderfl.net/user/tepe )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/daCM
*/
// forked from tepe's flash on 2014-6-9
package {
import Box2D.Collision.b2AABB;
import Box2D.Collision.Shapes.*;
import Box2D.Common.Math.b2Vec2;
import Box2D.Dynamics.b2Body;
import Box2D.Dynamics.b2BodyDef;
import Box2D.Dynamics.b2DebugDraw;
import Box2D.Dynamics.b2World;
import Box2D.Dynamics.Joints.*;
import flash.display.*;
import flash.events.*;
import flash.text.*;
import flash.ui.*;
public class FlashTest extends Sprite {
private static const DRAW_SCALE:Number = 100;
// 物理エンジンの管理クラス
private var world:b2World;
private var tf:TextField = new TextField();
public function FlashTest() {
addChild(tf);
tf.text = "test";
// 外枠を定義する
var worldAABB:b2AABB = new b2AABB();
worldAABB.lowerBound.Set(-100, -100);
worldAABB.upperBound.Set(100, 100);
var gravity:b2Vec2 = new b2Vec2(0, 0);//重力方向
// 外枠と重力を指定して、物理エンジン全体をセットアップする
world = new b2World(worldAABB, gravity, true);
addFloor(2,2);
debugDraw();
// イベントハンドラを登録する
addEventListener(Event.ENTER_FRAME, onFrame);
stage.addEventListener(MouseEvent.CLICK,onClick);
}
private function addFloor(x:Number=0,y:Number=0):void{
var sx:Number = 150;
var sy:Number = 15;
//======================
//▼床(静体)の生成
//BodyDefの設定
var bdFloor:b2BodyDef = new b2BodyDef();
bdFloor.position.Set(x, y);//初期位置
var pdFloor:b2PolygonDef = new b2PolygonDef();//ShapeDefの設定
pdFloor.SetAsBox(sx/DRAW_SCALE, sy/DRAW_SCALE);
var bFloor:b2Body = world.CreateBody(bdFloor);//ボディの生成
bFloor.CreateShape(pdFloor);
var s:Sprite = createSprite();
s.name = idCnt.toString();
idCnt++;
s.addChild(createLabel(s.name));
s.graphics.beginFill(0xffff00,0.5);
s.graphics.drawRect(-sx,-sy,sx*2,sy*2);
s.graphics.endFill();
bFloor.m_userData = s;
addChild(s);
}
private function onClick(e:MouseEvent):void{
if(Math.random()<0.5)addBall(mouseX/100,mouseY/100);
else addBox(mouseX/100,mouseY/100);
}
//フレーム
private function onFrame(e:Event):void {
// ワールド内の全てのb2Bodyに対する処理
for (var b:b2Body = world.GetBodyList(); b; b = b.GetNext()) {
if (b.GetUserData() is Sprite) {
// 物理エンジン内での位置と回転角度を反映させる
b.GetUserData().x = b.GetWorldCenter().x * DRAW_SCALE;
b.GetUserData().y = b.GetWorldCenter().y * DRAW_SCALE;
b.GetUserData().rotation = b.GetAngle() * 180 / Math.PI;
if(b.IsFrozen()){
world.DestroyBody(b);
removeChild(b.m_userData);
tf.appendText(b.m_userData.name+" lost\n");
tf.scrollV = tf.maxScrollV;
//txt1.text = "Lost";
}
}
}
// Flashはデフォルトで秒間24フレームなので、
// 物理シミュレーションを1/24秒進める
world.Step(1 / 24, 10);
}
private function debugDraw():void {
var debugDraw:b2DebugDraw = new b2DebugDraw();
debugDraw.m_sprite = this;
debugDraw.m_drawScale = DRAW_SCALE;
debugDraw.m_fillAlpha = 0.3;
debugDraw.m_lineThickness = 1;
debugDraw.m_drawFlags = b2DebugDraw.e_shapeBit | b2DebugDraw.e_jointBit;
world.SetDebugDraw(debugDraw);
}
private static var idCnt:int=0;
private function addBall(x:Number=0,y:Number=0):void{
//▼ボール(動体)の生成------------------
var _bBall:b2Body;
var bdBall:b2BodyDef = new b2BodyDef();
bdBall.position.Set(x,y);
//ShapeDefの設定
var pdBall:b2CircleDef = new b2CircleDef();
pdBall.radius = 0.25;
pdBall.density = 1;//密度(1平方メートルあたりの重量(kg))
pdBall.restitution = 0.3;//反発係数(通常0~1)
//ボディの生成
_bBall = world.CreateBody(bdBall);
_bBall.CreateShape(pdBall);
//質量の設定
_bBall.SetMassFromShapes();
var s:Sprite = createSprite();
s.name = idCnt.toString();
idCnt++;
s.addChild(createLabel(s.name));
s.graphics.beginFill(0x0000ff,0.5);
s.graphics.drawCircle(0,0,25);
s.graphics.endFill();
s.alpha = 0.5;
_bBall.m_userData = s;
addChild(s);
}
//ドラッグ操作に対応したSpriteを返す
private function createSprite():Sprite{
var s:Sprite = new Sprite();
s.alpha = 0.5;
//addChild(s);
s.addEventListener(MouseEvent.MOUSE_OVER,function():void{//ロールオーバー
s.alpha = 0.7;
Mouse.cursor = MouseCursor.HAND;
stage.removeEventListener(MouseEvent.CLICK,onClick);
});
s.addEventListener(MouseEvent.MOUSE_OUT,function():void{//ロールアウト
s.alpha = 0.5;
Mouse.cursor = MouseCursor.ARROW;
stage.addEventListener(MouseEvent.CLICK,onClick);
});
s.addEventListener(MouseEvent.MOUSE_DOWN,function(e:MouseEvent):void{//ドラッグ開始
for (var b:b2Body = world.GetBodyList(); b; b = b.GetNext()) {
if (b.GetUserData() is Sprite) {
if(b.GetUserData()==e.currentTarget){
target = b;
tf.appendText(b.m_userData.name+" target\n");
break;
}
}
}
//target.PutToSleep();//対象の物理運動を無効
var vec:b2Vec2 = target.GetPosition();
prevX = vec.x*DRAW_SCALE;
prevY = vec.y*DRAW_SCALE;
stage.addEventListener(MouseEvent.MOUSE_MOVE,onMove);
});
s.addEventListener(MouseEvent.MOUSE_UP,function():void{//リリース
stage.removeEventListener(MouseEvent.MOUSE_MOVE,onMove);
var vel:b2Vec2 = target.GetLinearVelocity().Copy();
vel.Add(new b2Vec2(0, 0));//ベクトル設定
target.SetLinearVelocity(vel);
target.WakeUp();
target = null;
});
return s;
}
private var target:b2Body;
private var prevX:Number;
private var prevY:Number;
private function onMove(e:MouseEvent):void{
var mx:Number = mouseX-prevX;
var my:Number = mouseY-prevY;
//prevX = mouseX;
//prevY = mouseY;
var curPosition:b2Vec2 = target.GetPosition();
//curPosition.Add(new b2Vec2(0, -0.5))
curPosition.Add(new b2Vec2(mx/DRAW_SCALE, my/DRAW_SCALE))
target.SetXForm(curPosition, target.GetAngle());
//target.PutToSleep();
prevX = curPosition.x*DRAW_SCALE;
prevY = curPosition.y*DRAW_SCALE;
target.WakeUp()
}
private function createLabel(str:String):Bitmap{
var t:TextField = new TextField();
t.text = str;
t.selectable=false;
t.width = t.textWidth+5;
t.height = t.textHeight+5;
//t.border=true;
var btm_base:BitmapData = new BitmapData(t.width+1, t.height+1, true, 0xFFFFFF);
var btm:Bitmap = new Bitmap( btm_base);
btm_base.draw(t);
return btm;
}
private function addBox(x:Number=0,y:Number=0):void{
//~~~~~~~~~~~~~~~~▼箱(動体)の生成
var _bBox:b2Body;
var sx:Number = 20;
var sy:Number = 20;
var bdBox:b2BodyDef = new b2BodyDef();
bdBox.position.Set(x,y);
//ShapeDefの設定
var pd:b2PolygonDef = new b2PolygonDef();
pd.SetAsBox(sx/DRAW_SCALE, sy/DRAW_SCALE);//形状
pd.density = 10000;//密度(1平方メートルあたりの重量(kg))
pd.restitution = 0.5;//反発係数(通常0~1)
//ボディの生成
_bBox = world.CreateBody(bdBox);
_bBox.CreateShape(pd);
//質量の設定
_bBox.SetMassFromShapes();
//var s:Sprite = new Sprite();
var s:Sprite = createSprite();
s.name = idCnt.toString();
idCnt++;
s.addChild(createLabel(s.name));
s.graphics.beginFill(0x00ff00,0.5);
s.graphics.drawRect(-sx,-sy,sx*2,sy*2);
s.graphics.endFill();
_bBox.m_userData = s;
addChild(s);
}
}
}