Herlockで始めるアプリの実装(2) [Edit]

こんにちは、ソニックムーブのみかちです。すっかり夏になりましたね!今年は暑い期間が長くなる予報で暑さに弱い私は涙目です。そんな中、Herlockの開発も佳境です!あともう少しで皆様にもお届けできるかと思いますので、よろしくお願いします!

今回から、サンプルアプリでリリースしている「ねこ穴」のゲーム実装について、下記の内容で2回に分けてご説明させていただきます!「ねこ穴は」穴から飛び出てくる"ねこ"たちをタップ&フリックではじき飛ばして点数を獲得するゲームです。実際ゲームをプレイして頂ければ内容がより掴みやすくなると思いますので、是非遊んでみてください!
ねこ穴ダウンロードはコチラ⇒Google PlayApp Store

  1. ランダムでねこが飛び出る
  2. ねこをフリックすると得点が加算される

細かい部分は割愛させていただきますので、詳細はコチラを参考にしてください。
今回は、穴からランダムでねこが飛び出る部分の実装についてご説明させていただきます。

【ランダムでねこが飛び出る部分の処理の流れ】

大まかな流れは下記となっています。

  1. 素材の読み込み
  2. ねこの種類をランダムで決める
  3. 飛び出す位置と速度等をランダムで決める
  4. ねこを生成して配置
  5. enterFrameでアニメーションさせる
  6. 特定位置まで行くと方向を変化させ出てきた穴に落ちる

それでは順に説明をしていきます。

1.素材の読み込み

ここでは下図の背景およびねこ素材画像を読み込みます。

Herlock

素材はBulkLoaderで読み込みます。
下記の様なコードでmaterialsに設定された素材が読み込まれすべて完了するとonloadハンドラが呼ばれます。
onloadハンドラに設定したstartHandlerには、一旦背景の表示処理を記載しています。
※ここではBulkLoaderの詳細な説明は省きますが、素材の読み込みを一括で管理出来るオブジェクトです。loader.get( "bg" )等でImageオブジェクトのインスタンスが取得出来ます。

// Stageを初期化します
var stage = new Stage( 640, 960 );
var layer = new Layer( stage );
//今回ははみ出す事前提でscaleModeをnoBorderにします
layer.scaleMode = "noBorder";
window.addLayer( layer );
	
var materials = {
    "bg": {
        type: "image",
        url: "background.png"
    },
    "cat1": {
        type: "image",
        url: "cat1.png"
    },
    "cat2": {
        type: "image",
        url: "cat2.png"
    },
    "cat3": {
        type: "image",
        url: "cat3.png"
    }
};

var loader = new BulkLoader( materials );
loader.onload = startHandler;

function startHandler() {
	//背景を設置します
	stage.addChild( new Bitmap( new BitmapData( loader.get( "bg" ) ) ) );
}

[実行結果]
背景画像(background.png)が表示されます。

Herlock

2.ねこの種類をランダムで決める

次に表示するねこをランダムに決定します。
ねこの種類の決定はJSでもASでもおなじみのMath.randomを使用します。3種類を均等に割り振りたいので0-2の整数をランダムで取得し、ねこの種類を決めます。

//BtimapDataを使い回したいので素材として定義して保持しておきます。
var CatType = {
	Cat1: new BitmapData( loader.get( "cat1" ) ),
	Cat2: new BitmapData( loader.get( "cat2" ) ),
	Cat3: new BitmapData( loader.get( "cat3" ) )
};

function getCatType() {
	//0-2の整数をランダムで取得します
	var num = Math.floor( Math.random() * 3 );
	//CatTypeに設定した"Cat1","Cat2","Cat3"が取得したいので下記のようにします
	return "Cat" + String(num + 1);
}

function createCat() {
	//ねこのBitmapを生成
	var cat = new Bitmap( CatType[getCatType()] );
	return cat;
}

[実行結果]
ランダムで取得したデータをわかりやすくalertで表示してみました。

Herlock

3.飛び出す位置と速度等をランダムで決める

ここでもやはりMath.randomを使います。ここは単純に数値なので、Math.randomからそのまま計算で決めることが出来ます。
先ほどのコードのcreateCatに追記していきます

function createCat() {
	var cat = new Bitmap( CatType[getCatType()] );
	
	//中心位置からの差分をMath.randomで決めx座標に代入
	cat.x = stage.stageWidth / 2 + ( Math.random() - 0.5 ) * 500;
	//y座標はひとまず固定にします
	cat.y = 800;
	//速度は20〜40の範囲でランダムとします
	cat.speed = 20 + Math.random() * 20;
	
	return cat;
}

[実行結果]
ランダムで取得したデータをalertで表示してみました。
(catNo:ねこの種類、x:x座標、y:y座標、speed:速度)

Herlock

4.ねこを生成して配置

上記で生成処理自体はおわりましたので、次にねこの生成と配置を行います。10フレームに一回ねこを生成するようにしますが、あまり一定間隔でもおもしろくないので、少し偏りをつけました。

//カウンター
var updateCount = 0;

function updateHandler() {
	//カウンターが10で割り切れるフレームのときに==10フレームに一回処理される
	if ( updateCount % 10 === 0 ) {
		//偏りを作る
		if ( Math.random() < 0.6 ) {
			//ねこを生成して配置する
			stage.addChild( createCat() );
		}
	}
}

5.enterFrameでアニメーションさせる

次にアニメーションを付けます。前回触れたenterFrameでアニメーションさせますが、効率よく管理するためにアニメーションさせるためのBitmapを配列に入れ、その中の要素のy座標にspeed分減算することで動かすことにします。
上記の4のコードにアニメーションのコントロールを追記します。

var updateCount = 0;
//ねこ管理配列
var cats = [];

function updateHandler() {
	if ( updateCount % 10 === 0 ) {
		if ( Math.random() < 0.6 ) {
			var cat = createCat();
			cats.push( cat );
			stage.addChild( cat );
		}
	}
	
	//catsを処理する
	for ( var i = 0; i < cats.length; i++ ) {
		cats[i].y -= cats[i].speed;
	}
}

6.特定位置まで行くと方向を変化して落ちる

こちらで最後となります。まず条件を下記のように設定します。

  • y座標が100以下になると落下する
  • y座標が1100を超えるとアニメーション対象を外れる
    ※画面外に出たという判定とする

上記の5のコードに追記していきます。

var updateCount = 0;
var cats = [];
//事後処理管理配列
var removes = [];

function updateHandler() {
	if ( updateCount % 10 === 0 ) {
		if ( Math.random() < 0.6 ) {
			var cat = createCat();
			cats.push( cat );
			stage.addChild( cat );
		}
	}
	
	for ( var i = 0; i < cats.length; i++ ) {
		cats[i].y -= cats[i].speed;
		
		//位置判定
		if(cats[i].y < 100 ) {
			cats[i].speed *= -1;
		}
		else if(cats[i].y > 1100 ) {
			//管理配列から削除
			//loop中にindexのサイズを変えたくないので事後処理管理の配列に入れる
			removes.push( cats[i] );
		}
	}
	
	//事後処理(管理配列から削除)
	if( removes.length > 0 ) {
		
		for ( var j = 0; j < removes.length; j++ ) {
			
			var removeIndex = cats.indexOf(removes[j]);
			
			if(removeIndex >= 0) {
				//ステージから削除
				stage.removeChild( removes[j] );
				//管理配列から削除
				cats.splice( removeIndex, 1 );
			}
		}
		
		removes = [];
	}
	
}

以上でランダムでねこが飛び出る部分の処理の実装は完了です。
最後に、ここまでのコードをつなげてみます。

/***********************************
  初期化及び設定値の定義
***********************************/

// Stageを初期化します
var stage = new Stage( 640, 960 );
var layer = new Layer( stage );

//今回ははみ出す事前提でscaleModeをnoBorderにします
layer.scaleMode = "noBorder";
window.addLayer( layer );

//素材定義
var materials = {
    "bg": {
        type: "image",
        url: "background.png"
    },
    "cat1": {
        type: "image",
        url: "cat1.png"
    },
    "cat2": {
        type: "image",
        url: "cat2.png"
    },
    "cat3": {
        type: "image",
        url: "cat3.png"
    }
};


var CatType = {
	Cat1: null,
	Cat2: null,
	Cat3: null
};

/***********************************
  読み込みと初期配置
***********************************/
var loader = new BulkLoader( materials );
loader.onload = startHandler;


function startHandler() {

	//背景を設置します
	stage.addChild( new Bitmap( new BitmapData( loader.get( "bg" ) ) ) );

	//CatTypeにBitmapDataを設定します
	CatType.Cat1 = new BitmapData( loader.get( "cat1" ) );
	CatType.Cat2 = new BitmapData( loader.get( "cat2" ) );
	CatType.Cat3 = new BitmapData( loader.get( "cat3" ) );

	//enterFrame
	stage.addEventListener("enterFrame",updateHandler);

}

/***********************************
  更新及びアニメーション処理
***********************************/
var updateCount = 0;
var cats = [];
var removes = [];

function updateHandler() {

	//カウンターが10で割り切れるフレームのときに==10フレームに一回処理される
	if ( updateCount % 10 === 0 ) {
		//偏りを作る
		if ( Math.random() < 0.6 ) {
			//ネコを生成して配置する
			var cat = createCat();
			cats.push( cat );
			stage.addChild( cat );
		}
	}

	//catsを処理する
    	for ( var i = 0; i < cats.length; i++ ) {
        	cats[i].y -= cats[i].speed;
	
		//位置判定
		if(cats[i].y < 100 ) {
			cats[i].speed *= -1;
		}
		else if(cats[i].y > 1100 ) {
			//管理配列から削除
			//loop中にindexのサイズを変えたくないので事後処理要の配列に入れる
			removes.push( cats[i] );
		}
    	}

	//事後処理要(管理配列から削除)
	if( removes.length > 0 ) {
	
		for ( var j = 0; j < removes.length; j++ ) {
		
			var removeIndex = cats.indexOf(removes[j]);
		
			if(removeIndex >= 0) {
				//ステージから削除
				stage.removeChild( removes[j] );
				//管理配列から削除
				cats.splice( removeIndex, 1 );
			}
		}
	
		removes = [];
	}

}

/***********************************
  ネコ生成関連の関数
***********************************/
function getCatType() {
	//0-2の整数をランダムで取得します
	var num = Math.floor( Math.random() * 3 );
	//CatTypeに設定した"Cat1"~"Cat3"が取得したいので下記のようにします
	return "Cat" + String(num + 1);
}

function createCat() {

	var cat = new Bitmap( CatType[getCatType()] );

	//中心位置からの差分をMath.randomで決めx座標に代入
	cat.x = stage.stageWidth / 2 + ( Math.random() - 0.5 ) * 500;

	//y座標はひとまず固定にします
	cat.y = 800;

	//速度は20〜40の範囲でランダムとします
	cat.speed = 20 + Math.random() * 20;

	return cat;
}

すべてのコードの実行結果が下図となります。

Herlock

今回は「ねこ穴」を使って実用的なアニメーションの実装についてお話しさせていただきました。次回も引き続き「ねこ穴」を使用して得点の処理についてご説明させていただきます。
「ねこ穴」は各ストアでダウンロードが可能ですので、ぜひダウンロードしてパフォーマンスも実感してもらえると嬉しいです!
ねこ穴ダウンロードはコチラ⇒Google PlayApp Store


梅雨が明けたと思ったら35度を超す猛暑が続く中、、Herlockの開発もまけじと熱い!そんな「Herlock」、クローズドベータ版の利用事前登録も引き続きよろしくお願いします!無料でご利用が可能ですので、少しでも興味を持たれた方はぜひご登録いただき「Herlock」をお試しいただけると幸いです!

また、FacebookやTwitterでも開発状況や新しい情報を配信しておりますのでこちらもチェックしてみてください!
FB:https://www.facebook.com/herlock.do
Twitter:@herlock_do

コメント

この記事にコメントを書く

記事に対するテクニカルな質問はご遠慮ください(利用規約)。

その他の記事