シーンでブロック崩しゲームを行う


 

前回でシーンの行き来を覚えました。

前回は、ただタイトルと、実際は何もないゲーム画面を行ったりきたりしただけでしたが、今回は「Game.js」をゲームブロック崩しに仕上げてみます。

完成ページを見てみましょう。
※PCの場合グーグルクロームかSafari、スマートフォンの場合アンドロイド、iPhoneでごらんください

サンプル9;

 

 

 

完成サンプルはこちら

jaction_sample9

jActionで作られてるので、もちろんそのままスマートフォンで動きます。

前回までと同じで

「index.html」「jAction.js」「Main.js」「Start.js」「Game.js」があります。

「Image」フォルダの中は

Bg.jpg -- ゲーム用の背景画像
titleBg.jpg - タイトル画面用背景画像
touchStart.png - タイトル画面に表示される「タッチスタート」の文字素材
block.jpg - ブロック崩しゲーム用のブロック

が入ってます。

「Main.js」「Start.js」の中身は前回のチュートリアルと全く同じものです。

今回重要なのは「Game.js」になります。では「Game.js」を見てましょう。

Game = function()
{
	EventDispatcher.initialize(this);

	var boxObject = new ja.BoxClass(20,20,"#0000ff");
	boxObject.x = 150;
	boxObject.y = 200;

	var barObj = new ja.BoxClass(100 ,15 ,"#00ffff"); //自分の指で動かすバー
	barObj.x = 110;
	barObj.y = 400;

	var actionFlg = false;
	var xinc = 5;
	var yinc = 5;

	ja.imageUnitObj.addEventListener("onLoad", this);
	ja.imageUnitObj.load(["Image/Bg.jpg",  "Image/block.jpg"]);

	var block_array = new Array(); //ブロックを格納する配列を作る

	var textObj = new ja.TextClass();
	textObj.color = "#FFFFFF";
	textObj.x = 0;
	textObj.y = 100;

	var startTextObj = new ja.TextClass();
	startTextObj.px = "30px";
	startTextObj.color = "#FFFFFF";
	startTextObj.x = 50;
	startTextObj.y = 200;
	startTextObj.text = "タッチでスタート";

	var blockContainer = new ja.Container();

	this.onLoad = function()
	{
		window.scrollTo(0, 1); //アドレスバーを消す

		ja.imageUnitObj.removeEventListener("onLoad", this);

		ja.stage.addChild(ja.imageUnitObj["Bg"]);
		ja.stage.addChild(blockContainer);
		ja.stage.addChild(boxObject);
		ja.stage.addChild(barObj);
		ja.stage.addChild(startTextObj);
		ja.stage.addChild(textObj);

		var x = 10;
		for(var i = 0 ; i < 5 ; i++)
		{
			var y = 0;
			for(var j = 0 ; j < 3 ; j++)
			{
				var block = new ja.ImageClass(ja.imageUnitObj["block"]);
				block.x = x;
				block.y = y;
				blockContainer.addChild(block);
				y += block.h + 10;
			}
			x += block.w + 10;
		}

		textObj.text = "残りのブロックは15個";

		ja.imageUnitObj["Bg"].addEventListener("touchUp", this);
		ja.imageUnitObj["Bg"].addEventListener("touchMove", this);
	};

	this.touchMove = function(e)
	{
		barObj.x = e.touch_x - 50;
	};

	this.touchUp = function()
	{
		ja.imageUnitObj["Bg"].removeEventListener("touchUp", this);
		startTextObj.visible = false;

		if(actionFlg)
		{
			actionFlg = false;
			this.dispatchEvent({type:"onGameEnd", target:this});
		}
		else
		{
			actionFlg = true;
			boxObject.addEventListener("onEnterFrame" , this);
		}
	};

	this.onEnterFrame = function()
	{
		boxObject.x += xinc;
		boxObject.y += yinc;

		for(var i = 0 ; i < blockContainer.numChildren() ; i++)
		{
			var blockObj = blockContainer.getChildAt(i);
			if(ja.hitObj.intersect(boxObject,blockObj))
			{
				blockContainer.removeChildAt(i);
				yinc = -yinc;
				textObj.text = "残り" + blockContainer.numChildren() + "個";
				break;
			}
		}

		if(ja.hitObj.intersect(boxObject , barObj))
		{
			yinc = -yinc;
			boxObject.y = barObj.y - boxObject.h - 1;
		}

		if(boxObject.x >= 300)
		{
			boxObject.x = 300;
			xinc = -xinc;
		}
		else if(boxObject.x <= 0)
		{
			boxObject.x = 0;
			xinc = -xinc;
		}

		if(boxObject.y <= 0)
		{
			boxObject.y = 0;
			yinc = -yinc;
		}
		else if(boxObject.y > 480)
		{
			startTextObj.x = 20;
			startTextObj.text = "タッチでタイトル画面へ"
			startTextObj.visible = true;
			boxObject.removeEventListener("onEnterFrame" , this);
			ja.imageUnitObj["Bg"].addEventListener("touchUp", this);
		}
	};

	this.destroy = function()
	{
		for(var i = ja.stage.numChildren() - 1 ; i >= 0 ; i--)
		{
			ja.stage.removeChildAt(i);
		}

		ja.imageUnitObj.destroy();
		EventDispatcher.destroy(this);
	};
};

「Game.js」は「チュートリアル2」の「ブロックの数を表示する(文字を表示する)」が元になっています。

どこが「チュートリアル2」の「ブロックの数を表示する(文字を表示する)」と比べて変わったか見てみましょう。

 

EventDispatcher.initialize(this);

前回のチュートリアルの通り、イベントを発生させるオブジェクトは、まずこの宣言をしなければなりません。

「Game.js」が、イベントを発行するのに必要な処理です。

自分の指で動かすバーも必要です。

var barObj = new ja.BoxClass(100 ,15 ,"#00ffff"); //自分の指で動かすバー

今回はボールと同じで「ja.BoxClass」を使って生成しました。

 

ja.imageUnitObj["Bg"].addEventListener("touchMove", this);

画面全体なので、画面全体に貼られているBG画面に、「”touchMove”」リスナーを貼ります。

touchMoveは、指が画面上で動くと反応します。

touchMoveメソッドは以下のように定義しました。
this.touchMove = function(e)
{
	barObj.x = e.touch_x - 50;
}

eという引数が指定されていますが、eは画面上の指の動きのイベントオブジェクトが格納されています。

「e.touch_x」で画面上のX座標です。今回使いませんが「e.touch_y」でY座標も拾えます。

バーは左上が原点で幅100ピクセルのバーです。

指の位置を真ん中にしたいので、半分の長さの50ピクセル分を引いていきます。

 

this.onEnterFrameメソッドに、ブロックの跳ね返りだけでなく

if(ja.hitObj.intersect(boxObject , barObj))
{
	yinc = -yinc;
	boxObject.y = barObj.y - boxObject.h - 1;
}
動かすバーの当たり判定と跳ね返り処理をいれます。
玉とバーが接触してyincの+-が逆転してますが、次の瞬間触れてると戻って誤動作してしまいますので、
念の為に
boxObject.y = barObj.y - boxObject.h - 1;
として、バーの上に持ってきています。バーのY座標からボールの縦幅分-1ピクセル分上に持ってきてるのです。

ボールがバーの位置を飛び越えて、画面外に出たらゲームオーバーです。
if(boxObject.y > 480)
{
	startTextObj.x = 20;
	startTextObj.text = "タッチでタイトル画面へ"
	startTextObj.visible = true;
	boxObject.removeEventListener("onEnterFrame" , this);
	ja.imageUnitObj["Bg"].addEventListener("touchUp", this);
}

でゲームオーバーの処理をしています。

 

ゲームオーバー時は、イベント


this.dispatchEvent({type:"onGameEnd", target:this});

を発行して「Main.js」に終了を伝え「Main.js」からメモリなどを綺麗にする為の最終処理「destroy」メソッドを呼ぶようにしています。


 

this.destroy = function()
{
	for(var i = ja.stage.numChildren() - 1 ; i >= 0 ; i--)
	{
		ja.stage.removeChildAt(i);
	}

	ja.imageUnitObj.destroy();
	EventDispatcher.destroy(this);
};

ここで注意点がひとつあります。

ja.imageUnitObj.destroy();
を実行剃る前に、ja.stageに張り付いている画面オブジェクトをremoveChildしなければなりません。
複数子供の画像オブジェクトがはりついている場合は、一つづつ指定するのは面倒です。
そこで今回は、numChildren()を使って画面からremoveChildしています。
for(var i = ja.stage.numChildren() - 1 ; i >= 0 ; i--)
{
	ja.stage.removeChildAt(i);
}

ここで気を付けないといけないのは、0番目の画像オブジェクトがremoveChildされた瞬間に1番目の画像オブジェクトが

0番目に変化することです。常に0番目からスタートするので、0番目がなくなった瞬間に一つづつ繰り上がるのです。

ここを気をつけてremoveChildしないとエラーを引き起こすことになります。

例では、安全に最後の方からremnoveChildをかけています。

 

for(var i =  0 ; i < ja.stage.numChildren() ; i++)
{
	ja.stage.removeChildAt(0);
}

というやり方もあります。存在する数だけ0番めの画像オブジェクトをremoveChildするのです。

 

後は、いままでのチュートリアルの応用です。

今回簡単なブロック崩しゲームを作ってみましたが、バーのどの位置で当たったかを判定して跳ね返る位置を変えたり

時間経過と共にボールのスピードを早めるなどすると、ゲームとしての面白さは、ぐっとあがってきます。

是非、挑戦してみてください。

 

次回はチュートリアル5「音の再生」に移ります。

実は音に関しては、iOSでは同時再生1音のみ、アンドロイドではOS2.2 などでは音はなりません。

jActionでは、アンドロイドではFlashの音声モジュールを併用して音を再生します。