Flashゲーム作成講座

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

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

リトライ

ゲームオーバーの後、またプレイできるようリトライの機能を付けましょう。

 

 

リトライのメッセージを作ろう

テキストツールを使って「もう一度プレイするにはクリック」というメッセージを作ります。

まず、テキストを表示するレイヤーを選択します。
スコア ゲームオーバー のレイヤーをクリックしましょう。

flash レイヤーを使って表示の優先を管理

これは「GAME OVER」と同じレイヤーですね。

 

 

ツールの中からテキストツールをクリックします。
そしてプロパティを開きます。
このとき、次の画像のように「GAME OVER」のプロパティが表示される時があります。
ステージをみると「GAME OVER」に枠が付いていると思います。
適当な場所を1回だけクリックして、選択状態を解除します。

flash 他のテキストが選択されている状態

 

 

テキストが選択されていない状態のプロパティが表示されたら、次のように設定します。
クラシックテキスト、ダイナミックテキスト、サイズ 20 pt、カラーは赤色

flash ダイナミックテキストを設定する

 

 

テキストツールを選択した状態で、GAME OVER の左下あたりをクリックします。
そして「もう一度プレイするにはクリック」と入力しましょう。

flash ダイナミックテキストを作成する

文章が改行しないように枠のサイズを調整します。

 

 

選択ツールに切り替えて、テキストをステージ中央に配置します。

flash 選択ツールでテキストをステージの中央に移動する

 

 

最後にインスタンス名を付けます。
retry_txt と入力しましょう。

flash インスタンス名を付けてプログラムで動かす

このインスタンス名を使って、プログラム側から制御します。

 

 

リトライの動作を確認しよう

ゲームオーバーからリトライの表示まで、どのような動作なのか実際に確かめましょう。
次の画像をクリックして下さい。

 

「GAME OVER」が表示されたら、クリックしないで数秒待って下さい
2秒後に「もう一度プレイするにはクリック」のメッセージが表示されます。

メッセージが表示されたらクリックしてみましょう。
宝石が再配置され、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;
var retCnt:int = 0;
var retryWait:int = 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();                     // 敵の移動

    if( retCnt == LINE_MAX ){        // 全ての宝石を奪われた
        gameover_txt.visible = true; // ゲームオーバーを表示
        if( !retry_txt.visible ){
            retryWait++;
            if( retryWait > 120 ){
                retry_txt.visible = true;    // リトライ表示
            }
        }
    }
}


//----------------------------------------------------
// 敵の移動
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:待機中
                retCnt++;            // 宝石を盗った回数
            }
        }
        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 ---");

    gameover_txt.visible = false;    // ゲームオーバーを非表示
    retry_txt.visible = false;       // リトライを非表示

    beamFlg = 0;                     // 0:未発射 1:発射中
    xSpeed = 2.0;                    // 敵の初期移動速度
    retCnt = 0;                      // 宝石を盗った回数
    retryWait = 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( retry_txt.visible ){         // リトライが表示中の時
        initGame();                  // ゲーム関連の初期化
        return;
    }

    if( beamFlg == 1 ) return;       // 0:未発射 1:発射中

    beamFlg = 1;

    // 自機の位置に弾を表示する
    beam_mc.x = player_mc.x;
    beam_mc.y = player_mc.y - 25;
}

 

変更点を見ていきます。

flash 時間をカウントする変数を宣言する

11行目、メッセージを表示するまでの時間をカウントする変数を宣言しています。

 

 

flash 変数の初期化とメッセージの非表示

159行目、「もう一度プレイするにはクリック」のテキストを非表示にします。
164行目、メッセージを表示するまでの時間を0に初期化しています。

 

 

flash リトライを表示する仕組み

63行目、リトライメッセージが非表示なら、64行目以降の処理が行われます。
つまり、すべての宝石を奪われてゲームオーバーを表示したとき、
リトライメッセージが非表示なら、120回カウントした後にリトライを表示する
という仕組みになっています。

今回のゲームは 60 フレームで動かしているので、120 回カウントすることは
2秒待つことになります。
「GAME OVER」が表示されてから2秒後に、リトライメッセージが表示されます。

フレームとは何か忘れてしまった人は[ フレームレートを変更する ]を参照して下さい。

 

 

flash クリックを受け付けてリトライの処理を行う

186行目、リトライメッセージが表示しているなら 187行目以降が実行されます。
つまり、マウスをクリックしたとき、リトライメッセージが表示されていたら
ゲームの初期化 initGame() を実行します。

このように初期化するための関数をしっかり作っておけば、少しの手順で
ゲームをリトライする仕組みが作れます。

188行目で return を使ってこの関数を抜けています。
190行以降の処理はゲーム中の処理のため、実行する必要がありません。
余計な処理を行わないようにプログラミングすると、バグの発生率を下げることが
できます。覚えておいて下さい。

 

 

次[ スコアを表示する ]へ進む