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を作りました。
今回は自分(オレンジの玉)以外の動くBodyを作りたいと思います。
作るBodyは仮に敵と仲間に分けます。
それだけでは自分(オレンジの玉)とあまり変わらなくなってしまうので
30秒からのカウントダウンするタイマー機能を付けて軽減時間のあるゲームにし
5秒ごとに敵・仲間と交互に3体づつ出現する形にしてみたいと思います。

画面右上に「残り時間」の文字の入った白半透明の画像、
そして「30」という残り時間用の文字を配置しました。
「30」はas側で数字を変更するため「disp_txt」というインスタンス名を付けました。
それと自分(オレンジの玉)同様シンボル化してASリンゲージした敵画像と仲間画像がライブラリにあります。
var timer:Timer = new Timer(1000); timer.addEventListener(TimerEvent.TIMER,onTimer); timer.start();
タイマーをコンストラクタに設置。
public function game04(){
createWorld();
createMy();
createBoss();
createEnemy1();
addEventListener(Event.ENTER_FRAME, Update, false, 0, true);
var timer:Timer = new Timer(1000);
timer.addEventListener(TimerEvent.TIMER,onTimer);
timer.start();
}
最初の敵はコンストラクタで作ってしまいます。
var i:int = int(disp_txt.text);
i = i-1;
disp_txt.text = String(i);
switch (i) {
case 25 :
createFriend1();
break;
case 20 :
createEnemy2();
break;
case 15 :
createFriend2();
break;
case 10 :
createEnemy3();
break;
case 5 :
createFriend3();
break;
}
ステージに作ったdisp_txtの数字を1秒毎に減らしながら
5秒置きに敵と仲間を交互に作りました。
敵と仲間の作りはほぼ自分(オレンジの玉)と同じなので省略。
ただ、ジョイントで動かすことは出来ません。
それと仲間の方が衝突後ややトリッキーな動きをします。
敵と仲間を作るときに色々変更するかなと思って別々のファンクションにしちゃいましたが
出来てみたらidとnameしか変更してませんでした。
同じソース回せばよかったですね……。
タイマーがつくため、自動で再生されると格好が悪いので今回からサンプルがポップアップです。

◆ポップアップでサンプルswfを開く
(ボス・仲間・敵画像:MGS技研)
衝突しても何も起こらないので寂しいですがタイマーを使いながらの制御が出来ました。
◆サンプルソース全文
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 game04 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 game04(){
createWorld();
createMy();
createBoss();
createEnemy1();
addEventListener(Event.ENTER_FRAME, Update, false, 0, true);
var timer:Timer = new Timer(1000);
timer.addEventListener(TimerEvent.TIMER,onTimer);
timer.start();
}
//////////////////////////////////////////////////////////////////////////////
// ワールドの作成
//////////////////////////////////////////////////////////////////////////////
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);
}
//////////////////////////////////////////////////////////////////////////////
// 敵1の作成
//////////////////////////////////////////////////////////////////////////////
private function createEnemy1():void{
var body:b2Body;
var bodyDef:b2BodyDef;
var boxDef:b2PolygonDef;
var circleDef:b2CircleDef;
bodyDef = new b2BodyDef();
bodyDef.position.Set(25.5 / 2, 2);
circleDef = new b2CircleDef();
circleDef.radius = 1.16;
circleDef.density = 0.8;
circleDef.friction = 0;
circleDef.restitution = 1;
bodyDef.userData = new enemy();
bodyDef.userData.id = 'id_enemy1';
bodyDef.userData.name = 'na_enemy1';
bodyDef.userData.enable = true;
bodyDef.userData.width = 70;
bodyDef.userData.height = 70;
body = m_world.CreateBody(bodyDef);
body.CreateShape(circleDef);
body.SetLinearVelocity(new b2Vec2(5, 0));
body.SetMassFromShapes();
addChild(bodyDef.userData);
}
//////////////////////////////////////////////////////////////////////////////
// 敵2の作成
//////////////////////////////////////////////////////////////////////////////
private function createEnemy2():void{
var body:b2Body;
var bodyDef:b2BodyDef;
var boxDef:b2PolygonDef;
var circleDef:b2CircleDef;
bodyDef = new b2BodyDef();
bodyDef.position.Set(25.5 / 2, 2);
circleDef = new b2CircleDef();
circleDef.radius = 1.16;
circleDef.density = 0.8;
circleDef.friction = 0;
circleDef.restitution = 1;
bodyDef.userData = new enemy();
bodyDef.userData.id = 'id_enemy2';
bodyDef.userData.name = 'na_enemy2';
bodyDef.userData.enable = true;
bodyDef.userData.width = 70;
bodyDef.userData.height = 70;
body = m_world.CreateBody(bodyDef);
body.CreateShape(circleDef);
body.SetLinearVelocity(new b2Vec2(5, 0));
body.SetMassFromShapes();
addChild(bodyDef.userData);
}
//////////////////////////////////////////////////////////////////////////////
// 敵3の作成
//////////////////////////////////////////////////////////////////////////////
private function createEnemy3():void{
var body:b2Body;
var bodyDef:b2BodyDef;
var boxDef:b2PolygonDef;
var circleDef:b2CircleDef;
bodyDef = new b2BodyDef();
bodyDef.position.Set(25.5 / 2, 2);
circleDef = new b2CircleDef();
circleDef.radius = 1.16;
circleDef.density = 0.8;
circleDef.friction = 0;
circleDef.restitution = 1;
bodyDef.userData = new enemy();
bodyDef.userData.id = 'id_enemy3';
bodyDef.userData.name = 'na_enemy3';
bodyDef.userData.enable = true;
bodyDef.userData.width = 70;
bodyDef.userData.height = 70;
body = m_world.CreateBody(bodyDef);
body.CreateShape(circleDef);
body.SetLinearVelocity(new b2Vec2(5, 0));
body.SetMassFromShapes();
addChild(bodyDef.userData);
}
//////////////////////////////////////////////////////////////////////////////
// 仲間1の作成
//////////////////////////////////////////////////////////////////////////////
private function createFriend1():void{
var body:b2Body;
var bodyDef:b2BodyDef;
var boxDef:b2PolygonDef;
var circleDef:b2CircleDef;
bodyDef = new b2BodyDef();
bodyDef.position.Set(25.5 / 2, 2);
circleDef = new b2CircleDef();
circleDef.radius = 1.16;
circleDef.density = 0.1;
circleDef.friction = 0;
circleDef.restitution = 1;
bodyDef.userData = new friend();
bodyDef.userData.id = 'id_friend1';
bodyDef.userData.name = 'na_friend1';
bodyDef.userData.enable = true;
bodyDef.userData.width = 70;
bodyDef.userData.height = 70;
body = m_world.CreateBody(bodyDef);
body.CreateShape(circleDef);
body.SetLinearVelocity(new b2Vec2(5, 0));
body.SetMassFromShapes();
addChild(bodyDef.userData);
}
//////////////////////////////////////////////////////////////////////////////
// 仲間2の作成
//////////////////////////////////////////////////////////////////////////////
private function createFriend2():void{
var body:b2Body;
var bodyDef:b2BodyDef;
var boxDef:b2PolygonDef;
var circleDef:b2CircleDef;
bodyDef = new b2BodyDef();
bodyDef.position.Set(25.5 / 2, 2);
circleDef = new b2CircleDef();
circleDef.radius = 1.16;
circleDef.density = 0.1;
circleDef.friction = 0;
circleDef.restitution = 1;
bodyDef.userData = new friend();
bodyDef.userData.id = 'id_friend2';
bodyDef.userData.name = 'na_friend2';
bodyDef.userData.enable = true;
bodyDef.userData.width = 70;
bodyDef.userData.height = 70;
body = m_world.CreateBody(bodyDef);
body.CreateShape(circleDef);
body.SetLinearVelocity(new b2Vec2(5, 0));
body.SetMassFromShapes();
addChild(bodyDef.userData);
}
//////////////////////////////////////////////////////////////////////////////
// 仲間3の作成
//////////////////////////////////////////////////////////////////////////////
private function createFriend3():void{
var body:b2Body;
var bodyDef:b2BodyDef;
var boxDef:b2PolygonDef;
var circleDef:b2CircleDef;
bodyDef = new b2BodyDef();
bodyDef.position.Set(25.5 / 2, 2);
circleDef = new b2CircleDef();
circleDef.radius = 1.16;
circleDef.density = 0.1;
circleDef.friction = 0;
circleDef.restitution = 1;
bodyDef.userData = new friend();
bodyDef.userData.id = 'id_friend3';
bodyDef.userData.name = 'na_friend3';
bodyDef.userData.enable = true;
bodyDef.userData.width = 70;
bodyDef.userData.height = 70;
body = m_world.CreateBody(bodyDef);
body.CreateShape(circleDef);
body.SetLinearVelocity(new b2Vec2(5, 0));
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 onTimer(e:TimerEvent):void{
var i:int = int(disp_txt.text);
i = i-1;
disp_txt.text = String(i);
switch (i) {
case 25 :
createFriend1();
break;
case 20 :
createEnemy2();
break;
case 15 :
createFriend2();
break;
case 10 :
createEnemy3();
break;
case 5 :
createFriend3();
break;
}
}
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;
}
}

コメント