DrawPhysics
マウスで描いた線がBox2Dで動きます。
/**
* Copyright momasahiro321 ( http://wonderfl.net/user/momasahiro321 )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/moCf
*/
package
{
import Box2D.Collision.*;
import Box2D.Common.Math.*;
import Box2D.Dynamics.*;
import Box2D.Collision.Shapes.*;
import flash.events.MouseEvent;
import flash.display.Sprite;
import flash.events.Event;
[SWF(frameRate="60")]
public class Main extends Sprite
{
private var mouseDownFlag:Boolean = false; //マウスボタンが押されているか
private var drawingObject:LineObject; //今描いている物体
private var world:b2World;
private var debug:Sprite = new Sprite();
public function Main()
{
//ワールドの作成
var aabb:b2AABB = new b2AABB();
aabb.lowerBound.Set(-0.05, -0.05);
aabb.upperBound.Set(4.70, 4.70);
var gravity:b2Vec2 = new b2Vec2(0.0, 5.0);
world = new b2World(aabb, gravity, true);
//壁の作成
var wallDef:b2BodyDef = new b2BodyDef();
wallDef.position.Set(0.00, 0.00);
var wallBody:b2Body = world.CreateBody(wallDef);
var wallShape:b2PolygonDef = new b2PolygonDef();
wallShape.SetAsOrientedBox(0.05, 2.33, new b2Vec2(-0.05, 2.33));
wallBody.CreateShape(wallShape);
wallShape.SetAsOrientedBox(0.05, 2.33, new b2Vec2(4.70, 2.33));
wallBody.CreateShape(wallShape);
wallShape.SetAsOrientedBox(2.33, 0.05, new b2Vec2(2.33, -0.05));
wallBody.CreateShape(wallShape);
wallShape.SetAsOrientedBox(2.33, 0.05, new b2Vec2(2.33, 4.70));
wallBody.CreateShape(wallShape);
//デバッグ描画
var debugDraw:b2DebugDraw = new b2DebugDraw();
debugDraw.m_fillAlpha = 0.3;
debugDraw.m_drawScale = 100;
debugDraw.m_lineThickness = 1;
debugDraw.m_drawFlags = b2DebugDraw.e_shapeBit;
debugDraw.m_sprite = debug
world.SetDebugDraw(debugDraw);
addChild(debug);
debug.visible = false;
//イベント登録
stage.addEventListener(MouseEvent.MOUSE_DOWN, mouseDown);
stage.addEventListener(MouseEvent.MOUSE_UP, mouseUp);
addEventListener(Event.ENTER_FRAME, enterFrame);
}
private function enterFrame(e:Event):void
{
if(mouseDownFlag)
{
drawingObject.draw();
}
world.Step(0.016, 10);
}
private function mouseDown(e:MouseEvent):void
{
drawingObject = new LineObject();
addChild(drawingObject);
mouseDownFlag = true;
}
private function mouseUp(e:MouseEvent):void
{
drawingObject.create(world);
mouseDownFlag = false;
}
}
}
import flash.events.Event;
import flash.display.AVM1Movie;
import flash.text.TextField;
import Box2D.Dynamics.*;
import flash.display.Sprite;
import flash.geom.Point;
import Box2D.Common.Math.*;
import Box2D.Collision.Shapes.*;
//物体
class LineObject extends Sprite
{
private var anchor:Vector.<Point> = new Vector.<Point>();//線を区切る点
private var p:Point = new Point(); //前のフレームのマウス座標
private var v:b2Vec2 = new b2Vec2(); //線の方向
private var count:int = 0;
private var body:b2Body;
private var created:Boolean = false;
public function LineObject()
{
alpha = 0.3;
graphics.lineStyle(5, 0x000000, 1.0, false, "normal", "round", "round");
graphics.moveTo(mouseX, mouseY);
anchor.push(new Point(mouseX, mouseY));
addEventListener(Event.ENTER_FRAME, enterFrame);
}
public function draw():void //線を描く
{
graphics.lineTo(mouseX,mouseY);
if(count == 2)
{
//10度以上曲がったらアンカーを打つ
if(VectorMath.angle(v,
new b2Vec2(mouseX - p.x, mouseY - p.y)) > 10 * Math.PI / 180)
{
anchor.push(new Point(mouseX, mouseY));
v.x = mouseX - p.x;
v.y = mouseY - p.y;
}
}
else
{
if(count == 1)
{
v.x = mouseX - p.x;
v.y = mouseY - p.y;
if(v.x != 0 || v.y != 0)
{
anchor.push(new Point(mouseX, mouseY));
count++;
}
}
else
{
count++;
}
}
p.x = mouseX;
p.y = mouseY;
}
public function create(world:b2World):void //物体化
{
var last:Point = anchor[anchor.length - 1];
if(last.x != mouseX || last.y != mouseY)
{
anchor.push(new Point(mouseX, mouseY));
}
var bodyDef:b2BodyDef = new b2BodyDef();
bodyDef.position.Set(0.00, 0.00);
body = world.CreateBody(bodyDef);
for(var i:int = 0; i < anchor.length - 1; i++)
{
var shapeDef:b2PolygonDef = new b2PolygonDef();
shapeDef.density = 1;
shapeDef.friction = 1.0;
shapeDef.restitution = 0.3;
var hx:Number = VectorMath.magnitude(new b2Vec2(
anchor[i + 1].x - anchor[i].x,
anchor[i + 1].y - anchor[i].y)) / 200;
var center:b2Vec2 = new b2Vec2(
(anchor[i].x + anchor[i + 1].x) / 200,
(anchor[i].y + anchor[i + 1].y) / 200);
var angle:Number = Math.atan2(
anchor[i + 1].y - anchor[i].y,
anchor[i + 1].x - anchor[i].x);
shapeDef.SetAsOrientedBox(hx, 0.025, center, angle);
body.CreateShape(shapeDef);
}
body.SetMassFromShapes();
created = true;
alpha = 1.0;
}
public function enterFrame(e:Event):void
{
if(created)
{
x = body.GetPosition().x * 100;
y = body.GetPosition().y * 100;
rotation = body.GetAngle() * 180 / Math.PI;
}
}
}
class VectorMath
{
//ベクトルのなす角
public static function angle(v1:b2Vec2, v2:b2Vec2):Number
{
return Math.acos((v1.x * v2.x + v1.y * v2.y) / (magnitude(v1) * magnitude(v2)));
}
//ベクトルの大きさ
public static function magnitude(v:b2Vec2):Number
{
return Math.sqrt(Math.pow(v.x, 2) + Math.pow(v.y ,2));
}
}