Unityを使わずにフリスビーを犬に届けよ!を作ってみる(4)の続きです。

今回は移動する障害物をつくります。

フリスビーを犬に届けよ!の元ネタ

Unishar-ユニシャー【Unityでのゲーム開発を手助けするメディア】

さぎのみや氏のTwitter

さぎのみや氏の個人ブログ

MovableObstacleクラスの定義

Obstacleクラスを継承してMovableObstacleクラスを定義します。Obstacleクラスについては第一回の記事を参照してください。

コンストラクタの引数が追加されています。最初の2つはX方向とY方向の移動速度です。最後の引数のmaxCountはその回数だけ移動したら逆向きに移動するという意味です。これで同じ場所を往復させることができます。

FrisbeeGameクラスの修正

障害物は固定されているものと移動するものがあるので、FixedObstaclesプロパティとMovableObstaclesプロパティを定義しました。

各ステージを生成するInitメソッドを示します。障害物の生成は後述するCreateObstaclesメソッドでおこないます。

各ステージにある障害物の位置はリソースのテキストファイルを読み込んで取得します。ステージの番号ごとに異なるものを読み込みます。

frisbee-stage-1.txt
frisbee-stage-2.txt
frisbee-stage-3.txt
frisbee-stage-4.txt
frisbee-stage-5.txt

読み込んだ文字列がこのようになっていると・・・

#は固定された障害物
SSSはスタート地点
GGGはゴール地点
▽はその位置とそのひとつ下の間を移動する障害物
△はその位置とそのひとつ上の間を移動する障害物
▼はその位置とそのふたつ下の間を移動する障害物
▲はその位置とそのふたつ上の間を移動する障害物
Rはその位置とそのふたつ右の間を移動する障害物
Lはその位置とそのふたつ左の間を移動する障害物

そのため左の柱に開いている隙間は広くなったり狭くなったりを繰り返すだけで完全に閉じることはありませんが、中央の柱に開いている隙間は完全に閉じてしまう場合があるということになります。

それから半は#よりも16ピクセル下に設置されている障害物です。難易度を上げるために隙間を狭くしたいのですが、64ピクセルでは広すぎる、32ピクセルでは狭すぎて通れないので苦肉の策として。

更新時の処理に移動できる障害物を移動させる処理を追加します。

Player.StageClearメソッドは以下のようになっています。ステージクリアが成立すると更新処理を止めるために死亡フラグをtrueにしています。そのため次のステージが生成されたら死亡フラグをクリアします。また時間の計測もリセットしています。

Playerクラスの修正

障害物の種類が増えたため、当たり判定の処理が少し変更になります。

FrisbeeHubクラスの修正

クライアントサイドにマップのデータを送るとき、固定されている障害物と移動する障害物のデータをわけて送らなければなりません。

障害物が移動したらそれをクライアントサイドに送信しなければなりません。

クライアントサイドにおける処理

クライアントサイドで追加する処理を示します。

最初に固定された障害物と移動できる障害物のふたつがサーバーサイドから送られてくるので、それぞれをシーンに追加します。

更新処理が必要になったらサーバーサイドからUpdateObstaclesToClientが送信されます。この場合は該当するものを移動させます。

それからEndUpdateToClientを受信したときの引数を変更したのとEndUpdateTimeToClientを追加したので以下も追加と変更が必要です。

connection.on(“EndUpdateTimeToClient”, function (time) {
textField1.innerHTML = time;
});

connection.on(“EndUpdateToClient”, function () {
if (maxX – CANVAS_WIDTH / 2 < cameraTargetX) camera.position.x = maxX - CANVAS_WIDTH / 2; else if (CANVAS_WIDTH / 2 < cameraTargetX) camera.position.x = cameraTargetX; else camera.position.x = CANVAS_WIDTH / 2; camera.position.y = 32 * 8 camera.position.z = 650; camera.lookAt(new THREE.Vector3(camera.position.x, 32 * 8, 0)); renderer.render(scene, camera); // レンダリング });