[Box2D]b2DebugDrawを使わずに色々と描画してみる。
===================================================
なんで、こんなにソース長くなっちゃうかなぁ。
*
* @author paq ( 898 )
* @since 2009.04.21
===================================================
// forked from paq's [Box2D]色を変えてみる
/*===================================================*//**
* なんで、こんなにソース長くなっちゃうかなぁ。
*
* @author paq ( 898 )
* @since 2009.04.21
*//*===================================================*/
package
{
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import Box2D.Dynamics.*;
import Box2D.Collision.*;
import Box2D.Collision.Shapes.*;
import Box2D.Dynamics.Joints.*;
import Box2D.Dynamics.Contacts.*;
import Box2D.Common.*;
import Box2D.Common.Math.*;
[SWF(width = 465, height = 465, backgroundColor = 0xFFFFFF, frameRate = 60)]
public class Intro extends Sprite
{
public function Intro()
{
addEventListener(Event.ADDED_TO_STAGE, initialize);
}
public function initialize(event:Event):void
{
removeEventListener(Event.ADDED_TO_STAGE, initialize);
var main:Main = new Main(stage);
addChild(main);
}
}
}
import flash.display.Sprite;
import flash.display.Stage;
import flash.events.Event;
import flash.events.MouseEvent;
import Box2D.Dynamics.*;
import Box2D.Collision.*;
import Box2D.Collision.Shapes.*;
import Box2D.Dynamics.Joints.*;
import Box2D.Dynamics.Contacts.*;
import Box2D.Common.*;
import Box2D.Common.Math.*;
import caurina.transitions.Tweener;
//==================================================================
// ■Box2DMain □Sprite
// worldの設定など様々な事を行うメインとなるクラス。
//==================================================================
class Box2DMain extends Sprite
{
public var layer:Stage;
public var _sprite:Sprite;
public var _world:b2World;
public var _physScale:Number = 30.0;
public var _iterations:int = 10;
public var _timeStep:Number = 1.0 / 30.0;
public var _display:b2Display;
public var _mouseJoint:b2MouseJoint;
public var _mouseBody:b2Body;
static public var mouseXWorldPhys:Number;
static public var mouseYWorldPhys:Number;
static public var mouseXWorld:Number;
static public var mouseYWorld:Number;
private var mousePVec:b2Vec2 = new b2Vec2();
private var mouseDown:Boolean = false;
public function Box2DMain(stg:Stage)
{
layer = stg;
initialize();
}
public function initialize():void
{
removeEventListener(Event.ADDED_TO_STAGE, initialize);
//コンテナ
_sprite = new Sprite();
addChild(_sprite);
addEventListener(Event.ENTER_FRAME, update);
addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
addEventListener(MouseEvent.CLICK, onMouseUp);
addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
addEventListener(Event.MOUSE_LEAVE, onMouseLeave);
//WORLD
var worldAABB:b2AABB = new b2AABB();
worldAABB.lowerBound.Set(-1000.0, -1000.0);
worldAABB.upperBound.Set(1000.0, 1000.0);
var gravity:b2Vec2 = new b2Vec2(0.0, 10.0);
var doSleep:Boolean = true;
_world = new b2World(worldAABB, gravity, doSleep);
//display
_display = new b2Display(_sprite, _world);
_display._physScale = 30.0;
addChild(_display)
createWall();
createObject();
}
public function createObject():void
{
}
private function createWall():void
{
var wallObject:b2PolygonDef = new b2PolygonDef();
wallObject.density = 0.0;
var wallDef:b2BodyDef = new b2BodyDef();
var wallBody:b2Body;
//Left
wallDef.position.Set(-11/ _physScale, layer.stageWidth/2 / _physScale);
wallObject.SetAsBox(10 / _physScale, layer.stageWidth/2 / _physScale);
wallBody = _world.CreateBody(wallDef);
wallBody.CreateShape(wallObject);
wallBody.SetMassFromShapes();
//Right
wallDef.position.Set((layer.stageWidth+11) / _physScale, layer.stageWidth/2 / _physScale);
wallObject.SetAsBox(10 / _physScale, layer.stageWidth/2 / _physScale);
wallBody = _world.CreateBody(wallDef);
wallBody.CreateShape(wallObject);
wallBody.SetMassFromShapes();
//Top
wallDef.position.Set(layer.stageWidth/2 / _physScale, -11 / _physScale);
wallObject.SetAsBox(layer.stageWidth/2 / _physScale, 10 / _physScale);
wallBody = _world.CreateBody(wallDef);
wallBody.CreateShape(wallObject);
wallBody.SetMassFromShapes();
//Bottom
wallDef.position.Set(layer.stageWidth/2 / _physScale, (layer.stageWidth-10/2) / _physScale);
wallObject.SetAsBox(layer.stageWidth/2 / _physScale, 10/2 / _physScale);
wallBody = _world.CreateBody(wallDef);
wallBody.CreateShape(wallObject);
wallBody.SetMassFromShapes();
}
private function onMouseDown(event:MouseEvent):void
{
mouseDown = true;
}
private function onMouseUp(event:MouseEvent):void
{
mouseDown = false;
}
private function onMouseMove(event:MouseEvent):void
{
if (mouseDown != event.buttonDown){
mouseDown = event.buttonDown;
}
}
public function onMouseLeave(e:Event):void
{
mouseDown = false;
MouseDrag();
}
//======================
// Update
//======================
private function update(event:Event):void
{
_world.Step(_timeStep, _iterations);
_sprite.graphics.clear();
UpdateMouseWorld();
MouseDrag();
_display.update();
}
//======================
// Update mouseWorld
//======================
public function UpdateMouseWorld():void
{
mouseXWorldPhys = (_sprite.mouseX)/_physScale;
mouseYWorldPhys = (_sprite.mouseY)/_physScale;
mouseXWorld = (_sprite.mouseX);
mouseYWorld = (_sprite.mouseY);
}
//======================
// Mouse Drag
//======================
public function MouseDrag():void
{
// mouse press
if (mouseDown && !_mouseJoint){
var body:b2Body = GetBodyAtMouse();
if (body)
{
var md:b2MouseJointDef = new b2MouseJointDef();
md.body1 = _world.GetGroundBody();
md.body2 = body;
md.target.Set(mouseXWorldPhys, mouseYWorldPhys);
md.maxForce = 300.0 * body.GetMass();
md.timeStep = _timeStep;
_mouseJoint = _world.CreateJoint(md) as b2MouseJoint;
body.WakeUp();
}
}
// mouse release
if (!mouseDown){
if (_mouseJoint)
{
_world.DestroyJoint(_mouseJoint);
_mouseJoint = null;
}
}
// mouse move
if (_mouseJoint)
{
var p2:b2Vec2 = new b2Vec2(mouseXWorldPhys, mouseYWorldPhys);
_mouseJoint.SetTarget(p2);
}
/*// mouse press
if (mouseDown && !_mouseJoint){
var body:b2Body = GetBodyAtMouse();
if (body)
{
_mouseBody = body;
}
}
// mouse move
if (_mouseBody)
{
var nPotision:b2Vec2 = _mouseBody.GetPosition();
_mouseBody.WakeUp();
nPotision.x = _sprite.mouseX / _physScale;
nPotision.y = _sprite.mouseY / _physScale;
_mouseBody.WakeUp();
}*/
}
//======================
// GetBodyAtMouse
//======================
public function GetBodyAtMouse(includeStatic:Boolean = false):b2Body
{
// Make a small box.
mousePVec.Set(mouseXWorldPhys, mouseYWorldPhys);
var aabb:b2AABB = new b2AABB();
aabb.lowerBound.Set(mouseXWorldPhys - 0.001, mouseYWorldPhys - 0.001);
aabb.upperBound.Set(mouseXWorldPhys + 0.001, mouseYWorldPhys + 0.001);
// Query the world for overlapping shapes.
var k_maxCount:int = 10;
var shapes:Array = new Array();
var count:int = _world.Query(aabb, shapes, k_maxCount);
var body:b2Body = null;
for (var i:int = 0; i < count; ++i)
{
if (shapes[i].GetBody().IsStatic() == false || includeStatic)
{
var tShape:b2Shape = shapes[i] as b2Shape;
var inside:Boolean = tShape.TestPoint(tShape.GetBody().GetXForm(), mousePVec);
if (inside)
{
body = tShape.GetBody();
break;
}
}
}
return body;
}
}
//==================================================================
// ■b2Display □Sprite
// b2DebugDrawの代わりとなるクラス。
//==================================================================
class b2Display extends Sprite
{
public var _sprite:Sprite;
public var _world:b2World;
public var _physScale:Number;
public function b2Display(sprite:Sprite, world:b2World)
{
_sprite = sprite
_world = world
}
public function update():void
{
for (var b:b2Body = _world.m_bodyList; b; b = b.m_next)
{
for (var s:b2Shape = b.GetShapeList(); s != null; s = s.GetNext())
{
if (b.m_userData != null)
{
DrawShape(s, b.m_xf, b.m_userData);
}
else
{
//DrawShape(s, b.m_xf, 0xFFFFFF);
}
}
}
}
public function DrawShape(shape:b2Shape, xf:b2XForm, userData:Object):void
{
switch (shape.m_type)
{
case b2Shape.e_circleShape:
{
var circle:b2CircleShape = (shape as b2CircleShape);
var center:b2Vec2 = b2Math.b2MulX(xf, circle.m_localPosition);
var radius:Number = circle.m_radius;
var axis:b2Vec2 = xf.R.col1;
DrawSolidCircle(center, radius, axis, userData);
}
break;
case b2Shape.e_polygonShape:
{
var i:int;
var poly:b2PolygonShape = (shape as b2PolygonShape);
var vertexCount:int = poly.GetVertexCount();
var localVertices:Array = poly.GetVertices();
var vertices:Array = new Array(b2Settings.b2_maxPolygonVertices);
for (i = 0; i < vertexCount; ++i)
{
vertices[i] = b2Math.b2MulX(xf, localVertices[i]);
}
DrawSolidPolygon(vertices, vertexCount, userData);
}
break;
}
}
public function DrawSolidPolygon(vertices:Array, vertexCount:int, userData:Object):void
{
_sprite.graphics.lineStyle(1.0, userData.lineColor, 1.0);
_sprite.graphics.moveTo(vertices[0].x * _physScale, vertices[0].y * _physScale);
_sprite.graphics.beginFill(userData.fillColor, 1);
for (var i:int = 1; i < vertexCount; i++){
_sprite.graphics.lineTo(vertices[i].x * _physScale, vertices[i].y * _physScale);
}
_sprite.graphics.lineTo(vertices[0].x * _physScale, vertices[0].y * _physScale);
_sprite.graphics.endFill();
}
public function DrawSolidCircle(center:b2Vec2, radius:Number, axis:b2Vec2, userData:Object) : void
{
_sprite.graphics.lineStyle(1.0, userData.lineColor, 1.0);
_sprite.graphics.moveTo(0,0);
_sprite.graphics.beginFill(userData.fillColor, 1.0);
_sprite.graphics.drawCircle(center.x * _physScale, center.y * _physScale, radius * _physScale);
_sprite.graphics.endFill();
_sprite.graphics.moveTo(center.x * _physScale, center.y * _physScale);
_sprite.graphics.lineTo((center.x + axis.x*radius) * _physScale, (center.y + axis.y*radius) * _physScale);
}
}
//==================================================================
// ■Main □Box2DMain
// Boxなどのオブジェクトを配置するクラス。
//==================================================================
class Main extends Box2DMain
{
public function Main(stg:Stage)
{
super(stg);
}
override public function createObject():void
{
var bd:b2BodyDef;
var box:b2PolygonDef = new b2PolygonDef();
var circ:b2CircleDef = new b2CircleDef();
box.SetAsBox(20 / _physScale, 20 / _physScale);
box.density = 1.0;
box.friction = 0.4;
box.restitution = 0.1;
circ.radius = 20 / _physScale;
circ.density = 1.0;
circ.friction = 0.4;
circ.restitution = 0.1;
bd = new b2BodyDef();
bd.position.Set(232 / _physScale, 232 / _physScale);
for (var i:uint; i < 2; i++ )
{
box.SetAsBox((20+i) / _physScale, (20+i) / _physScale);
var box1:b2Body = _world.CreateBody(bd);
box1.m_userData = new b2Material(0xF2E484)
box1.CreateShape(box);
box1.SetMassFromShapes();
box.SetAsBox((19-i) / _physScale, (21+i) / _physScale);
var box2:b2Body = _world.CreateBody(bd);
box2.m_userData = new b2Material(0x76A87E)
box2.CreateShape(box);
box2.SetMassFromShapes();
box.SetAsBox((18-i) / _physScale, (22+i) / _physScale);
var box3:b2Body = _world.CreateBody(bd);
box3.m_userData = new b2Material(0xB2DEB0)
box3.CreateShape(box);
box3.SetMassFromShapes()
box.SetAsBox((17-i) / _physScale, (23+i) / _physScale);
var box4:b2Body = _world.CreateBody(bd);
box4.m_userData = new b2Material(0xCCF0C6)
box4.CreateShape(box);
box4.SetMassFromShapes()
box.SetAsBox((16-i) / _physScale, (24+i) / _physScale);
var box5:b2Body = _world.CreateBody(bd);
box5.m_userData = new b2Material(0xE8A3A9)
box5.CreateShape(box);
box5.SetMassFromShapes()
}
for (i = 0; i < 2; i++ )
{
circ.radius = 20 / _physScale;
var circ1:b2Body = _world.CreateBody(bd);
circ1.m_userData = new b2Material(0xFFAA2D, 0xFFFFFF);
circ1.CreateShape(circ);
circ1.SetMassFromShapes();
circ.radius = 21 / _physScale;
var circ2:b2Body = _world.CreateBody(bd);
circ2.m_userData = new b2Material(0xC73C33, 0xFFFFFF);
circ2.CreateShape(circ);
circ2.SetMassFromShapes();
circ.radius = 22 / _physScale;
var circ3:b2Body = _world.CreateBody(bd);
circ3.m_userData = new b2Material(0x6A6A6E, 0xFFFFFF);
circ3.CreateShape(circ);
circ3.SetMassFromShapes()
circ.radius = 23 / _physScale;
var circ4:b2Body = _world.CreateBody(bd);
circ4.m_userData = new b2Material(0xCAD6D8, 0xFFFFFF);
circ4.CreateShape(circ);
circ4.SetMassFromShapes()
circ.radius = 24 / _physScale;
var circ5:b2Body = _world.CreateBody(bd);
circ5.m_userData = new b2Material(0xAB6037, 0xFFFFFF);
circ5.CreateShape(circ);
circ5.SetMassFromShapes()
}
}
}
//==================================================================
// ■b2Material
// b2Bodyの色情報などを保持するクラス。
//==================================================================
class b2Material
{
public var fillColor:Number;
public var lineColor:Number;
public function b2Material(fillcol:Number = 0xFFFFFF,linecol:Number = -1)
{
fillColor = fillcol;
lineColor = linecol;
if (lineColor == -1)
{
lineColor = fillColor;
}
}
}