はじめに
こちらのQiitaは勝手連載「ジャンプ&ランゲームを作ろう」になります。
初回の記事はこちらです。
【連載】ジャンプ&ランゲームを作ろう(1) プロジェクト作成
※お断り※ 毎日お昼休みに15分程度で執筆していおり細切れになりましてすみません
まずは
プラットフォーム(床)のブロックを自動で作成し続けます。
ブロックは移動しないがカメラが移動します。
カメラ外に外れたブロックは削除します。
先に結論
今回のソースコードはMain.ts
のみいじっています。Main.tsの完成像はこちらです。
https://github.com/liberapp-inc/h5g-qiita-jump-and-run/blob/1b50e73244528bb126427ca24efb7789075acfea/src/Main.ts
ゲームの初期化
カメラの対象となるゲーム内オブジェクトを格納するコンテナオブジェクトworld
を作成します。
まずはカメラの位置を 0
に初期化します。
protected createGameScene(): void {
this.world = new egret.DisplayObjectContainer();
this.addChild(this.world);
this.lastDrawnX = - this.width / 2;
this.cameraX = 0;
this.updateCamera();
}
ゲームループのスタート
ENTER_FRAME
イベントを処理するenterFrame
メソッドがゲームのループ処理になります。
private async runGame() {
:
this.addEventListener(egret.Event.ENTER_FRAME, this.enterFrame, this);
}
各フレームでは
1. カメラの位置を右に移動させます。
2. 次にカメラの視界の先のブロックを生成します。
4. カメラの位置にあわせてすべてのオブジェクトの表示位置を更新します。
5. カメラの視界から外れたブロックを削除します。
private enterFrame(t:number):boolean {
this.cameraX += 1; // 1
this.generateNewBlocks(); // 2
this.updateCamera(); // 3
this.eraseBlocksOutOfCamera(); // 4
return true;
}
カメラの視界の先のブロックを生成
generationBorder
はカメラの位置からちょうど画面幅分右先の位置です。最後に作成したブロックの右端をthis.lastDrawnX
で管理しています。最後に生成したブロックの右端がgenerationBorder
より左まで来た場合にブロックを生成します。
this.colors
で生成するブロックの色のパターンを管理しています。this.generationIndex
で次のブロックがどのパターンになるかを管理しています。
ブロックのサイズはPLATFORM_BLOCK_WIDTH
で、ブロックの世界座標から右方向に幅PLATFORM_BLOCK_WIDTH
、下方向に幅PLATFORM_BLOCK_WIDTH
のブロックを生成します。
private generateNewBlocks() {
const generationBorder = this.cameraX + this.width;
while(this.lastDrawnX < generationBorder) {
const p = new egret.Shape();
p.x = this.lastDrawnX;
p.y = 0;
this.lastDrawnX += PLATFORM_BLOCK_WIDTH;
const c = this.colors[this.generationIndex];
p.graphics.beginFill(c);
p.graphics.drawRect(0, 0, PLATFORM_BLOCK_WIDTH,PLATFORM_BLOCK_WIDTH);
p.graphics.endFill();
this.world.addChild(p);
this.platforms.push(p);
this.generationIndex = (this.generationIndex + 1) % 2;
}
}
カメラ位置に応じて表示の更新
カメラ位置に連動するオブジェクトはすべてthis.world
オブジェクトの子として生成しています。そのためにthis.world
の画面座標を調整するだけですべてのオブジェクトの位置が更新されます。
private updateCamera(): void {
this.world.x = this.width / 2 - this.cameraX;
this.world.y = this.height / 2;
}
最後に
画面の左端(カメラの位置から画面幅の半分だけ左)より左側にある非可視のオブジェクトをすべて削除します。
private eraseBlocksOutOfCamera() {
const visibilityLeft = this.cameraX - this.width / 2;
this.platforms = this.platforms.filter((p) => {
const r = p.x + p.width;
const inCamera = visibilityLeft <= r;
if (!inCamera) {
this.world.removeChild(p);
}
return inCamera;
});
}