Flashゲーム作成講座

初心者からクリエイター志望まで Flashゲームの作り方 入門

ゲームの作り方を初心者にも分かりやすく説明します。ゲームクリエイターを目指す方にも役立つ情報を。

敵が宝石を盗む

敵が宝石を盗む仕組みを作ります。

盗むと言っても、敵と宝石が接触したら敵を反転させて移動、いっしょに宝石も移動
という簡単な動作です。

 

 

敵が宝石を持っていく動作を確認しよう

まず、実際の動作を確認してみましょう。

下の画像をクリックすると動き出します。
ただ見ているだけでなく、何度か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;
}

 

変更点を見ていきます。

flash 敵がアイテムを持ち去るプログラム

 

変更点は敵の移動と出現処理の中にあります。

85-87行目、宝石と敵の座標を比較して当たり判定をしています。
36 足した値で比較しているのは、宝石と敵の距離を考えてのことです
この値を小さくすると、宝石と敵がより重なった状態で当たりとなります。
86行目では、敵の進行方向フラグを宝石付き右移動にしています。

 

96-99行目、敵が宝石付き右移動のとき、宝石に敵の座標を入れています。
敵は右へ移動しているので、宝石もいっしょに移動します。
敵の座標に 36 引いた値を代入しているのは、宝石と敵との距離をとるためです。

 

102行目、敵が画面外へ出たと判断する値を大きくしています。
値を大きくした理由は、宝石も画面の外へ移動させる為です
宝石の幅だけ値を大きくしています。

 

128行目、宝石が画面外へ出ていたら敵を出現させないようにしています。

 

 

次[ ゲームオーバー ]へ進む