ゲームオーバーの後、またプレイできるようリトライの機能を付けましょう。
テキストツールを使って「もう一度プレイするにはクリック」というメッセージを作ります。
まず、テキストを表示するレイヤーを選択します。
スコア ゲームオーバー のレイヤーをクリックしましょう。

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

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

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

文章が改行しないように枠のサイズを調整します。
選択ツールに切り替えて、テキストをステージ中央に配置します。

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

このインスタンス名を使って、プログラム側から制御します。
ゲームオーバーからリトライの表示まで、どのような動作なのか実際に確かめましょう。
次の画像をクリックして下さい。
「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;
}
変更点を見ていきます。

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

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

63行目、リトライメッセージが非表示なら、64行目以降の処理が行われます。
つまり、すべての宝石を奪われてゲームオーバーを表示したとき、
リトライメッセージが非表示なら、120回カウントした後にリトライを表示する
という仕組みになっています。
今回のゲームは 60 フレームで動かしているので、120 回カウントすることは
2秒待つことになります。
「GAME OVER」が表示されてから2秒後に、リトライメッセージが表示されます。
フレームとは何か忘れてしまった人は[ フレームレートを変更する ]を参照して下さい。

186行目、リトライメッセージが表示しているなら 187行目以降が実行されます。
つまり、マウスをクリックしたとき、リトライメッセージが表示されていたら
ゲームの初期化 initGame() を実行します。
このように初期化するための関数をしっかり作っておけば、少しの手順で
ゲームをリトライする仕組みが作れます。
188行目で return を使ってこの関数を抜けています。
190行以降の処理はゲーム中の処理のため、実行する必要がありません。
余計な処理を行わないようにプログラミングすると、バグの発生率を下げることが
できます。覚えておいて下さい。
次[ スコアを表示する ]へ進む