敵が宝石を盗む仕組みを作ります。
盗むと言っても、敵と宝石が接触したら敵を反転させて移動、いっしょに宝石も移動
という簡単な動作です。
まず、実際の動作を確認してみましょう。
下の画像をクリックすると動き出します。
ただ見ているだけでなく、何度かUFOを撃って破壊してみましょう。
敵と宝石が接触すると、敵の進む向きが変わります。
この時いっしょに宝石も移動するようになっています。
敵を破壊すると宝石はその場にとどまり、次の敵が出てきます。
宝石のなくなった所には、敵はでてきません。
前回の状態から動きが複雑になっていますが、プログラムとしては
シンプルな仕組みで実現できます。
次のようにプログラムを変更します。
const LINE_MAX = 6; // 宝と敵の段数
var enemyArr:Array = [];
var gemArr:Array = [];
var turn:Vector.<int> = new Vector.<int>(LINE_MAX,true);
var state:Vector.<int> = new Vector.<int>(LINE_MAX,true);
var delcnt:Vector.<int> = new Vector.<int>(LINE_MAX,true);
var beamFlg:int = 0;
var xSpeed:Number = 0;
initFunc();
//----------------------------------------------------
// システム関連の初期化
function initFunc() {
trace("initFunc ---");
for( var i=0; i < LINE_MAX; i++ ){
enemyArr[i] = new enemy(); // 敵の作成
enemyArr[i].stop();
gemArr[i] = new gem(); // 宝石の作成
disp.addChild(enemyArr[i]); // ステージに表示
disp.addChild(gemArr[i]);
}
initGame();
// 毎フレームイベントの登録
stage.addEventListener(Event.ENTER_FRAME, mainloop);
// マウスイベント 左ボタン押下のイベント登録
stage.addEventListener(MouseEvent.MOUSE_DOWN, m_down);
}
//----------------------------------------------------
// 毎フレーム処理
function mainloop(event:Event):void {
// マウスの座標を取得して自機を動かす
player_mc.x += (player_mc.mouseX / 5);
if( beamFlg == 0 ){ // 0:未発射 1:発射中
// 未発射なら自機と動きを同期させる
beam_mc.x = player_mc.x;
} else {
// 発射中のとき弾を移動する
beam_mc.y -= 10;
if( beam_mc.y < -30 ){ // 画面外へ弾が出たとき
beamFlg = 0;
beam_mc.x = player_mc.x;
beam_mc.y = player_mc.y - 25;
}
}
moveEnemy(); // 敵の移動
}
//----------------------------------------------------
// 敵の移動
function moveEnemy() {
var ex:int;
var ey:int;
for( var i=0; i < LINE_MAX; i++ ){
// 爆発中
if( state[i] == 2 ){
delcnt[i]--;
if( delcnt[i] == 0 ){
state[i] = 0; // 0:待機中
enemyArr[i].x = 530;
enemyArr[i].gotoAndStop(1);
}
}
// 出現中のみ以下の処理を行う
if( !(state[i] == 1) ) continue;
// 敵の移動処理
if( turn[i] == 0 ){
enemyArr[i].x -= xSpeed;
// 宝石と接触したら引き返す
if( (gemArr[i].x + 36) > enemyArr[i].x ){
turn[i] = 2;
}
// 左際まできたら右移動へ変更
if( enemyArr[i].x < 20 ){
turn[i] = 1;
}
} else {
enemyArr[i].x += xSpeed;
if( turn[i] == 2 ){
// 宝を連れて行く
gemArr[i].x = enemyArr[i].x - 36;
}
// 画面外へ出たら待機中にする
if( enemyArr[i].x > 580 ){
state[i] = 0; // 0:待機中
}
}
ex = enemyArr[i].x;
ey = enemyArr[i].y;
// 敵と弾との当たり判定の範囲を、見た目で調整する
if( (beam_mc.x > ex-20) && (beam_mc.x < ex+20)
&& (beam_mc.y > ey-20) && (beam_mc.y < ey+20) ){
state[i] = 2; // 2:爆発中
delcnt[i] = 18; // 消滅までのカウント
beamFlg = 0; // 0:未発射 1:発射中
enemyArr[i].play();
beam_mc.x = player_mc.x;
beam_mc.y = player_mc.y - 25;
}
}
if( Math.random() < 0.015 ){ // 敵の出現率
// 出現位置
var rnd:int = Math.floor(Math.random()*LINE_MAX);
for( i=0; i < LINE_MAX; i++ ){
var lno = (rnd + i) % LINE_MAX;
if( !(state[lno] == 0) ) continue;
if( gemArr[lno].x > 530 ) continue;
state[lno] = 1; // 1:出現中
turn[lno] = 0; // 0:左移動
enemyArr[lno].x = 530;
break;
}
}
}
//----------------------------------------------------
// ゲーム関連の初期化
function initGame() {
trace("initGame ---");
beamFlg = 0; // 0:未発射 1:発射中
xSpeed = 2.0; // 敵の初期移動速度
player_mc.y = 360; // 自機のy座標(固定)
beam_mc.x = player_mc.x;
beam_mc.y = player_mc.y - 25; // 弾の表示(半分 自機と重ねる)
for( var i=0; i < LINE_MAX; i++ ){
// 敵の初期設定
enemyArr[i].x = 530;
enemyArr[i].y = (i*42) + 60;
// 宝石の初期設定
gemArr[i].x = 40;
gemArr[i].y = (i*42) + 60;
turn[i] = 0; // 0:左移動 1:右移動 2:右(宝付き)
state[i] = 0; // 0:待機中 1:出現中 2:爆発中
}
}
//----------------------------------------------------
// マウス左ボタン押されたとき
function m_down(event:MouseEvent):void {
if( beamFlg == 1 ) return; // 0:未発射 1:発射中
beamFlg = 1;
// 自機の位置に弾を表示する
beam_mc.x = player_mc.x;
beam_mc.y = player_mc.y - 25;
}
変更点を見ていきます。

変更点は敵の移動と出現処理の中にあります。
85-87行目、宝石と敵の座標を比較して当たり判定をしています。
36 足した値で比較しているのは、宝石と敵の距離を考えてのことです。
この値を小さくすると、宝石と敵がより重なった状態で当たりとなります。
86行目では、敵の進行方向フラグを宝石付き右移動にしています。
96-99行目、敵が宝石付き右移動のとき、宝石に敵の座標を入れています。
敵は右へ移動しているので、宝石もいっしょに移動します。
敵の座標に 36 引いた値を代入しているのは、宝石と敵との距離をとるためです。
102行目、敵が画面外へ出たと判断する値を大きくしています。
値を大きくした理由は、宝石も画面の外へ移動させる為です。
宝石の幅だけ値を大きくしています。
128行目、宝石が画面外へ出ていたら敵を出現させないようにしています。
次[ ゲームオーバー ]へ進む