2006 年度デザイン情報学科情報処理 III 第 12 回マウスによる制御 ブロック崩し の部品 ボール直径 10pixel の円ラケット横 60pixel 縦 10pixel, マウスにより左右に移動ブロック横 50pixel 縦 20pixel,28 個 (7 個 4 段 ) 壁 ( フィールド ) 横 400pixel 縦 600pixel 2006 年度デザイン情報学科情報処理 III 2 ゲーム画面 ゲーム画面内の状態遷移図 初期設定 ブロック の配置ゲーム本体 ボール の移動 ラケット の移動 ラケット と ボール の当たり判定 ブロック と ボール の当たり判定ゲーム終了判定 初期設定 ゲーム本体 ゲーム本体を繰り返す クリア画面へ すべてのブロックがなくなったら 残りのボールがなくなったら ゲームオーバー画面へ 2006 年度デザイン情報学科情報処理 III 3 2006 年度デザイン情報学科情報処理 III 4 Flash による実装 状態 フレーム状態遷移 フレームの移動モジュールの候補一つ一つのフレーム ボール ラケット ブロック サブモジュール ボール や ラケット は移動や跳ね返りなどのサブモジュールを持つ ラケットを作る Main レイヤーに 60pixel 10pixel の長方形を配置 シンボルに変換 する名前 : Racket タイプ : ムービークリップ基準点 : 上端中央配置されたムービークリップに名前を付ける名前 : racket ActionScript で参照される名前 2006 年度デザイン情報学科情報処理 III 5 2006 年度デザイン情報学科情報処理 III 6
マウスの動きに連動したラケット 移動位置を計算する関数 move() function move(mx) { this._x = mx; mx; ActionScript レイヤーフレーム 2 racket の move() 関数の呼出し ball.move(); racket.move(_xmouse); マウスの x 座標 2006 年度デザイン情報学科情報処理 III 7 ラケットに当たると跳ね返るボール ラケットとボールの当たり判定ボールがラケットより下に来たときに ボールの x 座標がラケットの幅の内側にあるかどうかで判定オブジェクト同士の当たり判定を利用 a.hittest(b) a が b に重なっているときに真 今回はこっちを利用 ball.move(); racket.move(_xmouse); if if (racket.hittest(ball)) { 2006 年度デザイン情報学科情報処理 III 8 ラケットに当たると跳ね返るボール モジュール構成 跳ね返り処理をボールに記述 ( 関数 bound()) var var dx dx = 1; 1; var var dy dy = 1; 1; var var speed speed = 3; 3; function move() { this._x += += speed speed * dx; dx; this._y += += speed speed * dy; dy;...... function bound() { dy dy *= *= -1; -1; ゲーム画面 ボール (ball) ラケット (racket) 2006 年度デザイン情報学科情報処理 III 9 2006 年度デザイン情報学科情報処理 III 10 モジュール構成 モジュール仕様 ( ゲーム画面 ) ゲーム画面 初期設定 本体 mx ボール (ball) move bound move 機能ブロック崩しのゲーム画面を表すインタフェースなし内部変数なし論理なし ラケット (racket) 2006 年度デザイン情報学科情報処理 III 11 2006 年度デザイン情報学科情報処理 III 12
モジュール仕様 ( ゲーム画面. 本体 ) モジュール仕様 (ball) 機能ブロック崩しゲームの進行および描画を行うインタフェースなし内部変数なし論理 ボールの移動ラケットの移動 if if ( ボールがラケットに当たる ) { ボールの跳ね返り 機能ボールを表すインタフェースなし 内部変数 dx: 移動方向 (x 軸 ) dy: 移動方向 (y 軸 ) speed: 移動速度論理なし 2006 年度デザイン情報学科情報処理 III 13 2006 年度デザイン情報学科情報処理 III 14 モジュール仕様 (ball.bound) 機能 y 軸の移動方向を反転するインタフェースなし内部変数なし論理 dy に -1 をかける ブロックを作る Main レイヤーに 50pixel 20pixel の長方形を配置 シンボルに変換 する名前 : Brick タイプ : ムービークリップ基準点 : 中央リンケージ : アクションスクリプトに書き出し最初のフレームに書き出し 2006 年度デザイン情報学科情報処理 III 15 2006 年度デザイン情報学科情報処理 III 16 ブロックを作る 配置されたムービークリップは削除アクションスクリプトで配置するため初期設定のフレームで ブロックを生成 var var b_x b_x = 7; 7; var var b_num b_num = b_x; b_x; する ActionScript for for (i (i = 0; 0; i < b_x; b_x; i++) i++) { tmp_brick tmp_brick = new new Object(); Object(); tmp_brick._x tmp_brick._x = i*50 i*50 + 50; 50; tmp_brick._y tmp_brick._y = 160; 160; attachmovie("brick", "brick"+i, "brick"+i, (i+1)*10, (i+1)*10, tmp_brick); tmp_brick); シンボルの名前 ActionScript で操作する名前 横に 7 個ブロックを配置 深度 ( 重なり順 ) 初期化オブジェクト 2006 年度デザイン情報学科情報処理 III 17 ブロックを作る ActionScript で操作する名前 brick0 ~ brick6 深度 ( 重なり順 ) 10, 20,..., 60 同じ深度には一つのオブジェクトしか置けないボールやラケットも深度を持つ初期化オブジェクト座標 (_x, _y) をブロックに設定する 2006 年度デザイン情報学科情報処理 III 18
ブロックを作る ( 複数段 ) ブロックを作る ( 複数段 ) 50 100 150 200 250 300 350 (0, 0) x brick7 100 120 140 160 brick0 brick1 brick2 brick6 y brick21 brick27 brick28 brick13 2006 年度デザイン情報学科情報処理 III 19 var var b_x b_x = 7; 7; var var b_y b_y = 4; 4; var var b_num b_num = b_x b_x * b_y; b_y; for for (j (j = 0; 0; j < b_y; b_y; j++) j++) { for for (i (i = 0; 0; i < b_x; b_x; i++) i++) { k = j*b_x j*b_x + i; i; tmp_brick tmp_brick = new new Object(); Object(); tmp_brick._x tmp_brick._x = i*50 i*50 + 50; 50; tmp_brick._y tmp_brick._y =...;...; attachmovie("brick", "brick"+k, "brick"+k, (k+1)*10, (k+1)*10, tmp_brick); tmp_brick); 大きく意味が異なることに注意 attachmovie("brick", "brick"+j*b_x+i,...); j=2, i=3 のとき brick143 になる ( 正解は brick17) 2006 年度デザイン情報学科情報処理 III 20 ブロックに当たると跳ね返るボール ブロック (brick0) とボールの当たり判定 ball.move(); racket.move(_xmouse); if if (racket.hittest(ball)) { if if (brick0.hittest(ball)) { 2006 年度デザイン情報学科情報処理 III 21 ボールが当たると消えるブロック...... if if (racket.hittest(ball)) { if if (brick0.hittest(ball)) { brick0.removemovieclip(); ブロックの存在を確認 if if (brick0!=!= null) null) { if if (brick0.hittest(ball)) { brick0.removemovieclip(); 2006 年度デザイン情報学科情報処理 III 22 すべてのブロックとの当たり判定 for for (k (k = 0; 0; k < b_num; b_num; k++) k++) { if if (brick(k) (brick(k)!=!= null) null) { if if (brick(k).hittest(ball)) { brick(k).removemovieclip(); for for (k (k = 0; 0; k < b_num; b_num; k++) k++) { tmp_brick tmp_brick = eval("brick"+k); eval("brick"+k); if if (tmp_brick (tmp_brick!=!= null) null) { if if (tmp_brick.hittest(ball)) { tmp_brick.removemovieclip(); 2006 年度デザイン情報学科情報処理 III 23 クリアの判定 is_clear = true; true; for for (k (k = 0; 0; k < b_num; k++) k++) { tmp_brick = eval("brick"+k); if if (tmp_brick!=!= null) null) { is_clear = false; if if (tmp_brick.hittest(ball)) { tmp_brick.removemovieclip(); for 文を抜けた後も is_clear が true ならば ブロックは残っていない ( ただし 最後のブロックが消えた瞬間はクリアではない ) 2006 年度デザイン情報学科情報処理 III 24
クリア画面への状態遷移 is_clear = true; true; for for (k (k = 0; 0; k < b_num; k++) k++) { tmp_brick = eval("brick"+k); if if (tmp_brick!=!= null) null) { is_clear = false; if if (tmp_brick.hittest(ball)) { tmp_brick.removemovieclip(); if if (is_clear == == true) true) { gotoandplay("clear"); clear とラベルの付けられたフレームに移動 クリア画面を作る レイヤーを 1 つ追加 ActionScript と Main の間名前 : Message フレームを 2 つ追加 ActionScript レイヤーでは 独立した 2 つのキーフレーム Message レイヤーでは 連続した 2 つのフレーム Main レイヤーでは ゲーム画面から連続した 5 つのフレーム 2006 年度デザイン情報学科情報処理 III 25 2006 年度デザイン情報学科情報処理 III 26 クリア画面 クリア画面 Message レイヤーの 4 フレーム目にラベルを設定 clear Message レイヤーの 1 フレーム目にラベルを設定 game Message レイヤーの 4 フレーム目にクリアメッセージを配置 シンボルに変換 する名前 :Clear タイプ : ボタン配置されたボタンに名前を付ける名前 : bclear ActionScript で参照される名前 2006 年度デザイン情報学科情報処理 III 27 2006 年度デザイン情報学科情報処理 III 28 Clear を押したときの動作 ActionScript レイヤーの 4 フレーム目に bclear.onpress = function() { 現状は何もしない最終的には スタート画面に移動する ActionScript レイヤーの 5 フレーム目に スタート画面を作る 先頭にフレームを 2 つ挿入 ActionScript レイヤーでは 独立した 2 つのキーフレーム Message レイヤーでは 連続した 2 つのフレーム Main レイヤーでは 連続した 2 つのフレーム gotoandplay(_currentframe - 1); 1); 1 つ前のフレームに移動 ( 繰返し ) 2006 年度デザイン情報学科情報処理 III 29 2006 年度デザイン情報学科情報処理 III 30
スタート画面 スタート画面 Message レイヤーの 1 フレーム目にラベルを設定 start Message レイヤーの 1 フレーム目にスタートメッセージを配置 シンボルに変換 する名前 :Start タイプ : ボタン配置されたボタンに名前を付ける名前 : bstart ActionScript で参照される名前 2006 年度デザイン情報学科情報処理 III 31 2006 年度デザイン情報学科情報処理 III 32 ブロック崩し を押したときの動作 ActionScript レイヤーの 1 フレーム目に bstart.onpress = function() { gotoandplay("game"); ゲーム画面に移動する ActionScript レイヤーの 2 フレーム目に gotoandplay(_currentframe - 1); 1); ミスの判定 ball の ActionScript function move() {...... function miss() { if if (this._y > Stage.height-this._height/2) { return true; true; else else { return false; 1 つ前のフレームに移動 ( 繰返し ) 2006 年度デザイン情報学科情報処理 III 33 2006 年度デザイン情報学科情報処理 III 34 ボールの初期化 ball の ActionScript function miss() {...... function init() { 乱数による初期位置 dy dy = 1; 1; (x 方向 ) の決定 speed speed = 3; 3; this._y = 250; 250; this._x = Math.round(Math.random() * Stage.width); if if (Math.random() > 0.5) 0.5) { dx dx *= *= -1; -1; 乱数による移動方向の決定 ゲームオーバーの判定 ゲーム画面の初期設定 ( ActionScript レイヤーの 3 フレーム目 ) var var life life = 3; 3; ゲーム画面のゲーム本体 ( ActionScript レイヤーの 4 フレーム目 ) if if (ball.miss()) { life--; if if (life (life == == 0) 0) { gotoandplay("gameover"); ball.init(); 2006 年度デザイン情報学科情報処理 III 35 2006 年度デザイン情報学科情報処理 III 36
ゲームオーバー画面を作る ゲームオーバー画面 フレームを 2 つ追加 ActionScript レイヤーでは 独立した 2 つのキーフレーム Message レイヤーでは 連続した 2 つのフレーム Main レイヤーでは ゲーム画面から連続した 7 つのフレーム 2006 年度デザイン情報学科情報処理 III 37 2006 年度デザイン情報学科情報処理 III 38 ゲームオーバー画面 Message レイヤーの 8 フレーム目にラベルを設定 gameover Message レイヤーの 8 フレーム目にゲームオーバーメッセージを配置 シンボルに変換 する名前 :GameOver タイプ : ボタン配置されたボタンに名前を付ける名前 : bgameover ActionScript で参照される名前 GameOver を押したときの動作 ActionScript レイヤーの 8 フレーム目に bgameover.onpress = function() { gotoandplay("start"); スタート画面に移動する ActionScript レイヤーの 9 フレーム目に gotoandplay(_currentframe - 1); 1); 1 つ前のフレームに移動 ( 繰返し ) 2006 年度デザイン情報学科情報処理 III 39 2006 年度デザイン情報学科情報処理 III 40 スコアの表示 Main レイヤーの 3 フレーム目にダイナミックテキストとして 5 桁 ( 適当な長さ ) の数字を配置インスタンス名を指定 score ActionScript で参照される名前同名の変数に値を代入すると その値が出力されるゲーム画面の初期設定 ( ActionScript レイヤーの 3 フレーム目 ) var var score score = 0; 0; 2006 年度デザイン情報学科情報処理 III 41 スコアの加算 ブロックにボールが当たったらスコアを加算 is_clear = true; true; for for (k (k = 0; 0; k < b_num; k++) k++) { tmp_brick = eval("brick"+k); if if (tmp_brick!=!= null) null) { is_clear = false; if if (tmp_brick.hittest(ball)) { tmp_brick.removemovieclip(); score score += += 100; 100; 2006 年度デザイン情報学科情報処理 III 42
ボールのスピードを取得する スコアにボールのスピードを加味するために ball に getspeed() を記述 function getspeed() { return speed; score の計算に利用 score score += += ball.getspeed() * 100; 100; 2006 年度デザイン情報学科情報処理 III 43