Flashで物理演算を使ったミニゲーム その1「Box2Dについて」
Flashで物理演算を使ったミニゲーム その2「WorldとBodyとジョイント」
Flashで物理演算を使ったミニゲーム その3「動かないBody」
Flashで物理演算を使ったミニゲーム その4「カウントダウンするタイマーと動くBody」
Flashで物理演算を使ったミニゲーム その5「動かないBodyに衝突した時の処理」
Flashで物理演算を使ったミニゲーム その6「動くBodyに衝突した時の処理」
Flashで物理演算を使ったミニゲーム その7「効果音・BGM・背景」
Flashで物理演算を使ったミニゲーム その8「lemonovelで使う」
前回Worldと作成し、Bodyを1つ作りましたが
今回は動かないBodyを付けてみます。
動かないコンテナは仮にボスのような扱いで画面中央上の方に置いておこうと思います。
public function game03(){ createWorld(); createMy(); createBoss(); addEventListener(Event.ENTER_FRAME, Update, false, 0, true); }
「createBoss」のファンクションの実行をコンストラクタに追加。
実際にボスのオブジェクトを作るのは「createBoss」のファンクションに記述します。
bodyDef.userData.width = 312.5; bodyDef.userData.height = 200;
ボスの画像をライブラリに追加して
シンボルに変換して
自分(オレンジの玉)の画像と同じようにbossというクラス名でASリンゲージ。
実際の画像のサイズは500*320でしたが大きかったので/1.6してます。
boxDef = new b2PolygonDef(); boxDef.SetAsBox(312.5 / 2 / DRAW_SCALE, 200 / 2 / DRAW_SCALE); boxDef.density = 0;
画像サイズとは別にコンテナのサイズを指定しています。
少しややこしいですが最初に定義している
//定数定義 private static const DRAW_SCALE:Number = 30;
にて、「1メートルを30ピクセル」として設定しているため
このようになっていますが、実際「サイズ / 2 / 30」でも
「サイズ / 60」でもサイズを60で割った数字を直接書いたりしても問題はないです。
また、densityを0にして動かないコンテナになっています。
bodyDef.userData.id = 'id_boss'; bodyDef.userData.name = 'na_boss';
自分(オレンジの玉)と同様後で衝突時の判定のため名前をつけています。
(ボス画像:MGS技研)
[SWF]http://oblsk.sakura.ne.jp/help/wp-content/uploads/2016/01/game03.swf,800,600[/SWF]
画面をドラッグして動きを試せます。
衝突してもまだ何も起きないのが寂しいですが
動かない物質が出来ました。
ちなみに、コンテナの形はサークル型とキューブ型しかないので
このボスのような形だと実際画像がない部分にもコンテナが存在し、
自分(オレンジの玉)と衝突してしまいます。
めんどうなのでコンテナ一個で済ませていますが、
ちゃんとしたい場合は小さいコンテナをたくさん作って画像の形になるようにします。
適当で申し訳ないですがこんな感じに画像にそってコンテナを配置します。
◆サンプルソース全文
package{ ////////////////////////////////////////////////////////////////////////////// // インポート ////////////////////////////////////////////////////////////////////////////// import flash.display.MovieClip; import flash.display.Sprite; import flash.display.Bitmap; import flash.events.Event; import Box2D.Common.Math.*; import Box2D.Dynamics.*; import Box2D.Collision.*; import Box2D.Collision.Shapes.*; import Box2D.Dynamics.Joints.b2Joint; import Box2D.Dynamics.Joints.b2MouseJoint; import Box2D.Dynamics.Joints.b2MouseJointDef; import Box2D.Dynamics.Joints.b2RevoluteJoint; import Box2D.Dynamics.Joints.b2RevoluteJointDef; import flash.events.MouseEvent; import flash.utils.Timer; import flash.events.TimerEvent; import flash.text.*; public class game03 extends Sprite{ //定数定義 private static const DRAW_SCALE:Number = 30; // ジョイントの定義 private var mouseJointDef:b2MouseJointDef; private var mouseJoint:b2MouseJoint; // 値セット用 private var centerX:Number; private var centerY:Number; public function game03(){ createWorld(); createMy(); createBoss(); addEventListener(Event.ENTER_FRAME, Update, false, 0, true); } ////////////////////////////////////////////////////////////////////////////// // ワールドの作成 ////////////////////////////////////////////////////////////////////////////// private function createWorld():void{ //物理エンジンのセットアップ var worldAABB:b2AABB = new b2AABB(); worldAABB.lowerBound.Set(-100,-100); worldAABB.upperBound.Set(100,100); //重力のセットアップ var gravity:b2Vec2 = new b2Vec2(0.0, 0.4); //範囲・重力・スリープの有無 var doSleep:Boolean = true; // ワールド内のセットアップ m_world = new b2World(worldAABB, gravity, true); // ワールド内座標の設定 centerX = stage.stageWidth / 2 / DRAW_SCALE; centerY = stage.stageHeight / 2 / DRAW_SCALE; // 上 var bodyTop:b2BodyDef = new b2BodyDef(); bodyTop.position.Set(centerX, 0); var topShapeDef:b2PolygonDef = new b2PolygonDef(); topShapeDef.SetAsBox(centerX, 0.2); topShapeDef.density = 0; // 下 var bodyBottom:b2BodyDef = new b2BodyDef(); bodyBottom.position.Set(centerX, centerY * 2); var BottomShapeDef:b2PolygonDef = new b2PolygonDef(); BottomShapeDef.SetAsBox(centerX, 0.2); BottomShapeDef.density = 0; // 右 var bodyRight:b2BodyDef = new b2BodyDef(); bodyRight.position.Set(centerX * 2, centerY); bodyRight.angle = Math.PI; var rightShapeDef:b2PolygonDef = new b2PolygonDef(); rightShapeDef.SetAsBox(0.2, centerY); rightShapeDef.density = 0; // 左 var bodyLeft:b2BodyDef = new b2BodyDef(); bodyLeft.position.Set(0, centerY); bodyLeft.angle = Math.PI; var leftShapeDef:b2PolygonDef = new b2PolygonDef(); leftShapeDef.SetAsBox(0.2, centerY); leftShapeDef.density = 0; var top:b2Body = m_world.CreateBody(bodyTop); top.CreateShape(topShapeDef); var bottom:b2Body = m_world.CreateBody(bodyBottom); bottom.CreateShape(BottomShapeDef); var right:b2Body = m_world.CreateBody(bodyRight); right.CreateShape(rightShapeDef); var left:b2Body = m_world.CreateBody(bodyLeft); left.CreateShape(leftShapeDef); // 描画設定 var debugDraw:b2DebugDraw = new b2DebugDraw(); debugDraw.m_sprite = this; debugDraw.m_drawScale = DRAW_SCALE; debugDraw.m_fillAlpha = 0.3; debugDraw.m_lineThickness = 1; debugDraw.m_drawFlags = b2DebugDraw.e_shapeBit | b2DebugDraw.e_jointBit; m_world.SetDebugDraw(debugDraw); // イベントハンドラの登録 addEventListener(Event.ENTER_FRAME, enterFrameHandler); stage.addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler); stage.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler); stage.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler); } ////////////////////////////////////////////////////////////////////////////// // 自分の作成 ////////////////////////////////////////////////////////////////////////////// private function createMy():void{ var body:b2Body; var bodyDef:b2BodyDef; var boxDef:b2PolygonDef; var circleDef:b2CircleDef; bodyDef = new b2BodyDef(); bodyDef.position.x = 10; bodyDef.position.y = 15; circleDef = new b2CircleDef(); circleDef.radius = 1.66; circleDef.density = 0.3; circleDef.friction = 0.2; circleDef.restitution = 0.5; bodyDef.userData = new my(); bodyDef.userData.id = 'id_my'; bodyDef.userData.name = 'na_my'; bodyDef.userData.enable = true; bodyDef.userData.width = 100; bodyDef.userData.height = 100; body = m_world.CreateBody(bodyDef); body.CreateShape(circleDef); body.SetMassFromShapes(); addChild(bodyDef.userData); // ジョイントの定義 mouseJointDef = new b2MouseJointDef(); mouseJointDef.body1 = m_world.GetGroundBody(); mouseJointDef.body2 = body; mouseJointDef.target = body.GetWorldCenter(); mouseJointDef.maxForce = 30; mouseJointDef.timeStep = 1 / 24; } ////////////////////////////////////////////////////////////////////////////// // ボスの作成 ////////////////////////////////////////////////////////////////////////////// private function createBoss():void{ var body:b2Body; var bodyDef:b2BodyDef; var boxDef:b2PolygonDef; var circleDef:b2CircleDef; bodyDef = new b2BodyDef(); bodyDef.position.x = 13.5; bodyDef.position.y = 4; boxDef = new b2PolygonDef(); boxDef.SetAsBox(312.5 / 2 / DRAW_SCALE, 200 / 2 / DRAW_SCALE); boxDef.density = 0; bodyDef.userData = new boss(); bodyDef.userData.id = 'id_boss'; bodyDef.userData.name = 'na_boss'; bodyDef.userData.enable = true; bodyDef.userData.width = 312.5; bodyDef.userData.height = 200; body = m_world.CreateBody(bodyDef); body.CreateShape(boxDef); body.SetMassFromShapes(); addChild(bodyDef.userData); } ////////////////////////////////////////////////////////////////////////////// // ジョイントの処理 ////////////////////////////////////////////////////////////////////////////// private function mouseDownHandler(event:MouseEvent):void { mouseJoint = b2MouseJoint(m_world.CreateJoint(mouseJointDef)); } private function mouseUpHandler(event:MouseEvent):void { m_world.DestroyJoint(mouseJoint); mouseJoint = null; } private function mouseMoveHandler(event:MouseEvent):void { if (mouseJoint) { var x:Number = event.stageX / DRAW_SCALE; var y:Number = event.stageY / DRAW_SCALE; mouseJoint.SetTarget(new b2Vec2(x, y)); } } public function Update(e:Event):void{ m_world.Step(m_timeStep, m_iterations); 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 * 30; bb.m_userData.y = bb.GetPosition().y * 30; bb.m_userData.rotation = bb.GetAngle() * (180/Math.PI); if (bb.m_userData.enable == false) { m_world.DestroyBody(bb); removeChild(getChildByName(bb.m_userData.name)); } } } } private function enterFrameHandler(event:Event):void { m_world.Step(1 / 24, 10); } public var m_world:b2World; public var m_iterations:int = 10; public var m_timeStep:Number = 1.0/30.0; } }
コメント