« AS3 Technical Bible - vol.04
2Dアクションゲーム ブロックくずし Part.1
| DEEP KICK.com Blog | AS3 Technical Bible - vol.06
TweenMaxを使ったフォトギャラリー »

2008年11月30日

AS3 Technical Bible - vol.05
2Dアクションゲーム ブロックくずし Part.2

このエントリーをはてなブックマークに追加

w85cover.jpg web creators 2009年1月号 に掲載の連載「ActionScript 3 Technical Bible」のテーマは、「2Dアクションゲーム ブロックくずし Part.2」になります。

deepblocktennis2.jpg できあがりのサンプルはこちらをクリック。

前回に引き続き、2Dアクションゲームの原点のブロックくずし型ゲーム「DEEP BLOCK TENNIS」の作成について解説します。前回は、「パッド」と「ボール」がシーン内において跳ね返り運動を延々と行い続けるところまで作成しました。今回は、ブロックとなるオブジェクトをシーン内に配置し、ボールとブロックの衝突処理を中心に解説し、ゲームを完成させます。サンプルを作成するための詳しい解説は誌面の方を見ていただくとして、ここではブロックをシーン内に配置する仕組みと、ブロックの種類を制御する仕組みについて補足します。

ブロックをシーン内に登場させるのに必要な各プロパティを宣言します。それぞれのプロパティの意味するところは、スクリプト中のコメント文を参照。ブロックを配置する上で重要なのがX方向に並べるブロックの数を表す[xNum]と、Y方向に並べるブロックの数を表す[yNum]です。これらは後ほど入れ子構造にしたfor文で使われます。

Mainクラスに追加するブロック関連のプロパティ

//ブロック関連のプロパティ////////////
private var block:Block;
//ブロックへの参照を保持するための配列
private var blocks:Array;
//X方向に並べるブロックの数
private var xNum:uint = 7;
//Y方向に並べるブロックの数
private var yNum:uint = 9;
//最初のブロックのX座標位置
private var defX:int = 82;
//最初のブロックのY座標位置
private var defY:int = 78;
//X方向に並べるブロックの間隔
private var intervalX:int = 5;
//Y方向に並べるブロックの間隔
private var intervalY:int = 5;
//ブロックとボールの衝突判定フラグ
private var hitBlockTop:Boolean = false;
private var hitBlockBottom:Boolean = false;
private var hitBlockLeft:Boolean = false;
private var hitBlockRight:Boolean = false;

実際にブロックをシーン内に配置する処理を行う関数setBlock() の定義は、以下のようにします。

関数setBlock() の定義

//ブロック初期化関数
private function setBlock():void {
	blocks = new Array();
	for(var i:int=0; i < yNum; i++) {
		for(var j:int=0; j < xNum; j++) {
			var xPos:int = j * intervalX + defX;
			var yPos:int = i * intervalY + defY;
			block = new Block();
			//ブロックの点数を保持する
			block.score = 10;
			block.x = xPos + block.width * j;
			block.y = yPos + block.height * i;
			addChild(block);
			//ブロックへの参照を保持するための配列blocksに追加
			blocks.push(block);
		}
	}
}

ふたつのfor文が入れ子構造になっていますが、外側のfor文はY軸方向、内側のfor文はX軸方向を担当します。ここで先ほど定義したプロパティ[yNum]と[xNum]が使われており、各ブロックインスタンスの座標位置を計算し、適用しています。

次にブロックの種類を制御する仕組みについて考えてみます。今回作成しているサンプル「DEEP BLOCK TENNIS」では、3つの異なる種類のブロック、「Whiteブロック」「Greenブロック」「Orangeブロック」が登場します。それらをどのようにして区別し、配置しているのかについて見ていきます。まずは、ブロックの種類関連のプロパティからです。

ブロックの種類関連のプロパティ

//ブロックの種類関連のプロパティ////////////
//Whiteブロック・・・ノーマルブロック。得点は10
private var whiteBlockColor:uint = 0xCCCCCC;
private var whiteBlockScore:uint = 10;
//Greenブロック・・・ボールのスピードをデフォルトに戻すブロック。得点は20
private var greenBlockColor:uint = 0x66CC00;
private var greenBlockScore:uint = 20;
//Orangeブロック・・・ボールのスピードをアップするブロック。得点は30
private var orangeBlockColor:uint = 0xFF9900;
private var orangeBlockScore:uint = 30;
private var orangeBlockGainSpeedX:Number = 1.5;
private var orangeBlockGainSpeedY:Number = 1.5;
//ボールのスピードを制御するフラグ変数
private var ballMode:String = "White";
//Level1のブロックの配置を表した配列。0はWhite、1はGreen、2はOrangeブロックを表す
private var blockArray01:Array = [
	0, 0, 1, 0, 2, 0, 0,
	0, 0, 1, 0, 2, 0, 0,
	1, 1, 1, 1, 2, 2, 2,
	0, 0, 1, 0, 2, 0, 0,
	0, 0, 1, 0, 2, 0, 0,
	0, 0, 1, 0, 2, 0, 0,
	1, 1, 1, 2, 2, 2, 2,
	0, 0, 1, 0, 2, 0, 0,
	0, 0, 1, 0, 2, 0, 0,
];

ここで重要なのは、ブロックの配置を表した配列[blockArray01:Array]です。[0, 1, 2]の3つの数字が並んでいます。お察しの通り、これらの3つの数字の並び方は、ブロックの「座席位置」とでもいうべきものに対応しています。一番左上に配置されるブロックに与えられる番号は「0」、左端の上から3つめのブロックに与えられる番号は「1」といった具合です。ここでは「0 = Whiteブロック」「1 = Greenブロック」「2 = Orangeブロック」を表すものとします。長くなりますが、この配列[blockArray01:Array]に関する処理を加えた関数setBlock() の定義を見てみます。

ブロックの種類を判定する処理を追加した関数setBlock() の定義

//ブロック初期化関数
private function setBlock():void {
	//ブロック配列用ローカル変数
	var blockArray:Array;
	//ブロックのカラー置換用ローカル変数
	var transformColor:ColorTransform = new ColorTransform();
	//ブロック制御用カウンター変数
	var counter:uint = 0;
	//レベルごとに適用するブロック配列を指定する
	if(levelNum == 1) {
		blockArray = blockArray01;
	} else {
		blockArray = blockArray01;
	}
	//ブロックへの参照を保持するための配列blocks
	blocks = new Array();
	for(var i:int=0; i < yNum; i++) {
		for(var j:int=0; j < xNum; j++) {
			var xPos:int = j * intervalX + defX;
			var yPos:int = i * intervalY + defY;
			block = new Block();
			//ブロック配列からブロックの種類を判定
			if(blockArray[counter] == 0) {
				//ブロックの種類
				block.ofType = "White";
				//ブロックのカラーを適用
				transformColor.color = whiteBlockColor;
				block.transform.colorTransform = transformColor;
				//ブロックの点数を保持する
				block.score = whiteBlockScore;
			} else if(blockArray[counter] == 1) {
				//ブロックの種類
				block.ofType = "Green";
				//ブロックのカラーを適用
				transformColor.color = greenBlockColor;
				block.transform.colorTransform = transformColor;
				//ブロックの点数を保持する
				block.score = greenBlockScore;
			} else if(blockArray[counter] == 2) {
				//ブロックの種類
				block.ofType = "Orange";
				//ブロックのカラーを適用
				transformColor.color = orangeBlockColor;
				block.transform.colorTransform = transformColor;
				//ブロックの点数を保持する
				block.score = orangeBlockScore;
			}
			block.x = xPos + block.width * j;
			block.y = yPos + block.height * i;
			addChild(block);
			//ブロックへの参照を保持するための配列blocksに追加
			blocks.push(block);
			//trace(blockArray[counter]);
			counter++;
		}
	}
}

ブロック制御用カウンター変数[counter]を使って、配列[blockArray01:Array]の要素にどの数字が入っているのかをif文で判定し、ブロックの種類ごとにカラーを適用したり、点数の情報を代入したりしているわけです。

以上補足してみました。より詳しいサンプルの解説は誌面をご覧ください。サンプルファイルをダウンロードするためのパスワードは、誌面に掲載されています。

投稿者 kaoru : 2008年11月30日 11:02

このエントリーをはてなブックマークに追加

contents
about
contact
Photo Gallery
blog
iPhone/iPad アプリ
Kindle book
portfolio