こんにちは、ソニックムーブのみかちです。すっかり夏になりましたね!今年は暑い期間が長くなる予報で暑さに弱い私は涙目です。そんな中、Herlockの開発も佳境です!あともう少しで皆様にもお届けできるかと思いますので、よろしくお願いします!
今回から、サンプルアプリでリリースしている「ねこ穴」のゲーム実装について、下記の内容で2回に分けてご説明させていただきます!「ねこ穴は」穴から飛び出てくる"ねこ"たちをタップ&フリックではじき飛ばして点数を獲得するゲームです。実際ゲームをプレイして頂ければ内容がより掴みやすくなると思いますので、是非遊んでみてください!
ねこ穴ダウンロードはコチラ⇒Google Play・App Store
細かい部分は割愛させていただきますので、詳細はコチラを参考にしてください。
今回は、穴からランダムでねこが飛び出る部分の実装についてご説明させていただきます。
大まかな流れは下記となっています。
それでは順に説明をしていきます。
ここでは下図の背景およびねこ素材画像を読み込みます。
素材は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)が表示されます。
次に表示するねこをランダムに決定します。
ねこの種類の決定は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で表示してみました。
ここでもやはり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:速度)
上記で生成処理自体はおわりましたので、次にねこの生成と配置を行います。10フレームに一回ねこを生成するようにしますが、あまり一定間隔でもおもしろくないので、少し偏りをつけました。
//カウンター
var updateCount = 0;
function updateHandler() {
//カウンターが10で割り切れるフレームのときに==10フレームに一回処理される
if ( updateCount % 10 === 0 ) {
//偏りを作る
if ( Math.random() < 0.6 ) {
//ねこを生成して配置する
stage.addChild( createCat() );
}
}
}
次にアニメーションを付けます。前回触れた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;
}
}
こちらで最後となります。まず条件を下記のように設定します。
上記の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;
}
すべてのコードの実行結果が下図となります。
今回は「ねこ穴」を使って実用的なアニメーションの実装についてお話しさせていただきました。次回も引き続き「ねこ穴」を使用して得点の処理についてご説明させていただきます。
「ねこ穴」は各ストアでダウンロードが可能ですので、ぜひダウンロードしてパフォーマンスも実感してもらえると嬉しいです!
ねこ穴ダウンロードはコチラ⇒Google Play・App Store
梅雨が明けたと思ったら35度を超す猛暑が続く中、、Herlockの開発もまけじと熱い!そんな「Herlock」、クローズドベータ版の利用事前登録も引き続きよろしくお願いします!無料でご利用が可能ですので、少しでも興味を持たれた方はぜひご登録いただき「Herlock」をお試しいただけると幸いです!
また、FacebookやTwitterでも開発状況や新しい情報を配信しておりますのでこちらもチェックしてみてください!
FB:https://www.facebook.com/herlock.do
Twitter:@herlock_do