Box2d flash 2.0.2 俯瞰表現?


カワタです。

連投。今回は俯瞰目線(どっちかってーと真上目線だな)からカードをつかんで投げる的な?視点でBox2Dを使ってみた。通常

var gravity:b2Vec2 = new b2Vec2(0, 10);

みたいな形で重力を宣言するが、第一引数がx軸、第二引数がy軸への重力設定になっているので、これをまずは(0, 0)にしたげる。

そんでもって、それだけだと物体を放り投げると、延々とどっかへ飛んでってしまうので、各ボックスにlinearDampingとangularDampingというパラメータが用意されているので、例えば

bodyDef.linearDamping = 5;
bodyDef.angularDamping = 5;

のように設定したげる。(0がデフォルトっぽい)

以上。

[SWF]http://knap.jp/blog/swf/box2d_test4.swf, 425, 500[/SWF]

ソースは以下。

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 General.*;

var world:b2World;
const DRAW_SCALE:Number = 100;
var m_input:Input;
var m_mouseJoint:b2MouseJoint;  //マウスジョイント
var mouseXWorldPhys:Number;
var mouseYWorldPhys:Number;
var m_mouse_dowm:Boolean = false;  //マウスボタン押されてるか

init(); //初期表示へ

//レンダリング
addEventListener(Event.ENTER_FRAME, enterFrameHandler);

//ボックスの作成
addBt.addEventListener(MouseEvent.CLICK, clickHandler);
function clickHandler(e:MouseEvent){
makeBox();
}

//初期設定
function init():void {
buttonMode = true;

var worldAABB:b2AABB = new b2AABB();
worldAABB.lowerBound.Set(-100, -100);
worldAABB.upperBound.Set(100, 100);

// マウス操作
m_input = new Input(this);

// 重力
var gravity:b2Vec2 = new b2Vec2(0, 0);
world = new b2World(worldAABB, gravity, true);

//落下箱の作成
makeBox();
}

//ボックスの追加
function makeBox(){
// 箱の設置
//ランダムのX位置
var posX:Number = Math.random()*2+1;
//ランダムの回転
var rotate:Number = Math.random()*0.8;
// 箱の位置を左からランダム、上から0.5mとする
var bodyDef:b2BodyDef = new b2BodyDef();
bodyDef.position.Set(posX, 1);
bodyDef.linearDamping = 5;
bodyDef.angularDamping = 5;

var bodyShape:b2PolygonDef = new b2PolygonDef();
bodyShape.SetAsOrientedBox(0.5, 0.5, new b2Vec2(0, 0), rotate);
bodyShape.density = 1; // 密度 [kg/m^2]
bodyShape.restitution = 0; // 反発係数、通常は0~1
bodyShape.friction = 1; // 摩擦係数、通常は0~1

var body:b2Body = world.CreateBody(bodyDef);
body.CreateShape(bodyShape);
body.SetMassFromShapes();

// スプライトを表示する
var bodyImage:Sprite = new BodyImage();
bodyImage.width = 1 * DRAW_SCALE;
bodyImage.height = 1 * DRAW_SCALE;
bodyImage.rotation = rotate * 180 / Math.PI;
body.m_userData = new Sprite();
body.GetUserData().x = body.GetWorldCenter().x * DRAW_SCALE;
body.GetUserData().y = body.GetWorldCenter().y * DRAW_SCALE;
body.GetUserData().addChild(bodyImage);
addChild(body.GetUserData());

//addCUBEボタンを最前面に
var lastIndex:int = this.numChildren – 1;
this.setChildIndex(addBt, lastIndex);

/*デバッグ非表示
var debugDraw:b2DebugDraw = new b2DebugDraw();
debugDraw.m_sprite = this;
debugDraw.m_drawScale = 100; // 1mを100ピクセルにする
debugDraw.m_fillAlpha = 0.3; // 不透明度
debugDraw.m_lineThickness = 1; // 線の太さ
debugDraw.m_drawFlags = b2DebugDraw.e_shapeBit;
world.SetDebugDraw(debugDraw);
*/
}

//レンダリング
function enterFrameHandler(event: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;
}
}
updateMouseWorld();
mouseDrag();
world.Step(1 / 24, 10);
}

function updateMouseWorld():void {
// ワールド内でのマウス座標を取得
mouseXWorldPhys = (stage.mouseX) / DRAW_SCALE;
mouseYWorldPhys = (stage.mouseY) / DRAW_SCALE;
}

function mouseDrag():void{
// mouse press
if (Input.mouseDown && !m_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  = 1000.0 * body.GetMass();
md.timeStep  = 1/24;
m_mouseJoint = world.CreateJoint(md) as b2MouseJoint;
body.WakeUp();
}
}
var body2:b2Body = GetBodyAtMouse();
// mouse release
if (!Input.mouseDown){
if (m_mouseJoint) {
world.DestroyJoint(m_mouseJoint);
m_mouseJoint = null;
}
}

// mouse move
if (m_mouseJoint) {
var p2:b2Vec2 = new b2Vec2(mouseXWorldPhys, mouseYWorldPhys);
m_mouseJoint.SetTarget(p2);
}
}

//マウスの下の物体取得
var mousePVec:b2Vec2 = new b2Vec2();
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;
}

Scroll to top