mieki256's diary



2014/12/13() [n年前の日記]

#1 [dxruby] DXRubyとBMFont

ゲーム制作時に使うビットマップフォントのフォーマットの一つに、BMFont?ってのがあるのですけど。Unityあたりでも使えたりする、のかな。たしかそのはず。

_Bitmap Font Generator 、もしくは、 _ShoeBox で作ることができる。以下の2種類のファイルで構成されているのですが。
mplus1p_heavy_0-export.png

_mplus1p_heavy_0-export.fnt
info face="C:\home\Pictures\_work\bitmapfont\mplus1p_heavy_0-export" size=32 bold=0 italic=0 charset="" unicode=0 stretchH=100 smooth=1 aa=1 padding=0,0,0,0 spacing=1,1
common lineHeight=80 base=26 scaleW=256 scaleH=256 pages=1 packed=0 alphaChnl=1 redChnl=0 greenChnl=0 blueChnl=0
page id=0 file="C:\home\Pictures\_work\bitmapfont\mplus1p_heavy_0-export.png"
chars count=96
char id=33 x=175 y=149 width=13 height=24 xoffset=0 yoffset=56 xadvance=14 page=0 chnl=0 letter="!"
char id=34 x=156 y=173 width=18 height=15 xoffset=0 yoffset=55 xadvance=19 page=0 chnl=0 letter="""
char id=35 x=26 y=151 width=23 height=24 xoffset=0 yoffset=56 xadvance=24 page=0 chnl=0 letter="#"
char id=36 x=95 y=125 width=20 height=29 xoffset=0 yoffset=54 xadvance=21 page=0 chnl=0 letter="$"
 ...
 ...
 ...
char id=125 x=156 y=122 width=18 height=30 xoffset=0 yoffset=55 xadvance=19 page=0 chnl=0 letter="}"
char id=126 x=50 y=159 width=22 height=13 xoffset=0 yoffset=63 xadvance=23 page=0 chnl=0 letter="~"
char id=32 x=0 y=0 width=0 height=0 xoffset=0 yoffset=0 xadvance=20 page=0 chnl=0 letter=" "
char id=9 x=0 y=0 width=0 height=0 xoffset=0 yoffset=0 xadvance=160 page=0 chnl=0 letter="	"

kernings count=0

コイツを、DXRuby で表示してみたい、と思ったわけです。

とりあえず、ShoeBox で BMFont画像と .fnt を作成してから、 _SFontぽいもの - mirichiの日記 を参考にしつつソースを書いてみました。参考にというか、丸写しですけど。

_bmfont.rb
require 'dxruby'

# DXRuby BMFont 描画用クラス
#
# ShoeBox で作成したビットマップフォントを描画する
# @see http://renderhjs.net/shoebox/
#
# @example
#     require 'dxruby'
#     require_relative 'bmfont'
#     bmfont = BMFont.new("bmfont.png", "bmfont.fnt")
#     Window.loop do
#       Window.draw_bmfont(100, 20, "Hello BMFont", bmfont)
#     end
#
# @version 0.0.2
#
class BMFont

  # フォントの各文字を格納する構造体
  BMFontData = Struct.new(:image, :w, :h, :xofs, :yofs, :xadvance)

  # @return [Integer] 文字間スペース(単位はドット)
  attr_accessor :spacing

  # @return [Integer] フォント縦幅(単位はドット)
  attr_reader :height

  # @return [Integer] フォント縦幅調整値(単位はドット)
  attr_reader :line_height

  # @return [Integer] フォントベースライン位置
  attr_reader :baseofs

  # コンストラクタ
  # @param [String] imgfilename 画像ファイル名
  # @param [String] fntfilename 文字配置情報(.fnt)ファイル名
  # @param [Integer] spacing    文字間スペース
  def initialize(imgfilename, fntfilename, spacing = 0)
    img = Image.load(imgfilename)

    @bmfont_array = {}
    @spacing = spacing
    @height = 0
    @line_height = 0
    @baseofs = 0
    @chars_count = 0
    cnt = 0

    # .fntファイルを1行ずつ読み込んで処理
    open(fntfilename) {|file|
      while l = file.gets
        l.chomp!
        if l =~ /^chars count=(\d+)$/
          # 文字数取得
          @chars_count = $1.to_i
        elsif l =~ /^common (.+)$/
          # フォントの縦幅やベースライン位置を取得
          p = $1
          p.split(' ').each do |s|
            if s=~ /^(\S+)=(\d+)$/
              case $1
              when "lineHeight"
                @line_height = $2.to_i
              when "base"
                @baseofs = $2.to_i
              end
            end
          end
        elsif l =~ /^char (.+) letter=\"(.)\"$/
          # 1文字分の情報を取得
          str, c = $1, $2
          p = {}
          str.split(' ').each do |s|
            p[$1] = $2.to_i if s =~ /^(\S+)=(\d+)$/
          end

          id, x, y, w, h = p["id"], p["x"], p["y"], p["width"], p["height"]
          xs, ys, xa = p["xoffset"], p["yoffset"], p["xadvance"]
          cimg = img.slice(x, y, w, h) # 画像切り出し
          @bmfont_array[id] = BMFontData.new(cimg, w, h, xs, ys, xa)
          @height = h if @height < h
          cnt += 1
        end
      end
    }
    img.dispose
  end

  # 配列として指定した際に、BMFont情報の構造体を返す
  # @param [Integer] index 配列添字
  def [](index)
    return @bmfont_array[index]
  end
end

# Windowクラスに追加するBMFont描画用メソッド
module Window

  # BMFontを描画
  # @param [Number] x 描画x座標
  # @param [Number] y 描画y座標
  # @param [String] str 描画文字列
  # @param [Object] bmfont BMFontクラス
  # @param [Number] z 描画優先順位
  def self.draw_bmfont(x, y, str, bmfont, z = 0)
    str.each_byte do |code|
      x1 = x + bmfont[code].xofs
      y1 = y + bmfont[code].yofs - bmfont.line_height + bmfont.baseofs
      Window.draw(x1, y1, bmfont[code].image, z)
      # Window.drawBoxFill(x, y, x+2, y+2, C_RED)
      x += bmfont[code].xadvance + bmfont.spacing
    end
  end
end

# Imageクラスに追加するBMFont描画用メソッド
class Image

  # BMFontを描画
  # @param [Number] x 描画x座標
  # @param [Number] y 描画y座標
  # @param [String] str 描画文字列
  # @param [Object] bmfont BMFontクラス
  def draw_bmfont(x, y, str, bmfont)
    str.each_byte do |code|
      x1 = x + bmfont[code].xofs
      y1 = y + bmfont[code].yofs - bmfont.line_height + bmfont.baseofs
      self.draw(x1, y1, bmfont[code].image)
      x += bmfont[code].xadvance + bmfont.spacing
    end
  end
end


if $0 == __FILE__

  #テストコード

  lst = [
    "!\"\#$%&'()*+,-./0",
    "123456789:;<=>?@",
    "A B C D EFGHIJKLMNOP",
    "QRSTUVWXYZ[\]^_`",
    "abcdefghijklmnop",
    "qrstuvwxyz{|}~"
  ]

  # BMFontクラスを生成
  bmfont = BMFont.new('mplus1p_heavy_0-export.png', 'mplus1p_heavy_0-export.fnt')

  # 画像に描画してみる例
  image = Image.new(640, 240)
  x, y = 0, 0
  lst.each do |s|
    image.draw_bmfont(x, y, s, bmfont)
    y += bmfont.height
  end

  Window.bgcolor = [96, 96, 96]

  Window.loop do
    break if Input.keyPush?(K_ESCAPE)

    # 画面に描画してみる例
    x, y = 0, 0
    lst.each do |s|
      Window.draw_bmfont(x, y, s, bmfont)
      y += bmfont.height
    end

    Window.draw(0, 240, image)
  end
end

こんな感じの表示に。
bmfont_ss.png


他のスクリプトから呼ぶときは、以下のような感じ。

_main.rb
require 'dxruby'
require_relative 'bmfont'

bmfont = BMFont.new("mplus1p_heavy_0-export.png", "mplus1p_heavy_0-export.fnt")

Window.loop do
  y = 20
  Window.draw_bmfont(100, y, "Hello DXRuby", bmfont)
  y += bmfont.height
  Window.draw_bmfont(100, y, " & BMFont", bmfont)
end

とりあえず、ファイル一式を置いときます。

_bmfontsupport_20141213.zip

同梱のBMFont画像は、M+フォントで作ったので、たぶん自由に使えるはず。

スクリプトソースは、DXRuby作者様のソースを丸写しに近いのでライセンスはよくわかりませんが、たぶん自由に使っていいんじゃないかなと。DXRubyのヘルプファイルにも、
添付のサンプルスクリプト及びドキュメント内のスクリプトは全てパブリックドメインとします。著作者人格権は行使しません。そのまま使うなり、改造するなり、著作権表示など一切いりませんのでご自由にどうぞ。
と書いてありますし…。

#2 [dxruby][cg_tools] BMFontの作り方

一応、 _ShoeBox を使った BMFont の作り方もメモ。

ShoeBox を起動して、「GUI」タブを選択。
ss001.png

「Bitmap Font」のアイコンをクリックすると、「Cpoied Text to Clipboard」ってメッセージが点滅表示されて、必要な文字列がクリップボードにコピーされます。
ss002.png
_bmfont_string.txt に、文字列を貼り付けときました。

この文字列を使って、一旦、横に長いフォント画像を作成します。

自分の場合はGIMPで作成。画像を新規作成。
ss003.png

横幅が6,000ドットぐらいの、でかい画像に。
ss004.png

テキストツールを選択。
ss005.png

テキストツールを使って、先ほどクリップボードにコピーしてあった文字列を貼り付けて(Ctrl +V で貼り付け)、文字を描画。
ss006.png

ブレンドツール(グラデーション塗りするツール)その他を使って化粧。
ss007.png

レイヤーウインドウで右クリックして「可視レイヤーの統合」。
ss008.png

「画像」→「画像の自動切り抜き」で、最小限の大きさの画像に。レイヤー統合する前にコレ使うと切り取られ過ぎちゃうので、レイヤー統合してから使ってます。
ss009.png

「ファイル」→「Export As...」で、png画像として保存。
ss010.png

ShoeBox に、今保存したpng画像をドラッグアンドドロップ。
ss011.png

すると、下のようなウインドウが開く…はず。
ss012.png

右下の「Settings」で、テクスチャの詰め方や、ビットマップフォントのフォーマットを選べるようですが、とりあえず「Default」にしておけばヨサゲ。

「Save Font」をクリックすれば、元のpng画像のあるフォルダに、 という2つのファイルが保存されるはず。これが、BMFont画像と .fnt ファイルです。お疲れ様でした。

#3 [nitijou] 某所に行ってきた

Word文書とExcel文書を作成できたので、電動自転車で届けに。PM03:00-PM04:45までお邪魔してきた。詳細はGRPでメモ。

帰りは雪が降ってきた。トホホ。リオンドールとダイソーに回って、ファイルやら夜食やらを購入。

イイ感じの教え方はないものか。 :

相手は、PCに触ること自体が初めての方なので、
  • マウスの左ボタン、右ボタン、ホイールの使い分け
  • Deleteキー、Page Up/Downキー、カーソルキーの存在
等々を口頭で教えてみたものの。どうも自分の教え方は効率が悪いというか、たぶんコレ、すぐ忘れちゃうだろうなと…。自分がそのへん覚えていった過程を参考にできればいいのだけど、これが思い出せなくて。分かりやすい教え方ができてるのかよくわからず。

仮に本を渡したとしても、ほとんどの場合、読んでもらえないだろうし。TV番組っぽい動画チュートリアルでもあれば分かりやすいのだろうか。

アプリの言うとおりに操作していくと覚えられる、みたいなソフトって無いのかな。ソースネクストあたりで出してそうだな…。

ググってみたら、Excel の操作を覚えられるアプリ、みたいなものがソースネクストから出てるらしい。しかし、2007/2010/2013対応版…。2003版はもう入手不可っぽい。当たり前か。なかなか難しい。

以上、1 日分です。

過去ログ表示

Prev - 2014/12 - Next
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31

カテゴリで表示

検索機能は Namazu for hns で提供されています。(詳細指定/ヘルプ


注意: 現在使用の日記自動生成システムは Version 2.19.6 です。
公開されている日記自動生成システムは Version 2.19.5 です。

Powered by hns-2.19.6, HyperNikkiSystem Project