シューティングゲームを作る 〜その1〜
ParaFla! を用いて作成できるFlashゲームの例として、ParaFla!のページにシューティングゲームのサンプルが用意されています。
このシューティングゲームには適度に ActionScript が使用されているので、ActionScript の基礎を学ぶ際に一度目を通しておくと良いと思います。
ここでは、その『ParaFla! サンプルシューティングゲーム』の ActionScript をメインに解説します。
まず、スクリプトの前にメインイベントの説明をしていきます。
一番上にある『◎』がついているテキストは「START」ボタンで、
このボタンを押すとゲームが始まるラベルにジャンプするようになっています
(ちなみに、『◎』がついているイベントはボタン設定がされているイベントです)。
そのすぐ下にある画像イベントは、タイトル画像です。
透明度の調整でゆっくり出現するようになっています。
その後の「停止」で、「START」ボタンを押すまでFlashの再生を停止するようにしています。
ラベル「ゲームスタート」が、「START」ボタンを押した時に飛んでくるラベルです。
「START」ボタンを押すと、ここから再び再生が始まります。
ゲーム音楽を「ループ再生」させ、「画像消去」で深度 0 と 1 の「START」ボタンと、タイトル画像を消しています。
その下のスプライトには、ダメージを受けた時のエフェクトのイベントが入っています。
これは、ダメージを受けた時に再生されるように ActionScript で設定されています。
その下のテキスト4つは、ゲーム中に表示されるスコアとダメージです。
表示するものが2つなのに何故テキストイベントが4つあるのかというと、それぞれ色だけが違う2つのテキストを微妙にずらしてテキストに影があるように表現しているからです。
その下には、『●』がついた3つのスプライトがあります。
それぞれ上から順に「敵」、「弾」、「自機」のスプライトになっています
(『●』がついているスプライトは ActionScript が設定されているスプライトです)。
「敵のスプライト」には、ただ回転する絵のイベントが入っているだけで、
ゲーム中の敵の動きはすべて ActionScript で制御されています。
「敵のスプライト」の ActionScript の内容を以下に示します。
onClipEvent(load){
_x = Math.random() * 280 + 20; //横の出現位置をランダムに設定
_y = 0; //縦方向の出現位置は一番上なので、0に設定。
xv = Math.random() * 10 - 5; //横に移動する角度をランダムに設定
yv = Math.random() * 2 + 3; //縦に移動する角度をランダムに設定
if (eval("this") == _root.enChar){_visible = 0;}
/*
このスプライトは、ゲーム中ではActionScriptでコピーして使用している。
この処理は、このスプライトがコピーされたものでは無く、
コピー元のスプライトだった場合に、非表示にするものです。
*/
}
-
onClipEvent(enterFrame){
if (eval("this") != _root.enChar){
/*
『!=』は「異なったら」という意味。
コピー元で無く、コピーされたものだった場合の処理。
*/
_x += xv; //onClipEvent(load)で決めた移動量を現在位置に足しこむ。
_y += yv; // 〃
if (_x < 20){_x = 20; xv = Math.abs(xv);}
/*
壁(一番左)まで辿り着いたら、
進む方向を逆にする
*/
if (_x > 300){_x = 300; xv = -Math.abs(xv);} //壁(一番右)まで辿り着いたら
if (_y > 320){ //一番下まで辿り着いたら
_root.damage += 20; //ダメージを +20 する
_root.dmChar.gotoAndPlay("movieStart"); //ダメージを受けたらスプライトのイベントを再生する
this.removeMovieClip();
/*
自分自身を消去する。
removeMovieClipはスプライトを消去する命令ですが、
これはActionScriptでコピーしたスプライトにしか効果がありません。
コピー元のスプライトで使用すると無視されます。
*/
}
for (i=1; i<10; i++){ //iを1〜10まで変化させながら繰り返し処理する
if (this.hitTest(eval("_root.shChar" + i))){ //自機の出す弾に当たったら
eval("_root.shChar" + i).removeMovieClip(); //弾を消去する。
_root.bmNum ++;
if (_root.bmNum > 50){_root.bmNum = 1;}
//ここから爆風を表示する処理--------------------------
bc = "bmChar" + _root.bmNum;
_root.attachMovie("MC_Bomb", bc, 1050 + _root.bmNum);
eval("_root." + bc)._x = _x;
eval("_root." + bc)._y = _y;
//ここまで--------------------------------------------
_root.score += 10; //スコアを +10 する
this.removeMovieClip(); //自分を消去する
}
}
}
}
「Math.abs()」は、引数に指定した数値の絶対値を求めるメソッドです。
上記内では24行目と29行目で使用されています。
Math.abs(xv) = |xv|、-Math.abs(xv) = -|xv|
次に、「弾のスプライト」の ActionScript を示します。
onClipEvent(load){
_x = _root.myChar._x; //弾の発射位置を自機と同じ位置にする
_y = _root.myChar._y - 16; //↑と同じ。-16 することによって位置を調整している
if (eval("this") == _root.shChar){_y = -100;}
/*
このスプライトがコピーされたものでは無く、
コピー元のスプライトだった場合。
*/
}
-
onClipEvent(enterFrame){
if (_y > 0){ //弾が画面の一番上まで来ていなかったら
_y -= 16; //弾を上に移動させる
}else{ //それ以外(一番上まで来ている)だった場合は
this.removeMovieclip(); //自分を消去する
}
}
続いて「自機のスプライト」の ActionScript を示します。
onClipEvent(load){
shNum = 1; //弾のインスタンス名に付加する番号
shKeydown = 0;
/*
shKeydownは、ショットボタンを押しているかどうか、
状態を代入するための変数
*/
}
-
onClipEvent(enterFrame){
if (_x < 300){_x += Key.isDown(Key.RIGHT) * 6;} //右キーを押したら右に移動
if (_x > 20) {_x -= Key.isDown(Key.LEFT) * 6;} //左キーを押したら左に移動
if (Key.isDown(90)){ //キーコード90(Z)のキーを押したら
if(shKeydown == 0){ //shKeydownが0だったら
shNum ++; //shNumに1を足す
if (shNum > 10) shNum = 1; //shNumが10までいったら1に戻す
eval("_root.shChar" + shNum).removeMovieclip();
//↓で作ろうとしているスプライトが既に存在していたら消去する
duplicateMovieClip("_root.shChar", "shChar" + shNum, shNum + 980);
//duplicateMovieClipはスプライトを複製するActionScript。
//ここでスプライトをコピーしている。
}
shKeydown = 1; //shKeydownを1にする
}else{shKeydown = 0;} //それ以外なら(shKeydownが1だったら)0にする
}
これらのイベントの下にあるスクリプト『初期化』は、内部で使っている変数( shKeydown など)とスコア、ダメージを 0 に初期化する内容です。
「メインルーチンのスクリプト」がラベルとラベルジャンプに挟まれており、
ゲーム中はこのスクリプトがずっと実行され続けることになります。
「メインルーチンのスクリプト」については次のページで解説します。