⇒ 動作確認はこちらから

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

前回では車の描画をしました。今回はコースの描画をおこないます。前回同様にTypeScript/JavaScriptで使えるコードをC#で生成するのですが、OpenTKと同じように画像ファイルから読み取ったピクセルのデータをそのまま使おうとすると処理が重たくなってしまいます。ちょっと工夫が必要です。

画像ファイルから点情報を取得するクラス

まずコースが書かれたPNGファイルからGetPixelメソッドで取得したColor.ToArgb()がColor.Black.ToArgb()と同じになる点のリストを取得し、ここからコースの境界線とコースの内部にある点のリストを取得します。これは画像の輪郭を取得するにはとほとんどかわりません。

境界線の点のリストを取得する

次にこのクラスをつかって境界線の点のリストを取得する処理を示します。やっていることはTypeScriptで書く場合、そのままコピペすればコースの両側の境界線を取得するGetCourseBorder1関数とGetCourseBorder2関数として使える文字列の取得です。

コースの内部を取得する

同様にコースの内部かどうかを調べる関数も同様に生成できると考えたのですが、これをやってみると配列が大きくなりすぎて処理も時間がかかるため、読み込みに時間がかかるうえにゲーム中に何度も止まってしまったため、別の方法を考えることにします。

まずコースの内側を黒く塗りつぶす処理ですが、無数の正方形をシーンのなかに敷き詰めるのではなく、帯状になった平面をシーンのなかに追加します。

以下のコードはコースのなかを黒く塗りつぶすために用いる平面の中心座標と奥行きをセットにしたBandクラスの配列を取得するためのGetCourseInside関数を生成するコードです。

TypeScript側で定義するBandクラスは以下のようなものです。

C#側ではループの中で取得した値とそれに1を加えた数をそれぞれ保存しておき、次のループで取得した値とこれらと比較してみます。startが0ではないときにnextよりも大きな数が取得されたときは連続していない点を取得したことになるので、それまでに連続した点があるのであれば終了させ、新たな開始点をつくります。開始点のY座標と終了点のY座標の平均値が平面の中心のX座標になり、終了点のY座標から開始点のY座標を引いて1を加えたものが平面の奥行きになります。

座標はコースの内側かどうか?

次に車がある座標はコースの内側かどうかを取得する関数を生成するメソッドを示します。

TypeScriptで使う

これらを使ってTypeScriptでコースをシーンに追加します。

AddSceneCourseはコースを生成してシーンに追加する関数です。

CreateLeftは進行方向にむかって左側にあるコースの境界線を構成するオブジェクトを生成する関数です。

CreateRightは進行方向にむかって右側にあるコースの境界線を構成するオブジェクトを生成する関数です。

CreateInsideはコースの内部にある平面の集まりを生成する関数です。

IsCarInsideは車がコースアウトしていないか調べる関数です。