ブロック崩し - Flash(ActionScript)で様々なゲームを作ろう
目次
実行画面
普通のブロック崩しです。マウスでパドルを動かしてブロックを全て消すとクリア。ボールの跳ね返りかたがおかしい部分はプログラムを簡潔にするためなのでご勘弁ください。.fla ファイルダウンロード
今回のポイント
- 配列
- Drawing API
画面作成
まずステージ・ステージに乗せるシンボルなどを作ってゆきます。ステージのプロパティ
最初にステージのプロパティを適当に設定します。この解説で使っているムービーでは、サイズを「320×240」、背景色を「#FFD3EF」、フレームレートを「30fps」としています。ゲーム開始画面の作成
1フレーム目にゲーム開始画面を適当に作成して、スタート用のボタンシンボルを作って乗せてください。ゲーム画面の作成
2フレーム目のメインのゲーム画面を作成します。まず2フレーム目にキーフレームを作成し中身を全て削除します。次に画面下部中央にパドルのムービークリップシンボルを作成し、ステージ上のインスタンスに「pad_mc」と名前を付けます。次にボールのムービークリップシンボルを作成し、ステージ上のインスタンスに「ball_mc」と名前を付けます。最後に画面上部にブロックを配置するエリアを四角形で描き、ムービークリップシンボルに変換してステージ上のインスタンスに「area_mc」と名前を付けます。パドルとボールの中心点は画像の中心、ブロック配置エリアの中心点は、左上隅にしてください。
ゲームクリア画面の作成
次に3フレーム目にゲームクリア画面を作成します。まず3フレーム目にキーフレームを作成し中身を全て削除し、ゲームクリア画面を適当に作成してください。ActionScript の記述
続いて、フレームやムービークリップに ActionScript を記述して行きます。1フレーム目のアクション
1フレーム目をクリックして、以下のフレームアクションを記述してください。
stop();
ゲーム画面に移行しないようにストップします。スタートボタンのアクション
1フレーム目のスタートボタンをクリックして、以下のボタンアクションを記述してください。
on(release) {
gotoAndStop(2);
}
ボタンが押されたらゲーム画面に移行します。2フレーム目のアクション
2フレーム目をクリックして、以下のフレームアクションを記述してください。
score = 0; // スコア
bnum_x = 6; // 横ブロック数
bnum_y = 4; // 縦ブロック数
bsize_w = area_mc._width / bnum_x; // ブロック横サイズ
bsize_h = area_mc._height / bnum_y; // ブロック縦サイズ
b_array = new Array(); // ブロックがあれば true
area_mc._visible = false;
// 全ブロック表示
for (var y = 0; y < bnum_y; y++) {
b_array[y] = new Array();
for (var x = 0; x < bnum_x; x++) {
b_array[y][x] = true;
drawBlock(x, y, 0xF5F7A4, 0xFFAADE);
}
}
// ブロック当たり判定
function hitBlock() {
var x = Math.floor((ball_mc._x - area_mc._x) / bsize_w);
var y = Math.floor((ball_mc._y - area_mc._y) / bsize_h);
if (x < 0 || x >= bnum_x || y < 0 || y >= bnum_y) return false;
if (b_array[y][x] == false) return false;
drawBlock(x, y, 0xFFD3EF, 0xFFD3EF);
b_array[y][x] = false;
score++;
if (score >= bnum_y * bnum_x) gotoAndStop(3);
var px = (ball_mc._x - area_mc._x) % bsize_w;
var py = (ball_mc._y - area_mc._y) % bsize_h;
if (px < 6 || px >= bsize_w - 6) ball_mc.vx = -ball_mc.vx;
if (py < 4 || py >= bsize_h - 4) ball_mc.vy = -ball_mc.vy;
return true;
}
// ブロック描画 c:描画色 lc:ライン色
function drawBlock(x, y, c, lc) {
var sx = area_mc._x + x * bsize_w;
var sy = area_mc._y + y * bsize_h;
var ex = area_mc._x + (x + 1) * bsize_w - 3;
var ey = area_mc._y + (y + 1) * bsize_h - 3;
beginFill(c);
lineStyle(2, lc);
moveTo(sx, sy);
lineTo(ex, sy);
lineTo(ex, ey);
lineTo(sx, ey);
endFill();
}
解説は後述します。パドルのアクション
2フレーム目のパドルをクリックして、以下のムービークリップアクションを記述してください。
onClipEvent(enterFrame) {
_x = _root._xmouse;
}
パドルをマウスに追従するようにしています。ボールのアクション
2フレーム目のボールをクリックして、以下のムービークリップアクションを記述してください。
onClipEvent(load) {
vx = 4;
vy = 4;
}
onClipEvent(enterFrame) {
// 移動
_x += vx;
_y += vy;
if (_x < 0 || _x > Stage.width) vx = -vx;
if (_y < 0) vy = -vy;
// パドルとの当たり判定
if (_root.pad_mc.hitTest(_x, _y, false)) {
vy = -vy;
vx = (_x - _root.pad_mc._x) * 12 / _root.pad_mc._width;
}
// ブロックとの当たり判定
_root.hitBlock();
// ゲームオーバー判定
if (_y > Stage.height) {
_root.clear();
_root.gotoAndPlay(1);
}
}
解説は後述します。実行
以上が完成したら保存してゲームを実行してみてください。ActionScript 解説
2フレーム目のフレームアクション解説
ここのフレームアクションには、ブロックに関する処理が記述してあります。
score = 0;
得点です。今回は表示されませんが、ゲームクリアのチェックに使っています。
bnum_x = 6;
bnum_y = 4;
画面に表示するブロック数です。bnum_x が横、bnum_y が縦のブロック数です。これを変更すればブロック数を変えることができます。
bsize_w = area_mc._width / bnum_x;
bsize_h = area_mc._height / bnum_y;
ひとつのブロックの幅と高さです。ブロックを描画するエリア (area_mc) の大きさからブロックの数を割って算出しています。
b_array = new Array();
ブロックが存在するかチェックするための2次元配列です。(x, y) にブロックが存在すれば b_array[y][x] が true になり、存在しなければ false となります。ActionScript における配列の作り方は後述します。
area_mc._visible = false;
ブロックを描画するエリアは見えていてはいけないので最初に消しておきます。
for (var y = 0; y < bnum_y; y++) {
b_array[y] = new Array();
for (var x = 0; x < bnum_x; x++) {
b_array[y][x] = true;
drawBlock(x, y, 0xF5F7A4, 0xFFAADE);
}
}
ゲーム開始前に、まず全てのブロックを描画します。ブロックチェック配列 b_array の値をセットし、ブロック描画関数 drawBlock を呼び出します。drawBlock 関数については後述します。
function hitBlock() {
ブロックとボールとの当たり判定を行う関数です。
var x = Math.floor((ball_mc._x - area_mc._x) / bsize_w);
var y = Math.floor((ball_mc._y - area_mc._y) / bsize_h);
ここで、ボールがどこのブロックのエリアに入っているかを計算しています。このブロック座標 (x, y) がどのブロックを表すかは以下の図を参照してください。ちなみに、関数の中で var を使って変数宣言するとローカル変数となり、関数の中でのみ使える変数となります。
if (x < 0 || x >= bnum_x || y < 0 || y >= bnum_y) return false;
ボールが area_mc の範囲外ならば、何もせずに戻ります。
if (b_array[y][x] == false) return false;
ボールのあるエリアのブロックが既に消えていれば何もせずに戻ります。
drawBlock(x, y, 0xFFD3EF, 0xFFD3EF);
背景色でブロックを書き直すことによって、ブロックを消します。
b_array[y][x] = false;
チェック配列の値をクリアします。
score++;
得点を追加します。
if (score >= bnum_y * bnum_x) gotoAndStop(3);
得点がブロック数と同じになれば全て消えたということなので、ゲームクリア画面に移行します。
var px = (ball_mc._x - area_mc._x) % bsize_w;
var py = (ball_mc._y - area_mc._y) % bsize_h;
(px, py) は対象のブロックの左上を (0, 0) としたときのボールの相対座標になります。
if (px < 6 || px >= bsize_w - 6) ball_mc.vx = -ball_mc.vx;
ブロックの右端または左端に当たったとき、ボールの x 方向の速度を反転します。
if (py < 4 || py >= bsize_h - 4) ball_mc.vy = -ball_mc.vy;
ブロックの上端または下端に当たったとき、ボールの y 方向の速度を反転します。
function drawBlock(x, y, c, lc) {
ブロック描画関数です。c がブロックの塗り色、lc がブロックの線の色です。
var sx = area_mc._x + x * bsize_w;
var sy = area_mc._y + y * bsize_h;
var ex = area_mc._x + (x + 1) * bsize_w - 3;
var ey = area_mc._y + (y + 1) * bsize_h - 3;
描画するブロックの左上、右下座標を計算し、それぞれ (sx, sy)、(ex, ey) に代入します。
beginFill(c);
Drawing API によって線と塗りを開始します。c が塗り色となります。
lineStyle(2, lc);
線のスタイルを設定します。太さ2、色が lc の線になります。
moveTo(sx, sy);
現在の描画位置を (sx, sy) に移動します。線は引かれません。
lineTo(ex, sy);
lineTo(ex, ey);
lineTo(sx, ey);
lineTo によって、現在の描画位置から、引数で指定した座標まで線が引かれます。
endFill();
引かれた線で囲まれた部分に、beginFill で指定した塗りを適用します。線が開いている場合は、自動的に始点と終点が閉じられます。ボールのムービークリップアクション解説
onClipEvent(load) {
vx = 4;
vy = 4;
}
vx, vy はボールの速度です。ゲーム開始時は右下に向かうようにしています。
onClipEvent(enterFrame) {
毎フレームの処理です。
_x += vx;
_y += vy;
ボールの座標に速度を加えます。
if (_x < 0 || _x > Stage.width) vx = -vx;
if (_y < 0) vy = -vy;
画面の左・右・上端に当たったときは、速度を反転してボールが反射するようにします。
if (_root.pad_mc.hitTest(_x, _y, false)) {
パドルとの当たり判定を行っています。
vy = -vy;
vx = (_x - _root.pad_mc._x) * 12 / _root.pad_mc._width;
ボールとパドルが当たったら、y 方向の速度を反転し、x 方向はパドルの当たった位置によって速度を変えます。パドルの左に当たるほど左方向の速度が速く、パドルの右に当たるほど右方向の速度が速くなるようにします。
_root.hitBlock();
ボールとブロックとの当たり判定を行います。
if (_y > Stage.height) {
_root.clear();
_root.gotoAndPlay(1);
}
ボールの y 座標が画面下に来たときはすなわちゲームオーバーなので、Drawing API の clear メソッドによって残ったブロックを全て消去し、ゲーム開始画面に戻ります。ActionScript での配列の作り方
ary = new Array();
によって1次元配列を生成することができます。生成した後は
ary[0] = 1;
ary[1] = "abcde";
ary[2] = true;
のように各要素を使うことができます。上記のように要素には違う型の値を入れることもできます。
ary = new Array(1, "abcde", true);
のように配列生成のときに初期かも同時に行うことができます。また省略した書き方で、
ary = [1, "abcde", true];
でもOKです。2次元配列は、配列の各要素を配列にすることで行います。
ary = new Array();
ary[0] = new Array();
ary[1] = new Array();
ary[2] = new Array();
こんな感じです。