flash on 2009-10-22
...
@author ...
/**
* Copyright mtok ( http://wonderfl.net/user/mtok )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/xQ7S
*/
package
{
import Box2D.Collision.Shapes.b2CircleDef;
import Box2D.Collision.Shapes.b2MassData;
import Box2D.Collision.Shapes.b2Shape;
import Box2D.Dynamics.b2Body;
import Box2D.Dynamics.b2BodyDef;
import Box2D.Dynamics.Joints.b2DistanceJointDef;
import Box2D.Dynamics.Joints.b2MouseJointDef;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import Box2D.Collision.b2AABB;
import Box2D.Dynamics.b2World;
import Box2D.Common.Math.b2Vec2;
import Box2D.Dynamics.Joints.b2MouseJoint;
import Box2D.Collision.Shapes.b2PolygonDef;
import Box2D.Dynamics.b2DebugDraw;
/**
* ...
* @author ...
*/
public class Box2DTest2 extends Sprite
{
private var _world:b2World;
private var _isDebugDrawing:Boolean = true;
private var _timeStep:Number;
private var _isMouseDown:Boolean;
private var _mouseJoint:b2MouseJoint;
private var _mousePVec:b2Vec2 = new b2Vec2();
private var _iterations:int = 10;
public function Box2DTest2()
{
addEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
}
private function addedToStageHandler(e:Event):void
{
removeEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
initialize();
}
private function initialize():void {
_timeStep = 1 / stage.frameRate;
_world = buildWorld();
buildScene(_world);
setUpDebugDraw(_world);
addEventListener(Event.ENTER_FRAME, enterFrameHandler);
stage.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
stage.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
}
private function enterFrameHandler(e:Event):void
{
mouseDrag();
_world.Step(_timeStep, _iterations);
}
private function mouseDrag():void
{
var body:b2Body;
if (_isMouseDown && !_mouseJoint) {
body = getBodyAtMouse();
if (body) {
var md:b2MouseJointDef= new b2MouseJointDef();
md.body1 = _world.GetGroundBody();
md.body2 = body;
md.target.x = mouseX;
md.target.y = mouseY;
md.maxForce = 300 * body.GetMass();
md.timeStep = _timeStep;
_mouseJoint = _world.CreateJoint(md) as b2MouseJoint;
body.WakeUp();
}
}
if (!_isMouseDown) {
if (_mouseJoint) {
_world.DestroyJoint(_mouseJoint);
_mouseJoint = null;
}
}
if (_mouseJoint) {
_mouseJoint.m_target.x = mouseX;
_mouseJoint.m_target.y = mouseY;
}
}
private function getBodyAtMouse(isStaticIncluded:Boolean = false):b2Body
{
_mousePVec.x = mouseX;
_mousePVec.y = mouseY;
var aabb:b2AABB = new b2AABB();
aabb.lowerBound.x = mouseX - 10;
aabb.lowerBound.y = mouseY - 10;
aabb.upperBound.x = mouseX + 10;
aabb.upperBound.y = mouseY + 10;
var maxCount:int = 10;
var shapes:Array = new Array();
var count:int = _world.Query(aabb, shapes, maxCount);
var body:b2Body = null;
var shape:b2Shape;
for (var i:int = 0; i < count; i++) {
shape = shapes[i] as b2Shape;
if (shape.GetBody().IsStatic() == false || isStaticIncluded) {
var inside:Boolean = shape.TestPoint(shape.GetBody().GetXForm(), _mousePVec);
if (inside) {
body = shape.GetBody();
break;
}
}
}
return body;
}
private function mouseUpHandler(e:MouseEvent):void
{
_isMouseDown = false;
}
private function mouseDownHandler(e:MouseEvent):void
{
_isMouseDown = true;
}
private function setUpDebugDraw(world:b2World):void
{
if (_isDebugDrawing) {
var debugDraw:b2DebugDraw = new b2DebugDraw();
addChild(debugDraw.m_sprite = new Sprite());
debugDraw.m_drawScale = 1;
debugDraw.m_fillAlpha = 0.25;
debugDraw.m_lineThickness = 1;
debugDraw.m_drawFlags = /*DebugDraw.e_aabbBit | DebugDraw.e_centerOfMassBit | DebugDraw.e_coreShapeBit | DebugDraw.e_obbBit | DebugDraw.e_pairBit |*/ b2DebugDraw.e_shapeBit| b2DebugDraw.e_jointBit ;
world.SetDebugDraw(debugDraw);
}
}
private function buildScene(world:b2World):void
{
buildWalls(world);
buildShapes(world);
buildDistanceJoint(world);
}
private function buildDistanceJoint(world:b2World):void
{
var sw:Number = stage.stageWidth;
var sh:Number = stage.stageHeight;
var boxBodyDef:b2BodyDef = new b2BodyDef();
boxBodyDef.position.x = sw * 0.8;
boxBodyDef.position.y = sh * 0.5;
var box:b2Body = world.CreateBody(boxBodyDef);
var boxShape:b2PolygonDef= new b2PolygonDef();
boxShape.SetAsBox(40, 40);
boxShape.density = 0.7;
boxShape.friction = 0.3;
boxShape.restitution = 0.4;
box.CreateShape(boxShape);
var massData:b2MassData= new b2MassData();
massData.mass = 100;
box.SetMass(massData);
var jointDef:b2DistanceJointDef= new b2DistanceJointDef();
var ancher:b2Vec2 = new b2Vec2();
ancher.x = sw * 0.5;
ancher.y = 0;
jointDef.Initialize(box, world.GetGroundBody(), box.GetWorldCenter(), ancher);
world.CreateJoint(jointDef);
box.SetLinearVelocity(new b2Vec2(100, 0));
}
private function buildShapes(world:b2World):void
{
var sw:Number = stage.stageWidth;
var sh:Number = stage.stageHeight;
var bodyDef:b2BodyDef;
var body:b2Body;
var shapeDef:b2CircleDef;
for (var i:int = 0; i < 50; i++) {
bodyDef = new b2BodyDef();
bodyDef.position.x = sw * Math.random();
bodyDef.position.y = sh * Math.random();
body = world.CreateBody(bodyDef);
shapeDef = new b2CircleDef();
shapeDef.radius = Math.random() * 15 + 3;
shapeDef.density = 1;
shapeDef.friction = 0.3;
shapeDef.restitution = 0.7;
body.CreateShape(shapeDef);
body.SetMassFromShapes();
}
}
private function buildWorld():b2World
{
var gravity:b2Vec2 = new b2Vec2(0, 10);
var worldAABB:b2AABB = new b2AABB();
var sleep:Boolean = true;
worldAABB.lowerBound.x = 0;
worldAABB.lowerBound.y = 0;
worldAABB.upperBound.x = 465;
worldAABB.upperBound.y = 465;
var world:b2World = new b2World(worldAABB, gravity, sleep);
return world;
}
private function buildWalls(world:b2World):void
{
var wallShapeDef:b2PolygonDef = new b2PolygonDef();
var wallBodyDef:b2BodyDef = new b2BodyDef();
var wall:b2Body;
var sw:Number = stage.stageWidth;
var sh:Number = stage.stageHeight;
//右と左の壁に使うシェイプを定義
wallShapeDef.SetAsBox(100, (sh + 40) * 0.5);
//左
wallBodyDef.position.x = -95;
wallBodyDef.position.y = sh * 0.5;
wall = world.CreateBody(wallBodyDef);
wall.CreateShape(wallShapeDef);
wall.SetMassFromShapes();
//右
wallBodyDef.position.x = sw + 95;
wallBodyDef.position.y = sh * 0.5;
wall = world.CreateBody(wallBodyDef);
wall.CreateShape(wallShapeDef);
wall.SetMassFromShapes();
//上と下の壁に使うシェイプを定義
wallShapeDef.SetAsBox((sw+40) * 0.5, 100);
//下
wallBodyDef.position.x = (sw+40) * 0.5;
wallBodyDef.position.y = -95;
wall = world.CreateBody(wallBodyDef);
wall.CreateShape(wallShapeDef);
wall.SetMassFromShapes();
//下
wallBodyDef.position.x = (sw+40) * 0.5;
wallBodyDef.position.y = sh + 95;
wall = world.CreateBody(wallBodyDef);
wall.CreateShape(wallShapeDef);
wall.SetMassFromShapes();
}
}
}