[Box2D]b2RevoluteJointの使い方が分かった。
Jointの描画方法を間違えていました。
/*
* Jointの描画方法を間違えていました。
*/
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 = 0x000000, 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.*;
class Box2DMain extends Sprite
{
public var layer:Stage;
public var m_sprite:Sprite;
public var m_world:b2World;
public var m_physScale:Number = 30.0;
public var m_iterations:int = 10;
public var m_timeStep:Number = 1.0/30.0;
public var m_mouseJoint:b2MouseJoint;
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);
//コンテナ
m_sprite = new Sprite();
addChild(m_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;
m_world = new b2World(worldAABB, gravity, doSleep);
//デバック用
var dbgDraw:b2DebugDraw= new b2DebugDraw();
var dbgSprite:Sprite= new Sprite();
m_sprite.addChild(dbgSprite);
dbgDraw.m_sprite= dbgSprite;
dbgDraw.m_drawScale= 30.0;
dbgDraw.m_fillAlpha= 0.3;
dbgDraw.m_lineThickness= 1.0;
dbgDraw.m_alpha=1.0;
dbgDraw.m_xformScale=1.0;
dbgDraw.m_drawFlags = b2DebugDraw.e_shapeBit | b2DebugDraw.e_jointBit;
m_world.SetDebugDraw(dbgDraw);
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(10/2 / m_physScale, layer.stageWidth/2 / m_physScale);
wallObject.SetAsBox(10/2 / m_physScale, layer.stageWidth/2 / m_physScale);
wallBody = m_world.CreateBody(wallDef);
wallBody.CreateShape(wallObject);
wallBody.SetMassFromShapes();
//Right
wallDef.position.Set((layer.stageWidth-10/2) / m_physScale, layer.stageWidth/2 / m_physScale);
wallObject.SetAsBox(10/2 / m_physScale, layer.stageWidth/2 / m_physScale);
wallBody = m_world.CreateBody(wallDef);
wallBody.CreateShape(wallObject);
wallBody.SetMassFromShapes();
//Top
wallDef.position.Set(layer.stageWidth/2 / m_physScale, 10/2 / m_physScale);
wallObject.SetAsBox(layer.stageWidth/2 / m_physScale, 10/2 / m_physScale);
wallBody = m_world.CreateBody(wallDef);
wallBody.CreateShape(wallObject);
wallBody.SetMassFromShapes();
//Bottom
wallDef.position.Set(layer.stageWidth/2 / m_physScale, (layer.stageWidth-10/2) / m_physScale);
wallObject.SetAsBox(layer.stageWidth/2 / m_physScale, 10/2 / m_physScale);
wallBody = m_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
{
m_world.Step(m_timeStep, m_iterations);
m_sprite.graphics.clear();
UpdateMouseWorld();
MouseDrag();
}
//======================
// Update mouseWorld
//======================
public function UpdateMouseWorld():void
{
mouseXWorldPhys = (m_sprite.mouseX)/m_physScale;
mouseYWorldPhys = (m_sprite.mouseY)/m_physScale;
mouseXWorld = (m_sprite.mouseX);
mouseYWorld = (m_sprite.mouseY);
}
//======================
// Mouse Drag
//======================
public function MouseDrag():void
{
// mouse press
if (mouseDown && !m_mouseJoint){
var body:b2Body = GetBodyAtMouse();
if (body)
{
var md:b2MouseJointDef = new b2MouseJointDef();
md.body1 = m_world.GetGroundBody();
md.body2 = body;
md.target.Set(mouseXWorldPhys, mouseYWorldPhys);
md.maxForce = 300.0 * body.GetMass();
md.timeStep = m_timeStep;
m_mouseJoint = m_world.CreateJoint(md) as b2MouseJoint;
body.WakeUp();
}
}
// mouse release
if (!mouseDown){
if (m_mouseJoint)
{
m_world.DestroyJoint(m_mouseJoint);
m_mouseJoint = null;
}
}
// mouse move
if (m_mouseJoint)
{
var p2:b2Vec2 = new b2Vec2(mouseXWorldPhys, mouseYWorldPhys);
m_mouseJoint.SetTarget(p2);
}
}
//======================
// 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 = m_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;
}
}
class Main extends Box2DMain
{
public function Main(stg:Stage)
{
super(stg);
}
override public function createObject():void
{
//以下、Box2DFlashAS3のサンプルから
var bd:b2BodyDef;
var circ:b2CircleDef = new b2CircleDef();
var box:b2PolygonDef = new b2PolygonDef();
var jd:b2RevoluteJointDef = new b2RevoluteJointDef();
for (var i:uint = 0; i < 3; i++){
var startX:Number = 70 + Math.random() * 20 + 100 * i;
var startY:Number = 20 + Math.random() * 50;
// BODIES
// Head
circ.radius = 12.5 / m_physScale;
circ.density = 1.0;
circ.friction = 0.4;
circ.restitution = 0.3;
bd = new b2BodyDef();
bd.position.Set(startX / m_physScale, startY / m_physScale);
var head:b2Body = m_world.CreateBody(bd);
head.CreateShape(circ);
head.SetMassFromShapes();
//if (i == 0){
head.ApplyImpulse(new b2Vec2(Math.random() * 100 - 50, Math.random() * 100 - 50), head.GetWorldCenter());
//}
// Torso1
box.SetAsBox(15 / m_physScale, 10 / m_physScale);
box.density = 1.0;
box.friction = 0.4;
box.restitution = 0.1;
bd = new b2BodyDef();
bd.position.Set(startX / m_physScale, (startY + 28) / m_physScale);
var torso1:b2Body = m_world.CreateBody(bd);
torso1.CreateShape(box);
torso1.SetMassFromShapes();
// Torso2
bd = new b2BodyDef();
bd.position.Set(startX / m_physScale, (startY + 43) / m_physScale);
var torso2:b2Body = m_world.CreateBody(bd);
torso2.CreateShape(box);
torso2.SetMassFromShapes();
// Torso3
bd = new b2BodyDef();
bd.position.Set(startX / m_physScale, (startY + 58) / m_physScale);
var torso3:b2Body = m_world.CreateBody(bd);
torso3.CreateShape(box);
torso3.SetMassFromShapes();
// UpperArm
box.SetAsBox(18 / m_physScale, 6.5 / m_physScale);
box.density = 1.0;
box.friction = 0.4;
box.restitution = 0.1;
bd = new b2BodyDef();
// L
bd.position.Set((startX - 30) / m_physScale, (startY + 20) / m_physScale);
var upperArmL:b2Body = m_world.CreateBody(bd);
upperArmL.CreateShape(box);
upperArmL.SetMassFromShapes();
// R
bd.position.Set((startX + 30) / m_physScale, (startY + 20) / m_physScale);
var upperArmR:b2Body = m_world.CreateBody(bd);
upperArmR.CreateShape(box);
upperArmR.SetMassFromShapes();
// LowerArm
box.SetAsBox(17 / m_physScale, 6 / m_physScale);
box.density = 1.0;
box.friction = 0.4;
box.restitution = 0.1;
bd = new b2BodyDef();
// L
bd.position.Set((startX - 57) / m_physScale, (startY + 20) / m_physScale);
var lowerArmL:b2Body = m_world.CreateBody(bd);
lowerArmL.CreateShape(box);
lowerArmL.SetMassFromShapes();
// R
bd.position.Set((startX + 57) / m_physScale, (startY + 20) / m_physScale);
var lowerArmR:b2Body = m_world.CreateBody(bd);
lowerArmR.CreateShape(box);
lowerArmR.SetMassFromShapes();
// UpperLeg
box.SetAsBox(7.5 / m_physScale, 22 / m_physScale);
box.density = 1.0;
box.friction = 0.4;
box.restitution = 0.1;
bd = new b2BodyDef();
// L
bd.position.Set((startX - 8) / m_physScale, (startY + 85) / m_physScale);
var upperLegL:b2Body = m_world.CreateBody(bd);
upperLegL.CreateShape(box);
upperLegL.SetMassFromShapes();
// R
bd.position.Set((startX + 8) / m_physScale, (startY + 85) / m_physScale);
var upperLegR:b2Body = m_world.CreateBody(bd);
upperLegR.CreateShape(box);
upperLegR.SetMassFromShapes();
// LowerLeg
box.SetAsBox(6 / m_physScale, 20 / m_physScale);
box.density = 1.0;
box.friction = 0.4;
box.restitution = 0.1;
bd = new b2BodyDef();
// L
bd.position.Set((startX - 8) / m_physScale, (startY + 120) / m_physScale);
var lowerLegL:b2Body = m_world.CreateBody(bd);
lowerLegL.CreateShape(box);
lowerLegL.SetMassFromShapes();
// R
bd.position.Set((startX + 8) / m_physScale, (startY + 120) / m_physScale);
var lowerLegR:b2Body = m_world.CreateBody(bd);
lowerLegR.CreateShape(box);
lowerLegR.SetMassFromShapes();
// JOINTS
jd.enableLimit = true;
// Head to shoulders
jd.lowerAngle = -40 / (180/Math.PI);
jd.upperAngle = 40 / (180/Math.PI);
jd.Initialize(torso1, head, new b2Vec2(startX / m_physScale, (startY + 15) / m_physScale));
m_world.CreateJoint(jd);
// Upper arm to shoulders
// L
jd.lowerAngle = -85 / (180/Math.PI);
jd.upperAngle = 130 / (180/Math.PI);
jd.Initialize(torso1, upperArmL, new b2Vec2((startX - 18) / m_physScale, (startY + 20) / m_physScale));
m_world.CreateJoint(jd);
// R
jd.lowerAngle = -130 / (180/Math.PI);
jd.upperAngle = 85 / (180/Math.PI);
jd.Initialize(torso1, upperArmR, new b2Vec2((startX + 18) / m_physScale, (startY + 20) / m_physScale));
m_world.CreateJoint(jd);
// Lower arm to upper arm
// L
jd.lowerAngle = -130 / (180/Math.PI);
jd.upperAngle = 10 / (180/Math.PI);
jd.Initialize(upperArmL, lowerArmL, new b2Vec2((startX - 45) / m_physScale, (startY + 20) / m_physScale));
m_world.CreateJoint(jd);
// R
jd.lowerAngle = -10 / (180/Math.PI);
jd.upperAngle = 130 / (180/Math.PI);
jd.Initialize(upperArmR, lowerArmR, new b2Vec2((startX + 45) / m_physScale, (startY + 20) / m_physScale));
m_world.CreateJoint(jd);
// Shoulders/stomach
jd.lowerAngle = -15 / (180/Math.PI);
jd.upperAngle = 15 / (180/Math.PI);
jd.Initialize(torso1, torso2, new b2Vec2(startX / m_physScale, (startY + 35) / m_physScale));
m_world.CreateJoint(jd);
// Stomach/hips
jd.Initialize(torso2, torso3, new b2Vec2(startX / m_physScale, (startY + 50) / m_physScale));
m_world.CreateJoint(jd);
// Torso to upper leg
// L
jd.lowerAngle = -25 / (180/Math.PI);
jd.upperAngle = 45 / (180/Math.PI);
jd.Initialize(torso3, upperLegL, new b2Vec2((startX - 8) / m_physScale, (startY + 72) / m_physScale));
m_world.CreateJoint(jd);
// R
jd.lowerAngle = -45 / (180/Math.PI);
jd.upperAngle = 25 / (180/Math.PI);
jd.Initialize(torso3, upperLegR, new b2Vec2((startX + 8) / m_physScale, (startY + 72) / m_physScale));
m_world.CreateJoint(jd);
// Upper leg to lower leg
// L
jd.lowerAngle = -25 / (180/Math.PI);
jd.upperAngle = 115 / (180/Math.PI);
jd.Initialize(upperLegL, lowerLegL, new b2Vec2((startX - 8) / m_physScale, (startY + 105) / m_physScale));
m_world.CreateJoint(jd);
// R
jd.lowerAngle = -115 / (180/Math.PI);
jd.upperAngle = 25 / (180/Math.PI);
jd.Initialize(upperLegR, lowerLegR, new b2Vec2((startX + 8) / m_physScale, (startY + 105) / m_physScale));
m_world.CreateJoint(jd);
}
}
}