はじめに
この記事では p2.js 物理エンジンを使用して、
EgretEngineのオブジェクトに物理現象を加えていきます。
準備
p2.js 物理エンジンのダウンロード
1、egret-game-libraryのダウンロード
GitHubより、「egret-game-library」をダウンロード。
「egret-game-library」を解凍して、egret-game-library-master/physics/libsrc/binを開きます。
その中の「physics」フォルダを、プロジェクトフォルダがある場所にコピーしてください。
場所は、「Egret Launcher」を起動して、Open project locationを押せば分かります。
2、p2.js物理エンジンの適用
プロジェクトを開き、「egretProperties.json」を開いてください。
次に、
1 2 3 4 |
{ "name": "physics", "path": "../physics" }, |
を追加してください。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
{ "engineVersion": "5.2.13", "compilerVersion": "5.2.13", "template": {}, "target": { "current": "web" }, "modules": [ { "name": "egret" }, { "name": "eui" }, { "name": "assetsmanager" }, { "name": "tween" }, { "name": "promise" }, { "name": "physics", "path": "../physics" }, { "name": "game" } ] } |
ここで注意点です。
このjsonファイル内では、ダブルスラッシュでコメントを付けるとエラーになります。
できるだけ、余計なものはつけないようにしましょう。
「../」は、jsonファイルの1つ上のフォルダへ行くという意味です。
また、
1 2 3 |
{ "name": "game" } |
をついでに付けておきましょう。
これは「MainContext」というコードを使用するときに使用します。
MainContextは、
1 |
egret.MainContext.instance.stage.stageHeight; |
のように使用し、ステージ(画面)の高さや幅を取得するときに使います。
ゲームをデバッグで実行すると、modulesフォルダ内にphysicsが生成されます。これで完了です。
p2.js 物理エンジンを使用した自然落下
Main.ts
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
class Main extends eui.UILayer { public constructor() { super(); this.once(egret.Event.ADDED_TO_STAGE, this.addToStage, this); } private addToStage(event:egret.Event) { //物理エンジンを使うようのフィールドを作成 const world = new p2.World(); world.sleepMode = p2.World.BODY_SLEEPING; world.gravity = [0, 9.8 * 50]; //物理挙動をもつコライダーの生成 const body : p2.Body = new p2.Body({mass:1, position:[200,300]}); const bodyShape = new p2.Circle({ radius: 100 }); body.addShape(bodyShape); world.addBody(body); //ループ処理 egret.Ticker.getInstance().register(loopMethod,this); function loopMethod(dt:number) { world.step(1/60, dt/1000, 10); drawBall(); } //図形の表示用オブジェクトのインスタンス化 const shape:egret.Shape = new egret.Shape(); this.addChild(shape); //ボールの描画 function drawBall(){ //ステージに残っている図形を一度消す shape.graphics.clear(); shape.graphics.beginFill(0xff0000); shape.graphics.drawCircle(body.position[0], body.position[1], 100); shape.graphics.endFill(); } } } |
物理現象をステージに付与
1 2 3 |
const world = new p2.World(); world.sleepMode = p2.World.BODY_SLEEPING; world.gravity = [0, 9.8 * 50]; |
「world.sleepMode = p2.World.BODY_SLEEPING; 」は、一定時間が経過したオブジェクトの物理エンジンをスリープ状態にし、パフォーマンスを向上させます。
「world.gravity = [0, 9.8 * 50];」でステージに重力を付与します。
ここで注意点ですが、p2.js と EgretEngineは長さの単位が異なるうえ、座標系も違います。
なので、座標を補正してあげる必要があるため、50を掛けています。
物理挙動を持つコライダーの生成
1 2 3 4 |
const body : p2.Body = new p2.Body({mass:1, position:[200,300]}); const bodyShape = new p2.Circle({ radius: 100 }); body.addShape(bodyShape); world.addBody(body); |
コライダーは接触判定をおこなったり、壁にめり込まないように計算してくれるワイヤーフレームです。
詳しくは、こちらのコライダーの記事もご覧ください。
「const body : p2.Body = new p2.Body({mass:1, position:[200,300]});」でコライダーを生成します。
1 2 3 4 5 6 7 |
var body = new Body({ mass: 1, position: [0, 0], angle: 0, velocity: [0, 0], angularVelocity: 0 }); |
のように、{ } の中でposition や angle 等を設定できます。
BodyのAPIについては以下の公式サイトをご覧ください。
「const bodyShape = new p2.Circle({ radius: 100 });」でコライダーを円形に切り取る準備をします。
最後に「body.addShape(bodyShape);」でコライダーを円形に切り取り、「world.addBody(body);」で画面に追加します。
ループ処理「egret.Ticker.getInstance()」
1 2 3 4 5 6 7 |
//ループ処理 egret.Ticker.getInstance().register(loopMethod,this); function loopMethod(dt:number) { world.step(1/60, dt/1000, 10); drawBall(); } |
ループ処理を行うには「egret.Ticker.getInstance().register( 関数 ,this);」を使用します。
「world.step(秒, 関数が最後に呼び出されてからの経過時間, 関数の呼び出しごとにとる固定ステップの最大数);」です。
このメソッドを使って円の描画をしていきます。
コライダーだけでは無色透明なので、図形の描画は必要です。
図形の描画
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
//図形の表示用オブジェクトのインスタンス化 const shape:egret.Shape = new egret.Shape(); this.addChild(shape); //ボールの描画 function drawBall(){ //ステージに残っている図形を一度消す shape.graphics.clear(); shape.graphics.beginFill(0xff0000); shape.graphics.drawCircle(body.position[0], body.position[1], 100); shape.graphics.endFill(); } |
上記コードで円の描画をおこなっております。円の描画方法は以下の記事も参照してください。
【eui.UILayer】図形の描画方法「drawCircle」「drawRect」「lineTo」
「shape.graphics.clear();」で現在ステージに描画してあるオブジェクトを消去します。
これがないと、以下のように線状になります。
参考URL
EgretEngineで超簡単なゲームを作ってみよう(2) 物理エンジン エクステンションの導入
EgretEngineで超簡単なゲームを作ってみよう(3) タップでの操作の実装
次回の記事