Box2DFlashAS3 Study#1 「ぽとぽと落ちてくる」 
Box2DFlashAS3学習中の続き。
このコンテンツをご覧いただくには「javascriptをON」「flash player9以上」が必須環境となります。 / RSSリーダーで読んでいる方は、本記事に移動してごらんください。
内容的にはいつもの内輪ネタです。すいません!
以下のブログ記事を参考にしました。
ソース
at sonicさんのソースをベースに、FICCさんのソースをv2.0.0に対応させながら追記したという感じです。3人の写真はFlashのライブラリに入れて、先日のProgressionワークショップで教えてもらった技(→リンケージ一括設定を使ってみる | ra66it.net)で設定しておきます。
Tora&Demuが落ちてくる間隔の設定はTimerクラスを使うのがAS3っぽいのかなと思ったけど、それを学習してる時間がなかったのでとりあえずエンターフレーム毎に数える方法でやりきってしまいました。ほかにもツッコミどころ満載だと思いますが・・・、改善点があったらご指摘いただけるとうれしいです!
package {
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.Input;
import flash.display.*;
import flash.events.Event;
public class ShinqooBox2D extends Sprite {
//Box2D variables
public var m_sprite:Sprite;
public var m_world:b2World;
public var m_iterations:int;
public var m_timeStep:Number;
public var m_physScale:Number;
public var m_mouseJoint:b2MouseJoint;
// world mouse position
static public var mouseXWorldPhys:Number;
static public var mouseYWorldPhys:Number;
static public var mouseXWorld:Number;
static public var mouseYWorld:Number;
private var mousePVec:b2Vec2;
// input
public var m_input:Input;
//------------------------------------------------------------
// constructor
//------------------------------------------------------------
public function ShinqooBox2D() {
// set variables
{
m_sprite = new Sprite();
addChild(m_sprite);
m_iterations=10;
m_timeStep=1 / 30;
m_physScale=30;// =1m (1meter=30pixels)
m_input = new Input(m_sprite);
mousePVec = new b2Vec2();
};
// make base world
{
var worldAABB:b2AABB = new b2AABB();
worldAABB.lowerBound.Set(-1000.0, -1000.0);
worldAABB.upperBound.Set(1000.0, 1000.0);
var g:Number=9.80665;//標準重力加速度g = 9.80665 m/s2
var gravity:b2Vec2 = new b2Vec2(0.0, g);
var doSleep:Boolean = true;
m_world = new b2World(worldAABB, gravity, doSleep);
};
// floor
{
var floorWidth:Number=500;
var floorHeight:Number=40;
var floorDef:b2PolygonDef = new b2PolygonDef();
floorDef.SetAsBox(floorWidth/2/m_physScale,floorHeight/2/m_physScale);
floorDef.density = 100.0;
floorDef.friction = 1.0/m_physScale;
var floorBD:b2BodyDef = new b2BodyDef();
floorBD.position.Set(stage.stageWidth/2/m_physScale, (stage.stageHeight+20)/m_physScale);
var floor = m_world.CreateStaticBody(floorBD);
floor.CreateShape(floorDef);
floor.SetMassFromShapes();
};
//setDebug();
this.addEventListener(Event.ENTER_FRAME, Update, false, 0, true);
}
//add Hasecame
private function addHasecame():void {
//幅と高さ
var hasecameWidth:Number=415;
var hasecameHeight:Number=260;
//顔と体
var polygonDef1:b2PolygonDef = new b2PolygonDef();
polygonDef1.vertexCount = 4;
polygonDef1.vertices[0].Set(-150/m_physScale, -35/m_physScale);
polygonDef1.vertices[1].Set(165/m_physScale, -35/m_physScale);
polygonDef1.vertices[2].Set(220/m_physScale, 115/m_physScale);
polygonDef1.vertices[3].Set(-230/m_physScale, 115/m_physScale);
polygonDef1.density = 80.0/m_physScale;
polygonDef1.friction = 28.0/m_physScale;
polygonDef1.restitution = 1.0/m_physScale;
//UFO部分
var polygonDef2:b2PolygonDef = new b2PolygonDef();
polygonDef2.vertexCount = 4;
polygonDef2.vertices[0].Set(-30/m_physScale, -120/m_physScale);
polygonDef2.vertices[1].Set(10/m_physScale, -130/m_physScale);
polygonDef2.vertices[2].Set(85/m_physScale, -35/m_physScale);
polygonDef2.vertices[3].Set(-40/m_physScale, -35/m_physScale);
polygonDef2.density = 80.0/m_physScale;
polygonDef2.friction = 10.0/m_physScale;
polygonDef2.restitution = 1.0/m_physScale;
var polygonBD:b2BodyDef = new b2BodyDef();
polygonBD.position.Set(250/m_physScale,-800/m_physScale);
polygonBD.userData = new Hasecame();
polygonBD.userData.width = hasecameWidth;
polygonBD.userData.height = hasecameHeight;
m_sprite.addChild(polygonBD.userData);
var hasecame:b2Body = m_world.CreateDynamicBody(polygonBD);
hasecame.CreateShape(polygonDef1);
hasecame.CreateShape(polygonDef2);
hasecame.SetMassFromShapes();
}
//add Tora
private function addTora():void {
var CircleRadius:Number=35;
var circleDef:b2CircleDef = new b2CircleDef();
circleDef.radius = CircleRadius/m_physScale;
circleDef.density = 15.0/m_physScale;
circleDef.friction = 15.0/m_physScale;
circleDef.restitution = 25.0/m_physScale;//Toraはよく跳ねる
var circleBD:b2BodyDef = new b2BodyDef();
circleBD.position.Set((Math.random()*100+300)/m_physScale,-100/m_physScale);
circleBD.userData = new Tora();
circleBD.userData.width = CircleRadius*2;
circleBD.userData.height = CircleRadius*2;
m_sprite.addChild(circleBD.userData);
var circle:b2Body = m_world.CreateDynamicBody(circleBD);
circle.CreateShape(circleDef);
circle.SetMassFromShapes();
}
//add Demu
private function addDemu():void {
var CircleRadius:Number=35;
var circleDef:b2CircleDef = new b2CircleDef();
circleDef.radius = CircleRadius/m_physScale;
circleDef.density = 20.0/m_physScale;
circleDef.friction = 20.0/m_physScale;
circleDef.restitution = 5.0/m_physScale;//Demuはあまり跳ねない
var circleBD:b2BodyDef = new b2BodyDef();
circleBD.position.Set((Math.random()*100+100)/m_physScale,-100/m_physScale);
circleBD.userData = new Demu();
circleBD.userData.width = CircleRadius*2+10;
circleBD.userData.height = CircleRadius*2+10;
m_sprite.addChild(circleBD.userData);
var circle:b2Body = m_world.CreateDynamicBody(circleBD);
circle.CreateShape(circleDef);
circle.SetMassFromShapes();
}
//------------------------------------------------------------
// debug mode
//------------------------------------------------------------
public function setDebug():void {
var dbgDraw:b2DebugDraw = new b2DebugDraw();
var dbgSprite:Sprite = new Sprite();
addChild(dbgSprite);
dbgDraw.m_sprite = dbgSprite;
dbgDraw.m_drawScale = m_physScale;
dbgDraw.m_fillAlpha = 0.5;
dbgDraw.m_lineThickness = 1;
dbgDraw.m_drawFlags = 0xFFFFFFFF;
m_world.SetDebugDraw(dbgDraw);
}
//------------------------------------------------------------
// update every frame
//------------------------------------------------------------
private var count1:int=0;//ToraとDemu用カウンター
private var count2:int=0;//Hasecame用カンター
public function Update(e:Event):void {
m_world.Step(m_timeStep,m_iterations);
UpdateMouseWorld();
MouseDrag();
Input.update();
count1++;
count2++;
if (count1>=10) {//カウント10毎にToraとDemuを振らせる
count1=0;
addTora();
addDemu();
}
if (count2>=300) {//カウント300でHasecame降臨
addHasecame();
count2=-3000;//忘れたころに振ってくるように
}
for (var bb:b2Body = m_world.m_bodyList; bb; bb = bb.m_next) {
if (bb.m_userData is Sprite) {
bb.m_userData.x = bb.GetPosition().x * m_physScale;
bb.m_userData.y = bb.GetPosition().y * m_physScale;
bb.m_userData.rotation = bb.GetAngle() * (180/Math.PI);
if (bb.m_userData.x<-250 || bb.m_userData.x>750) {//画面外に出たら削除(このような処理でいいのか自信がない・・・)
m_world.DestroyBody(bb);
m_sprite.removeChild(bb.m_userData);
}
}
}
}
//------------------------------------------------------------
// Update mouseWorld
//------------------------------------------------------------
public function UpdateMouseWorld():void {
mouseXWorldPhys = (Input.mouseX)/m_physScale;
mouseYWorldPhys = (Input.mouseY)/m_physScale;
mouseXWorld = (Input.mouseX);
mouseYWorld = (Input.mouseY);
}
//------------------------------------------------------------
// Mouse Drag
//------------------------------------------------------------
public function MouseDrag():void {
// mouse press
if (Input.mouseDown && !m_mouseJoint) {
buttonMode = true;
var body:b2Body = GetBodyAtMouse();
if (body) {
var md:b2MouseJointDef = new b2MouseJointDef();
md.body1 = m_world.m_groundBody;
md.body2 = body;
md.target.Set(mouseXWorldPhys, mouseYWorldPhys);
md.maxForce = 300.0 * body.m_mass;
md.timeStep = m_timeStep;
m_mouseJoint = m_world.CreateJoint(md) as b2MouseJoint;
body.WakeUp();
}
}
// mouse release
if (!Input.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].m_body.IsStatic() == false || includeStatic) {
var tShape:b2Shape = shapes[i] as b2Shape;
var inside:Boolean = tShape.TestPoint(tShape.m_body.GetXForm(), mousePVec);
if (inside) {
body = tShape.m_body;
break;
}
}
}
return body;
}
}
}

















おもしろすぎなんですけど・・・
たま子: 2008年05月28日 22:59
おおーっ、これって決まったパターンの繰り返しってわけじゃないのね。
へぇ~っ、面白れ~な~って見てたら突然ハセカメが!
その後かなり見てたけどハセカメは出てこない。
レアキャラなんだね、ハセカメは。
KUMA: 2008年05月29日 09:05
めっちゃおもろいやないかぁ〜〜(チン!)
2ki: 2008年05月29日 18:25
今時ブラクラかと思いました…
しらかわ: 2008年05月31日 01:10
あ、次は俺も使ってほしいっす!
しらかわ: 2008年05月31日 01:29
すごい!
って、うちの椅子やんw
daikichi: 2008年06月04日 10:20