⇒ 動作確認はこちらから

アクセルとブレーキは別のキーにしてほしいというリクエストがあったので別バージョンも作成しました。Zキー:アクセル、Xキー:ブレーキです。⇒ 動作確認はこちらから

前回はコースの描画をしました。今回は車の操作とコースアウトしたかどうかの判定、コースアウト時の処理をおこないます。

コースアウトしたかどうかは現在の車の座標を調べればわかります。コースを描画するときにIsCarInside関数を作りました。車の座標を調べて四捨五入で整数に変換してこの関数に渡せばコースアウトしていればfalseが返されます。

ライバル車の動きを実装する

まずはライバル車の動きから考えます。

ライバル車を管理するためのRivalCarクラスを作成します。

コンストラクタを示します。引数は生成時に存在する座標と速度です。静的変数 Carsに追加してあとでまとめて移動させます。静的関数 Addは生成されたインスタンスを配列 Carsに追加するための関数です。

車の向きを最適化する

車を生成したら適切な向きにしなければなりませんが、これをするのがGetIdealRotationY関数です。車が存在するうえで理想の方向を求めるには車の座標にもっとも近いコースの両脇の2点を求め、これと直交する回転角になるような値を求めます。

GetNeerestBorderPoints関数は車の座標にもっとも近いコースの両脇の2点を求めます。

次に車を動かす関数を考えます。車を理想の方向に向かせたら、センターラインからみてどちら側に寄っているかを調べます。大きく左寄りであるときは右にハンドルを切り、右寄りのときは左にハンドルを切ります。そのあと三角関数をつかってposition.xとposition.zを変えます。

そのあと当たり判定をおこないます。自車と衝突した場合は自車がクラッシュしたときの処理(後述)とライバル車をスピンさせる処理をおこないます。ライバル車同士の場合はクラッシュしていないもの同士限定で当たり判定をおこないます。

GetIdealPosition関数は車を配置する理想の座標を求めます。

MoveAll関数は配列に格納されたライバル車すべてに対して移動の処理をおこないます。

RivalCarクラスを継承するクラス

RivalCarクラスを継承して以下のクラスを作成します。コンストラクタの引数はXZ座標と速度です。

ライバル車の初期化

プログラムが開始されたらRivalCarクラスを継承して作成したクラスを使ってライバル車の初期化をおこないます。

自車の操作とコースアウト判定

次に自車に対しても操作とコースアウト判定をおこないます。

自車を初期化

InitMyCar関数は自車を初期化する関数です。

カメラに車を追わせる

FollowCamera関数はカメラを車を追う座標と方向にセットします。

つねに自車から8離れた位置にカメラをセットします。これで常に同じ方向から自車を撮影しているように見えます。ただし左右キーがおされているときは方向転換をしている感じを出すために、少しずらします。

Update関数

Update関数は1秒間に60回呼び出されます。コースは1周が約2キロなので時速がそれに合うように値を調整します。1フレームあたりspeed / expansionRate * 1.05メートル移動していると考えるとちょうどよいようです。

ゴールしたときの時間を記録したいのでUpdate関数が実行された回数を数えます。レースがスタートしてしばらくしてからゴールの周辺を通過した場合、ゴールしたと判断します。

クラッシュ時の処理

Crash関数はクラッシュ時の処理をおこないます。

BlowOffMyCar関数はクラッシュしたため車が吹き飛んでいる処理をおこないます。

ResurrectionCar関数は吹っ飛んだ自車を元の位置に戻します。

移動処理

MoveMyCar関数は通常の移動処理をおこないます。

PlaySoundIfTurning関数は時速100km以上でハンドルを切っているなら音を鳴らします。

ゴール時の処理

IsGoal関数はゴールしたかどうかを調べます。自車の初期座標は(148,0,120)なのでその周辺であればゴール地点にいることになります。

AddStartLine関数はスタート地点に赤い線を引きます。

ShowText関数はゲームに関する情報を表示するためのものです。

HTMLはこのようになっています。

BGMをならす

PlayBGM関数はBGMをならす処理をおこないます。

let soundBgm: HTMLAudioElement = new Audio(‘./sounds/bgm2.mp3’);

完成させる

プログラムが開始されたときに実行される処理を示します。

最後に本体部分を示します。

⇒ 動作確認はこちらから