« 連載を一冊にまとめた「ActionScript クリエイティブテクニック - Flash CS3/8対応版」発売! |
DEEP KICK.com Blog
| AS3 Technical Bible - vol.05
2Dアクションゲーム ブロックくずし Part.2 »
2008年10月30日
AS3 Technical Bible - vol.04
2Dアクションゲーム ブロックくずし Part.1
web creators 2008年12月号
に掲載の連載「ActionScript 3 Technical Bible」のテーマは、「2Dアクションゲーム ブロックくずし Part.1」になります。
できあがりのサンプルはこちらをクリック。
左右矢印キーで、パッドを動かします。
今回の連載から2回に分けて、2Dアクションゲームの原点のブロックくずし型ゲーム「DEEP BLOCK TENNIS」の作成について解説します。ゲームの構成要素としては、縦横に並んだ「ブロック」、左右に移動させる「パッド」、パッドやブロックやシーンの壁に衝突して跳ね返り運動を行う「ボール」の3つの要素があります。前編となる今回は、「パッド」と「ボール」がシーン内において跳ね返り運動を延々と行い続けるところまで作成します。サンプルを作成するための詳しい解説は誌面の方を見ていただくとして、ここではキーでパッドを制御するメソッドの定義と、パッドとボールの衝突処理について補足します。
Mainクラスのコンストラクタが実行されると、パッドを初期化するための関数setPad()が実行されます。この関数では、Flaファイルであらかじめ作成したパッド用のムービークリップに対してリンケージ設定を行っておいたものを、new Pad() で呼び出しています。
パッドの初期位置を確定し、X座標の可動範囲を計算します。addChild() メソッドで表示リストに追加し、何らかのキーが押された時にonKeyDownHandler()、押されていたキーが離された時にonKeyUpHandler() が実行されるようにリスナー関数を設定します。以上がパッドを初期化するための関数setPad()の仕事になります。
パッド初期化関数setPad()
private function setPad():void {
//padVX = 0;
//パッドの作成
pad = new Pad();
pad.x = sceneCenterX;
pad.y = padY;
padLeft = left + pad.width / 2 + 5;
padRight = right - pad.width / 2 - 5;
addChild(pad);
stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDownHandler);
stage.addEventListener(KeyboardEvent.KEY_UP, onKeyUpHandler);
}
パッドをキーで操作するためのリスナー関数onKeyDownHandler()とonKeyUpHandler()の定義を見てみます。onKeyDownHandler() は何らかのキーが押下されたときに実行されますが、何のキーが押下されたのかをswitch文で判定します。左矢印キーが押下されるとkeyCodeプロパティは[Keyboard.LEFT]、右矢印キーが押下されるとkeyCodeプロパティの値は[Keyboard.RIGHT]を返しますので、それぞれの処理を記述しています。[padAccel]には、キーが押下されている間の毎フレームごとにパッドがX軸方向を移動する距離、すなわちパッドの水平方向のスピードを表す数値が入っています。スピードというのは単なる「速さの大きさ」なので、パッドをX軸方向のどちらに動かすのかという「ベクトル」に変換した情報を、パッドの速度を表すプロパティ[padVX]に代入します。キーがアップされると、パッドの速度を「0」にします。
パッド操作用リスナー関数
private function onKeyDownHandler(event:KeyboardEvent):void {
switch(event.keyCode) {
case Keyboard.LEFT:
//左矢印キー
padVX = -padAccel;
break;
case Keyboard.RIGHT:
//右矢印キーの処理
padVX = padAccel;
break;
}
}
private function onKeyUpHandler(event:KeyboardEvent):void {
padVX = 0;
}
以上が、パッドを制御するために必要な準備段階です。パッドを毎フレームごとに移動させるために必要な情報は、すべて揃いました。パッドとボールを動かし、それぞれが衝突をしていないかどうかをモニターするために毎フレーム実行されるリスナー関数onEnterFrameHandler()を見ていきます。パッドはその可動範囲内でのみ移動することができます。もし可動範囲外に出ようとしていたら、可動範囲の最小値もしくは最大値で固定しておきます。そうしないと、パッドはシーンの外部に自由に出ていってしまいます。
パッドとボールが座標上で接触しているかどうかは、hitTestObject(obj:DisplayObject):Boolean メソッドを使って調べます。これはDisplayObjectクラスで用意されているメソッドで、引数に渡したobjと接触しているかどうかを判定することができます。
ムービークリップ[Pad]の構造上、padcore部分とpadframe部分は重なっているので、padcoreに接触しているのであれば、かならずpadframeに接触しているはずです。したがってまず最初にpadframeに接触しているかどうかを調べています。もしpadframeに接触していなければ、padcoreには接触していないからです。padframeに接触していたら、必要以上にボールとパッドの接触を検出しないために、とりあえずボールをパッドと接触しない位置にまで移動させておきます。ここではボールの半径分、ボールを上に引き上げています。もしpadcoreに接触していなかったら、パッドの外縁部にボールが接触したとみなせるので、ゲームの難易度を上げるためにボールの水平方向の速度を1.2倍に増加します。padcoreにも接触していれば、ボールの速度はそのままです。そしてボールに対して垂直方向の跳ね返り運動を適用します。ボールの移動と跳ね返り運動については、誌面のほうに図を用いて詳しく解説してありますので、そちらを読んでみてください。以上がパッドとボールが座標上で接触している場合の処理になります。それ以外の場合、シーン内のボールの跳ね返り運動となります。
毎フレーム実行するリスナー関数
private function onEnterFrameHandler(event:Event):void {
//パッドの移動
pad.x += padVX;
if(pad.x <= padLeft) {
pad.x = padLeft;
}
if(pad.x >= padRight) {
pad.x = padRight;
}
//パッドとボールの衝突判定
hitPadFrame = pad.padframe.hitTestObject(ball);
hitPadCore = pad.padcore.hitTestObject(ball);
if(hitPadFrame) {
//padframeと衝突していたら
ball.y -= radius;
if(hitPadCore) {
//パッドの中心部に衝突していたら
ballVX *= 1;
} else {
//パッドの外縁部に衝突していたら
ballVX *= 1.2;
}
ballVY *= -1;
ball.x += ballVX;
ball.y += ballVY;
//パッドのアニメーション
pad.gotoAndPlay(2);
} else {
//padframeと衝突していなかったら
ball.x += ballVX;
ball.y += ballVY;
//シーン内のボールの跳ね返り
if(ball.x + radius > right) {
ball.x = right - radius;
ballVX *= -1;
} else if(ball.x - radius < left) {
ball.x = left + radius;
ballVX *= -1;
}
if(ball.y + radius > bottom) {
ball.y = bottom - radius;
ballVY *= -1;
} else if(ball.y - radius < top) {
ball.y = top + radius;
ballVY *= -1;
}
}
}
以上補足してみました。詳しいサンプルの解説は誌面をご覧ください。サンプルファイルはweb creatorsに付録でついているCD-ROM内に入っていますので、そちらも参考にするとよいでしょう。次回はこの続きを解説します。
投稿者 kaoru : 2008年10月30日 18:15


