ゲージにこる (偽NaGu-Ru開発日記)00/01/15

さて今回は、アクションゲームなどで体力ゲージが表示されている、 「ステータスパネル(とでもいうのかな?)」に凝ってみることにしました。 あまりにも拙作ゲームのパネルがへっぽこだったので(^^;)

えーと、よく見る「ゲージ」っていうのは、大抵縦か横にまっすぐ増えていく、 っていうのが多いですよね。しかーし!!な〜んかこれだと簡単過ぎて つまんないんじゃない?と思う方もいるはず(もしかして俺だけ?)。確かに、 一番直感的で分かり易いんだと思うけどね。

で、いろいろ考えた結果、「ゲージは円形」ということになりました。 左の図を見てみれば分かると思いますが、なんちゅーか、昔のレースゲームで よく見かけるようなやつです。でも、結構これを作るとなればむっかしーんです。

んじゃ、何が難しいのか。それは「ゲージの増え方」ですよ。 縦、横にまっすぐ伸びるやつだと、ゲージが淡色で塗りつぶされているものであれ、 画像を使っているものであれ、かなり簡単に処理できます。だって、 転送する範囲は「矩形」なんですから。

しかし、円形ゲージでは転送範囲が「矩形」ではなく「扇形」ですよね。 これがむっかしーんですよ。扇形で転送できる関数とかはないので、このへんを 自前で処理する必要があるのです。しかし、これをなんとかしてこそプログラマというもの。

ちゅうわけで、いろいろと方法を考えてみるわけです。
まず、最初に思いつくのが「ゲージを色分けして区切っておいて、それをFloodFillで塗る」 という方法でした。これなら、ゲージの画像を適当に作ってから、塗りつぶす点を ちゃんと指定してやれば実現できるという、一番手軽な方法だと思います。

しかし、上記の方法ではゲージに画像を使うことができないし、 どうもしっくりこないので、他の方法を考えることにしました。 で、どうするかというと、画像変形のひとつである「極座標変換」を使うのです。 具体的には、矩形範囲の転送を使って画像をずらしたり、指定色で塗りつぶしてから、 極座標変換を適用することによって、みごと「扇形」転送処理を施したかのように 見せることが出来ます。
下に、図を置いときます。
これが これが...→ これもんに!! これもんに!!

さて、だいたいイメージはつかんでもらえたと思います(つーかツカンドケ!!)。 では早速詳しくいってみましょう。
とはいえ、極座標変換を多少なりともツカンデる、ということを前提にして話を進めますよ。 そのへん、覚悟しておいてくださいね(もう一回見とけ)。

実は、極座標変換の高速化のために作っている「極座標テーブル」を作っているところを ちょこっと変更してやるだけで、いいんです。用は、転送元のサイズをうま〜く転送先にあわせる、 そんだけです。


{R・・・半径、kTable・・・極座標テーブル、tex・・・テクスチャ、}
p:=@kTable;
  for y:= 0 to R*2-1 do begin
    for x:= 0 to R-1 do begin
      //中心座標による変換
      tx:=x-R;
      ty:=R-y;
      //直交→極
      dx:=trunc(Atan2(tx,ty) * tex.Width / 1024);
      dy:=trunc(sqrt(tx*tx+ty*ty)*(tex.Height/24));

      //テーブルに入れる
      p^:=Point(dx,dy);
      //次へ
      Inc(p);
    end;
  end;
こんな感じになるだけです。 変更したのは赤い部分です。あ、Atan2で例外処理をしていないことと、 この場合、角度は360°系(2π)ではなく、1024度系ってことに注意してね。
それと、テーブルのサイズが24×48ですが、これは半円のゲージを作るためです。

このゲージをスクロールさせると、「ゲージが増える(減る)」っていう処理になります。

※ゲージ
なんつーか、こんなやつ。

※円形
イメージとしては、 こんな感じ。↓

※矩形
僕も最初読めなかった感じのひとつ。 「くけい」と読むらしい。何かというと、長方形...かな? 構造体でいうとTRect(DELPHIで)に当たる。

※「扇形」で転送できる関数はない
当たり前といえば当たり前。おそらく、TCanvas.CopyRectやBitBlt、DirectDrawSurface.Blt感覚で 行うとなれば、ペイントで実装されている「自由範囲指定」みたいな、ちょっと高度なテクニックが いると思う。

※これをなんとかしてこそプログラマ。
どっかで聞いたような言葉だと思う人は少なくあるまい。 3Dプログラミングに詳しい「shi3z」氏が「Direct3Dプログラミングガイドブック」で 使っていたセリフであるからだ。なんとなく格好いいので、使わせてもらった(悪く言えばパクった)。

※FloodFill
WinAPIでサポートされているGDI関数。 パラメータを指定して画像を指定色で塗ることができる。 妙に使いづらいという記憶がある。

※極座標変換
座標系を、ディスプレーで採用されている「直交座標系」から 「極座標系」に変換することにより、画像を丸く変形する処理。 詳しくはこちら。






もどる