スコアを表示させる機能を追加します。

Form1クラスのなかにScoreというフィールド変数を作成します。あとは敵のクラスでIsDeadがtrueになったときに点数を加算するようにします。

あとはスコアをどうやって表示させるかですが、これまでのようにフォームにラベルを貼り付けてそこに表示させると簡単なのですが、GLControlのなかに書けないかやってみました。

3Dで表示させてきましたが、2Dの表示を組み合わせます。

Draw3D()メソッドはこれまでglControlEx1_Paint(object sender, PaintEventArgs e)メソッドのなかに書いてきたものをまとめただけです。問題はDraw2D()メソッドです。文字を描画するにはどうすればいいのでしょうか?

OpenTKでテクスチャーを使ってテキストを描画する – Qiitaによると「まずテキストのビットマップを作成し、それをテクスチャーとして貼りつける方法がよさそう」とのことです。そこでまずは表示したい文字をBitmapで取得します。

取得するものはスコアですが、それ以外に自分のライフがどうなっているか、対ボス戦闘をしているときはボスのライフも表示させたいです。スコアは上部に、ボスと闘っているときはスコアの下にボスのライフを表示させます。自機のライフは画面下に表示させます。

まずは描画したいもののBitmapを取得するメソッドを示します。

ここからテクスチャを取得します。これはCharacterクラスのものとほとんど同じです。戻り値だけが違います。

ここからテクスチャを取得したらあとは描画するだけなのですが、プロジェクションと視界の設定をする必要があります(ここでハマってしまった)。

あとは描画するだけです。

どこでハマったかというと、実行してみるとうまく表示されません。ライフが使っていない色である緑色に表示されます。

どうやらスコア表示のために生成した部分が影になっているようです。そしてゲーム開始前は緑色の直線が描画されているので、それが反射したわずかな環境光で緑色になっていたのです。わかってしまうとなんでもないですが、わからないと「なんでこうなるの?」となってしまいます。

ということでライトは無効にしました。Lighting()メソッドを呼ぶのをやめました。GL.Disable(EnableCap.Lighting)にします。

あともうひとつハマりどころがありました。実行時間が短時間だと気がつかなかったのですが、長時間プレイしているとメモリがなくなってしまいます。原因はつぎからつぎへとテクスチャをつくり続けていることです。使わないテクスチャはGL.DeleteTexture(int)しなければなりません。

ライトは無効にすると直線に色をつけるためには

これではダメです。そこでDrawField()メソッドを書き換えます。

これで一応、完成ということにします。