[Box2D] デジタルししおどし (カラーバリエーション)
回転ジョイントの勉強をかねて「ししおどし」を作ってみました。
[ 参考にさせていただいたサイト ]
http://d.hatena.ne.jp/nitoyon/20090428/box2dflashas3_2_0_2
http://sakeprog.cocolog-nifty.com/sake/2008/05/box2dflashas3_0054.html#more
http://hokori.net/category/note/
http://nutsu.com/blog/2008/091721_as_box2djoint.html
/*
回転ジョイントの勉強をかねて「ししおどし」を作ってみました。
[ 参考にさせていただいたサイト ]
http://d.hatena.ne.jp/nitoyon/20090428/box2dflashas3_2_0_2
http://sakeprog.cocolog-nifty.com/sake/2008/05/box2dflashas3_0054.html#more
http://hokori.net/category/note/
http://nutsu.com/blog/2008/091721_as_box2djoint.html
*/
package {
import Box2D.Collision.b2AABB;
import Box2D.Collision.Shapes.*;
import Box2D.Common.Math.b2Vec2;
import Box2D.Dynamics.b2Body;
import Box2D.Dynamics.b2BodyDef;
import Box2D.Dynamics.b2DebugDraw;
import Box2D.Dynamics.b2World;
import Box2D.Dynamics.Joints.b2DistanceJoint;
import Box2D.Dynamics.Joints.b2DistanceJointDef;
import Box2D.Dynamics.Joints.b2GearJoint;
import Box2D.Dynamics.Joints.b2GearJointDef;
import Box2D.Dynamics.Joints.b2MouseJoint;
import Box2D.Dynamics.Joints.b2MouseJointDef;
import Box2D.Dynamics.Joints.b2PrismaticJoint;
import Box2D.Dynamics.Joints.b2PrismaticJointDef;
import Box2D.Dynamics.Joints.b2RevoluteJoint;
import Box2D.Dynamics.Joints.b2RevoluteJointDef;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.display.StageScaleMode;
import flash.display.StageAlign;
import flash.display.StageQuality;
import flash.events.TimerEvent;
import flash.utils.Timer;
import flash.utils.getTimer;
public class ShishiOdoshi extends Sprite {
private var world:b2World;
private var m_physScale:uint = 100;
private var m_sprite:Sprite;
private var colors:Array;
private const ADD_INTERVAL_TIME:int = 300;
private var myTimer:Timer;
public function ShishiOdoshi():void {
stage.frameRate=60;
stage.quality=StageQuality.BEST;
stage.align=StageAlign.TOP_LEFT;
stage.scaleMode=StageScaleMode.NO_SCALE;
addEventListener(Event.ENTER_FRAME, enterFrameHandler);
init();
}
private function init():void {
var worldAABB:b2AABB = new b2AABB();
worldAABB.lowerBound.Set(-100, -100);
worldAABB.upperBound.Set(100, 100);
colors = [ 0xdffe24, 0x84d90a, 0x2a95bf, 0xf2b910, 0xff368c, 0x6cbace];
// 重力
var gravity:b2Vec2 = new b2Vec2(0, 9.8);
world = new b2World(worldAABB, gravity, true);
m_sprite = new Sprite();
addChild(m_sprite);
// 床の設置
var floorBodyDef:b2BodyDef = new b2BodyDef();
floorBodyDef.position.Set(2.5, 3.5);
var floorShapeDef:b2PolygonDef = new b2PolygonDef();
floorShapeDef.SetAsBox(2, 0.05);
// 物体として作る
var floor:b2Body = world.CreateBody(floorBodyDef);
floor.CreateShape( floorShapeDef );
// 坂の設置
var slopeBodyDef:b2BodyDef = new b2BodyDef();
slopeBodyDef.position.Set(2.2, 3.3);
var slopeShapeDef:b2PolygonDef = new b2PolygonDef();
slopeShapeDef.SetAsOrientedBox(0.3, 0.03, new b2Vec2(0, 0), 0.8);
// 物体として作る
var slope:b2Body = world.CreateBody(slopeBodyDef);
slope.CreateShape( slopeShapeDef );
// 柱の設置
var pillarBodyDef:b2BodyDef = new b2BodyDef();
pillarBodyDef.position.Set( 2, 3 );
var pillarShapeDef:b2PolygonDef = new b2PolygonDef();
pillarShapeDef.SetAsBox( 0.05, 0.5);
// 物体として作る
var pillar:b2Body = world.CreateBody( pillarBodyDef );
pillar.CreateShape( pillarShapeDef );
var boxBodyDef:b2BodyDef = new b2BodyDef();
boxBodyDef.position.Set(2.1, 2.6);
boxBodyDef.angle = 1.25;
var boxShapeDef:b2PolygonDef= new b2PolygonDef();
boxShapeDef.density = 1; // 密度
boxShapeDef.restitution = 0.01; // 反発係数
// 物体を作る
var boxBody:b2Body = world.CreateBody( boxBodyDef );
boxShapeDef.vertexCount = 4;
boxShapeDef.vertices[0].Set( 0.2, -1.2 );
boxShapeDef.vertices[1].Set( 0.2, 0.6);
boxShapeDef.vertices[2].Set( 0.1, 0.6 );
boxShapeDef.vertices[3].Set( 0.1, -1.2 );
// 形を物体に追加する
boxBody.CreateShape( boxShapeDef );
// 定義を変更してもう1個の形を追加する
boxShapeDef.vertexCount = 4;
boxShapeDef.vertices[0].Set( 0.2, 0 );
boxShapeDef.vertices[1].Set( 0.2, 0.8 );
boxShapeDef.vertices[2].Set( -0.2, 0.8 );
boxShapeDef.vertices[3].Set( -0.2, 0 );
// 形を物体に追加する
boxBody.CreateShape( boxShapeDef );
// 定義を変更してもう1個の形を追加する
boxShapeDef.vertexCount = 4;
boxShapeDef.vertices[0].Set( -0.1, -0.8 );
boxShapeDef.vertices[1].Set( -0.1, 0.6 );
boxShapeDef.vertices[2].Set( -0.2, 0.6 );
boxShapeDef.vertices[3].Set( -0.2, -0.8 );
// 形を物体に追加する
boxBody.CreateShape( boxShapeDef );
// 箱を動く物体として作る
boxBody.SetMassFromShapes();
// ジョイントの定義
var jointDef:b2RevoluteJointDef = new b2RevoluteJointDef();
jointDef.enableLimit = true
jointDef.lowerAngle = -90 / (180/Math.PI);
jointDef.upperAngle = 5 / (180/Math.PI);
var anchor:b2Vec2 = boxBodyDef.position;
jointDef.Initialize( boxBody, pillar, anchor );
var revolute_joint : b2RevoluteJoint = world.CreateJoint( jointDef ) as b2RevoluteJoint;
var wxArr:Array = [ 400, 410 ];
var wyArr:Array = [ 30, 155 ];
var wwArr:Array = [ 5, 200 ];
var whArr:Array = [ 50, 5 ];
var rArr:Array = [ -0.2, -0.45 ];
/* Pipe */
for (var j:uint = 0; j < wxArr.length; j++) {
var PipeBodyDef:b2BodyDef = new b2BodyDef();
PipeBodyDef.position.Set(wxArr[j] / m_physScale, wyArr[j] / m_physScale);
var PipeShapeDef:b2PolygonDef = new b2PolygonDef();
PipeShapeDef.SetAsOrientedBox(wwArr[j] / 2 / m_physScale, whArr[j]/2 / m_physScale, new b2Vec2(0,0), rArr[j]);
var PipeBody:b2Body = world.CreateBody( PipeBodyDef);
PipeBody.CreateShape( PipeShapeDef);
}
myTimer = new Timer(ADD_INTERVAL_TIME, 0);
myTimer.addEventListener(TimerEvent.TIMER, addCircle);
myTimer.start();
/*
addCircle();
addCircle();
addCircle();
*/
////////////////////////////////////////
// 描画設定
var debugDraw:b2DebugDraw = new b2DebugDraw();
debugDraw.m_sprite = this;
debugDraw.m_drawScale = 100; // 1mを100ピクセルにする
debugDraw.m_fillAlpha = 1; // 不透明度
debugDraw.m_lineThickness = 1; // 線の太さ
//debugDraw.m_drawFlags = b2DebugDraw.e_shapeBit | b2DebugDraw.e_jointBit | b2DebugDraw.e_centerOfMassBit;
debugDraw.m_drawFlags = b2DebugDraw.e_shapeBit;
world.SetDebugDraw(debugDraw);
}
private function enterFrameHandler(event:Event):void {
if (world == null) {
return;
}
// 物理シミュレーションを進める
world.Step(1 / 24, 10);
for (var bb:b2Body = world.m_bodyList; bb; bb = bb.m_next){
if (bb.m_userData is Sprite){
bb.m_userData.x = bb.GetPosition().x * 100;
bb.m_userData.y = bb.GetPosition().y * 100;
bb.m_userData.rotation = bb.GetAngle() * (180/Math.PI);
}
if(bb.GetPosition().x > stage.stageWidth/100 ){
//trace("delete : "+bb);
world.DestroyBody(bb);
m_sprite.removeChild(bb.m_userData);
}
}
}
private function addCircle(e:TimerEvent):void{
var circleDef:b2CircleDef = new b2CircleDef();
//circleDef.radius = Math.random()/10+0.00075;
circleDef.radius = 0.05;
circleDef.density = 1;
circleDef.friction = 0.05;
circleDef.restitution = 0.01;
var circleBD:b2BodyDef = new b2BodyDef();
circleBD.position.Set(400/ m_physScale, 0);
// 実際の円を生成
var sp:Sprite = new Sprite;
sp.graphics.beginFill( getColor(), 0.6);
sp.graphics.drawCircle(0, 0, 30);
sp.graphics.endFill();
// 円を保存
circleBD.userData=sp;
circleBD.userData.width=10;
circleBD.userData.height=10;
m_sprite.addChild(circleBD.userData);
var circleBody:b2Body = world.CreateBody( circleBD );
circleBody.CreateShape( circleDef );
circleBody.SetMassFromShapes();
}//end of function
private function getColor():Number {
return colors[ Math.floor(Math.random()*colors.length) ];
}//end of function
}
}