JP / EN

広告
2023/06/23

ゲームUIのために画像で数字を描画~オリジナルのテクスチャで任意の数字を~

タグ:game

ゲームUIでは体力やダメージなどの表示に数字がしばしば必要になるが、 独自に用意した数字テクスチャ画像を使いたいときにちょっとコツが 必要になる。 むろんフレームワークのテキスト描画機能を使って数値を テキストに変換してから描画すれば簡単ではあるが、 フォントの融通が利かない問題がある。装飾的にデザインした オリジナルの数字テクスチャで任意の数字を描画することが できれば、かなり表現の幅が広がる。
なおサンプルコードではローレベルのスプライト描画APIを使うことを想定 している。ツクールやUnityでもアルゴリズム的には同様のことをする ことになるはずではあるが、テクスチャの切り替えのために スクリプトを使ったりする必要があるかもしれない。

使う素材

図のように"0"から"9"が多くのプログラミング言語の仕様 0始まりと合わせるために "0"から始めるのがおすすめ。 これによって[画像幅] * [数字]で描画したい数字に対応する スプライトを参照できるようになるのだ。 あの規則的でなくてもプログラム的に対応できないことはないが、煩雑になる。


図:数字画像素材 7seg LED風、自作・ご利用は自由にどうぞ

考え方とサンプルコード

素材として0から9までの数字が連番で並べてあるので
  • 描画したい値の1桁目の数字を調べる
  • 調べた数字に対応するフレームを桁数に合わせた位置に描画
  • 2桁目, 3桁目と表示したい桁数だけ上を繰り返す
ということをすればよい。

C++でこれを実現した関数は、こんな感じになる
  void renderNumber(Graphics* graphics, Image* img, int num, int x, int y)
  {
    const int max_num_digits = 8;  / 最大桁数
    for (int i = max_num_digits; i >= 0; i--)
    {
      const int spritew = 16;  // スプライトの幅
      const int spriteh = 32;  // スプライトの高さ
      int base = 1;  // 基数、何桁目を描画しているかを計算
      for (int j = 0; j < i; j++)
        base *= 10;  // 10のi乗を計算、数学ライブラリをincludeするのが面倒だったのでforループで
      int digit = (num / base) % 10;  //これでi桁目の数字を[0, 9]の範囲として取得
      graphics->draw(
        img,  // 画像
        x + (max_num_digits - i) * spritew,  // 描画位置のx座標
        y,    // 描画位置のy座標
        spritew * digit,  // テクスチャ参照位置のx座標
        0,  // テクスチャ参照位置のy座標
        spritew,  // スプライトの幅
        spriteh;  // スプライトの高さ
      }
  }
  
このコード内のGraphicsImageは それぞれライブラリの画像描画機能・画像をラップした独自クラスである。 適宜自分のライブラリに読み替えられたい。
流儀としては下桁から描画を始めるか上桁から始めるかがあるが、 ここでは上桁から、左から右へ描画している。 もちろんどちらでもよい。
またここでは最大8桁で、上が余ったら0埋めをしている。

これをゲーム内に入れるとこんな感じになる。 ここではスポーツ場のスコアボード的なものを上の素材で作ってみた。


図:上記描画数字をゲーム内に取り込んだ例


このエントリーをはてなブックマークに追加

https://wonderhorn.net/