出来上がったゲームを遊んでみて気づくのが、当たり判定の理不尽さです。これは、スプライトの透明部分も当たり判定として扱われてしまっているため、スプライトの見かけ上の大きさよりも、ずっと大きい範囲が当たり判定に使われていることが原因です。
この問題を解消する方法としては、キャラクターの画像の透明部分を極限まで切り詰めたり、当たり判定の処理を自力で実装するなどの方法がありますが、今回はとてもお手軽な方法で問題を解決します。
このように、画像を指定しない透明な小さいスプライトを用意して、くまの中心に配置します。そして、くまの当たり判定をこのスプライトが代わりに行えば当たり判定が小さくなります。常にスプライトがくまと同じ位置にあるように設定する必要がありますが、この方法を使うと、見かけとは異なる当たり判定を手軽に実装できます。
var createGameScene = function() {
…省略…
// くまの設定
var kuma = new Sprite(32, 32); // スプライトを作る
kuma.image = game_.assets['./img/chara1.png']; // 画像を設定
kuma.x = 80; // 横位置調整 画面左側に配置
kuma.y = GROUND_LINE - kuma.height; // 縦位置調整 くまの下端を地面の高さに合わせる
scene.addChild(kuma); // シーンに追加
// くまの当たり判定用スプライトの設定
var kuma_hit = new Sprite(1, 1); // スプライトを作る(幅1, 高さ1)
// kuma_hit.image = // 画像は設定しない(透明)
kuma_hit.x = kuma.x + kuma.width / 2; // 横位置調整 くまの左右中央に配置
kuma_hit.y = kuma.y + kuma.height / 2; // 縦位置調整くまの上下中央に配置
scene.addChild(kuma_hit); // シーンに追加
…省略…
// 毎フレームイベントをシーンに追加
scene.addEventListener(Event.ENTER_FRAME, function(){
…省略…
// 当たり判定用スプライトをくまの上下中心に置く
kuma_hit.x = kuma.x + kuma.width/2;
kuma_hit.y = kuma.y + kuma.height/2;
…省略…
// 障害物のスクロールとくまとの接触の設定
if (hurdle.x > -hurdle.width) { // ハードルが出現している(画面内にある)とき
hurdle.x -= SCROLL_SPEED; // ハードルをスクロール
if (hurdle.intersect(kuma_hit)) { // ハードルとくまがぶつかったとき
kumaDead(); // くまがやられた関数を実行
}
}
if (igaguri.x > -igaguri.width) { // いがぐりが出現している(画面内にある)とき
igaguri.x -= SCROLL_SPEED; // いがぐりをスクロール
if (igaguri.intersect(kuma_hit)) {// いがぐりとくまがぶつかったとき
kumaDead(); // くまがやられた関数を実行
}
}
if (bird.x > -bird.width) { // 鳥が出現している(画面内にある)とき
bird.x -= SCROLL_SPEED * 1.2; // 鳥を1.2倍速でスクロール
if (bird.frame > 0) { // 鳥のフレーム番号を0, 1, 0, 1と切り替えて羽ばたかせる
bird.frame = 0;
} else {
bird.frame = 1;
}
if (bird.intersect(kuma_hit) { // 鳥とくまがぶつかったとき
kumaDead(); // くまがやられた関数を実行
}
}
…省略…
)};
…
これで、当たり判定が小さくなりました。
最後に、ゲームオーバー画面が味気ないので、ゲームの結果を表示します。createGameoverSceneの引数にスコアを追加して、スコアが大きく表示されるようにします。
var createGameScene = function() {
…省略…
// くまがやられた関数
var kumaDead = function() {
alert("ヤラレチャッタ"); // ポップアップメッセージを出す
kuma.frame = 3; // くまを涙目にする
game_.pushScene(createGameoverScene(scroll)); // ゲームオーバーシーンをゲームシーンに重ねる(push)
}
…省略…
var createGameoverScene = function(scroll) {
var scene = new Scene(); // 新しいシーンを作る
scene.backgroundColor = 'rgba(0, 0, 0, 0.5)'; // シーンの背景色を設定
// ゲームオーバー画像を設定
var gameoverImage = new Sprite(189, 97); // スプライトを作る
gameoverImage.image = game_.assets['./img/gameover.png']; // 画像を設定
gameoverImage.x = 66; // 横位置調整
gameoverImage.y = 170; // 縦位置調整
scene.addChild(gameoverImage); // シーンに追加
…省略…
// スコア表示用ラベルの設定
var scoreLabel = new Label(scroll.toString()); // ラベルを作る
scoreLabel.width = 320; // 幅を設定
scoreLabel.textAlign = 'center'; // 文字を中央寄せ
scoreLabel.color = '#ffffff'; // 文字を白色に
scoreLabel.x = 0; // 横位置調整
scoreLabel.y = 12; // 縦位置調整
scoreLabel.font = '96px sans-serif'; // 28pxのゴシック体にする
scene.addChild(scoreLabel); // シーンに追加
// スコア説明ラベル設定
var scoreInfoLabel = new Label('?走り抜いた'); // ラベルを作る
scoreInfoLabel.width = 320; // 幅を設定
scoreInfoLabel.textAlign = 'center'; // 文字を中央寄せ
scoreInfoLabel.color = '#ffffff'; // 文字を白色に
scoreInfoLabel.x = 0; // 横位置調整
scoreInfoLabel.y = 130; // 縦位置調整
scoreInfoLabel.font = '32px sans-serif'; // 28pxのゴシック体にする
scene.addChild(scoreInfoLabel); // シーンに追加
…省略…
以上で完成です。お疲れさまでした!!
これまで5回に渡ってenchant.jsによるスマートフォン向けゲーム作りを紹介しましたが、いかがでしたでしょうか。
初めてプログラムを書く人にとっては難しかった部分があるかもしれませんが、enchant.jsはゲーム向けのライブラリであること、さらに、学習用として開発されていることだけあって、初めてのスマートフォン向けゲーム作りには最適な手段の1つであると思います。この記事があなたのゲーム作りのヒントになれば幸いです。
大関隆介
2006年に株式会社アローズ・システムズに入社し飲食店検索サイトの要件定義〜運用までを行いPHPやperlなどを利用したサーバサイドの開発からJavaScript(Ajax、jQuery)を使ったクライアントサイドの開発も行う。モバイルに特化した業務がしたいと考えるようになり、2010年10月に株式会社ゆめみに入社し、現在はシステムエンジニアとしてスマートフォンサイトやスマホアプリの提案・設計・開発に従事。最近では、大規模なアプリの開発・運用チームの中心メンバーとして活躍。
佐藤浩昭
2011年に株式会社ゆめみに入社。学生時代はPC向けのFlashコンテンツを制作していた。入社後はフィーチャーフォン向けのPHP+Flash Lite 1.1のWebアプリの制作やenchant.jsを用いたサントリーのゲーム開発に従事し、現在は大手メーカーのAndroidアプリのメイン開発に携わる。Webコンテンツからネイティブアプリまで幅広い知識を持つ
Copyright © ITmedia, Inc. All Rights Reserved.