こんにちは。
ECF Techブログ
担当 Michiharu.Tです。
前回に引き続き、JavaScriptの2Dゲームフレームワーク Phaserを使ったプログラムをご紹介したいと思います。
今回は物理エンジンを活用して、2Dアクションの土台となるプログラムに挑戦します。よろしくお願いします。
本記事は前回記事の続編として用意しているものです。前回からご覧になりたい方は下のリンクからお願いします。

対象読者
- プログラミングの経験がある方
- JavaScriptの基本的なプログラムが読める方
つくるもの

アクションゲームの土台となるプログラムを作成します。
(できること)
- プレイヤー(魔法使い)は、左右移動とジャンプができます。
- 地面は乗ることができます。
使用する画像
魔法使い

こちらの画像は、ぴぽや倉庫さんで提供されている画像です。他にも2Dゲーム用の画像が豊富にあります。興味のある方は下のリンクからどうぞ。

残り2つの画像はオリジナルです。ご自由にご利用ください。
空
地面
プログラム
では早速、プログラムを見ていきましょう。まずは、今回動作させるプログラムの全文を掲載します。コピーしてhtmlファイルを作成し、ブラウザで実行してみましょう。
物理エンジンの設定
物体の落下や弾力など、物理的な複雑な計算をしてくれるAPI群は物理エンジンなどと呼ばれています。キャラクターの移動や落下、ジャンプなどに用いることができます。次の部分がその基本設定です。
physics: {
default: 'arcade',
arcade: {
gravity: { y: 200 },
debug: false
}
}
オブジェクトになっています。各プロパティを確認しましょう。
- default: どの物理エンジンを使用するかを設定します。Phaserでは「arcade」が標準となっています。
- arcade: 物理エンジンの設定項目です。
- gravity: 重力がどの方向に働くかを示します。
y:200は、下方向に重力が働くことを示します。 - debug: デバッグモードのON/OFFを設定します。
- gravity: 重力がどの方向に働くかを示します。
デバッグモードは、下の画面のようにスプライトのあたり判定領域や速度状態を示してくれるものになります。

地面の作成
プレイヤーが乗る地面を作成します。まずは画像をロードします。
//地面の画像
this.load.image('ground','assets/ground.png');
ゲーム画面上に地面を準備していきます。
//地面の作成 grounds = this.physics.add.staticGroup();
this.physics.add.staticGroup関数は、動かないオブジェクトを入れておく入れ物を用意します。
動かないとは、他のオブジェクトがぶつかったりしてもその影響で動いたりしない。という事です。
その入れ物に4つの地面を入れていきます。
grounds.create(100,550,'ground'); grounds.create(300,550,'ground'); grounds.create(500,550,'ground'); grounds.create(700,550,'ground');
groundsのもつcreate関数を使って、画面上の位置と使用する画像の名前を指定しています。
魔法使いの作成
物理エンジンに基づく挙動が可能なスプライトを作成します。
//プレイヤースプライトの作成 player = this.physics.add.sprite(400,300,'witch');
前回、通常のスプライトを作成した時と違い、physicsがついた関数を使っています。
また、物理挙動に必要な情報の設定を行ないます。
player.setBounce(0.2); player.setCollideWorldBounds(true);
setBounceは弾み具合を表します。実行すると魔法使いが地面にぶつかったとき、少しだけバウンドするのがわかります。
setCollideWorldBoundsは、画面の端にぶつかるかどうかを設定します。これがないと移動したときに画面から消えてしまう場合があります。
アニメーションの設定
次はアニメーションの設定です。アニメーションに用いる画像とフレームの番号割当の画像を再掲します。

今回は左右に歩くアニメーションを用意しておきます。
this.anims.create({
key: 'left',
frames: this.anims.generateFrameNumbers('witch', { start: 3, end: 5}),
frameRate: 5,
repeat: -1
});
this.anims.create({
key: 'right',
frames: this.anims.generateFrameNumbers('witch', { start: 6, end: 8 }),
frameRate: 5,
repeat: -1
});
魔法使いは登場すると同時に、左向きのアニメーションを開始します。
//プレイヤーアニメーションの開始
player.anims.play('left',false);
キーボードで魔法使いを動かす
Phaserはキーボード操作の設定も簡単に行うことができます。
まずはキーボード操作を管理するオブジェクトを準備します。
//キーボードイベント取得オブジェクト cursors = this.input.keyboard.createCursorKeys();
createCursorKeysはキーボードの矢印キーを使えるようにする関数です。
キー操作に連動して、プレイヤーを動かすためにupdate関数内に次のプログラムを追記しています。
function update(){
//左キーが押された時
if (cursors.left.isDown)
{
player.setVelocityX(-100);
player.anims.play('left', true);
}
//右キーが押された時
else if (cursors.right.isDown)
{
player.setVelocityX(100);
player.anims.play('right', true);
}
//キーが押されていない時
else
{
player.setVelocityX(0);
}
//上キーが押されたらジャンプ(接地しているときのみ)
if (cursors.up.isDown && player.body.touching.down)
{
player.setVelocityY(-330);
}
}
update関数は一般的にゲームループと呼ばれる処理部分です。1秒に決まった回数分実行されます。1秒あたりの実行回数はFPS(Frames Per Second)と言います。
この中にキーボードのキーが押されている状態を判断するif文が入っています。たとえば、if(cursors.left.isDown)は「左キーが押されていたら」となります。
setVelocityXは速度を設定する関数です。1秒間に進むピクセル数を設定します。
キーが押されていない時の処理も必ず入れます。これがないと、左右キーを離したときに魔法使いが停止しません。
ジャンプの条件は、cursors.up.isDown && player.body.touching.downとなっています。上キーが押された時かつ接地しているときの2つの条件となっています。
押された瞬間、上方向(setVelocityY(-330))の力が発生しますがやがて重力に負け、地面に戻ることとなります。
これで基本形ができました。地面を増やしたり、位置を変えたりしてアクションらしい画面を作りましょう。

おわりに
今回は以上とさせていただきます。最後までありがとうございました。Phaserの物理エンジンは細やかな設定ができ、とても便利です。私も勉強しながら引き続き、情報提供をしていきたいと思います。よろしくお願いします。
合同会社イー・シー・エフでは、子ども向けプログラミングなどの教育講座を実施しています。プログラミング教室の案内や教育教材の情報、また関連するご相談・問い合わせにつきましては下記よりご確認ください。





