クラス分けした。pyxelにおける日本語表示の集大成。
成果物
前回と同じに見えるが、コードが全然ちがう。
コード
1. run.sh
- 00FF © 2018 hicc 患者長ひっくからttfファイルを入手
- BitmapFontGenerator.py: TTF→PNG
- main.py
以下のような構造。
ファイル | 役割 |
---|---|
run.sh | 実行用スクリプト |
BitmapFontGenerator.py | TTF →PNG |
main.py | PNG →pyxel.blt →日本語を窓に表示 |
他
ファイル | 役割 |
---|---|
PyxelText.py | ビットマップフォント出力API。draw(x, y, s) 。座標x ,y に文字列s を表示する。s には平仮名と片仮名も指定できる。 |
x8y12pxTheStrongGamer.py | ビットマップフォント固有データ。識別名と1文字あたりの幅と高さを持っている。 |
BitmapFontMapper.py | 文字(Unicode番号 )とPNG画像上の座標における対応表をつくる |
BitmapFont.py | TTFからPNGを作成する |
PyxelSpec.py | pyxelの仕様をまとめた(画像の最大サイズ等) |
別のフォントを使うときはx8y12pxTheStrongGamer.pyを参考にすればできるはず。(未確認)
使い分け
TTF→PNG
TTFファイルからPNGファイルを作成したいとき。必要なファイルは以下。
pyxelで表示したいとき
- ビットマップフォント画像(PNG形式)
- main.py
- PyxelText.py
- x8y12pxTheStrongGamer.py
- BitmapFontMapper.py
- BitmapFont.py
- PyxelSpec.py
PNGがあればTTFは不要。これが今回のポイント。
要点
PNGがあればTTFは不要
TTFファイルが無くともPNGがあれば表示できる。
あとはPNGファイルを.pyxres
にドラッグ&ドロップすれば.pyxres
ファイル1つに固めて配布できるはず。TTFを配布せずに済む。ピクセルデータだけで完結できる。
技術面のキモ
ピクセルデータ操作
BitmapFont.pyにてピクセルデータを__data
に入れている。
self.__data = numpy.array(img.getdata()).reshape(PyxelSpec.Image.Size[0], PyxelSpec.Image.Size[1])
PIL.Image.getdata()は、この画像のピクセル値をシーケンスで返す。内部PILデータ型のため特定のシーケンス操作のみ許容する。通常のシーケンスに変換するにはlist(img.getdata())
する。今回のコードはnumpy
で操作するためnumpy.array()
している。
numpy.arrayは配列を作成する。
numpy.reshape()はデータを変更せずに配列に新しい形状を与える。numpy.arange(6).reshape((3, 2))
すると[[0,1],[2,3],[4,5]]
になる。
__data[y][x]
のように入っており、値は0
,255
のいずれか。0
が背景色で、255
が文字の部分。おそらくPNGはインデックスカラー。ここで取得された0
や255
はパレットのインデックス番号と思われる。8bitカラーのインデックスカラーは256色まで。つまり0
〜255
。通常、0
番は背景や透明色である。
なぜ`__data[x][y]
でなく__data[y][x]
か。それはfor文で回すときに「左から右へ。上から下へ」の順でピクセル捜査できるから。以下のように。この方向は一般的なものなので踏襲する。
class PyxelText: ... def __load(self): img_bank = pyxel.image(self.__img) for y in range(PyxelSpec.Image.Size[1]): for x in range(PyxelSpec.Image.Size[0]): img_bank.set(x, y, self.__col if self.__font.Data[y][x] else 0)
0
以外なら、pyxelパレット番号のうち指定した値self.__col
に変換して画像を作成する。なお、__load()
内でいう画像はPILの一般的な画像ではなく、pyxelの16色インデックスカラーな画像である。
課題
- 他のフォントで試す
- 文字の色を変える
- 漢字も対象にする
- メッセージウインドウの枠内で折り返す
- 1文字ずつアニメーションし音を出す
所感
とりあえず、日本語の表示は一旦ここまでにしよう。他にも課題は多いが、フォントだけに時間を取られてしまうとゲームがいつまでたってもできない。あとは必要に応じて都度やる。
情報源
製作者、先駆者に感謝。
前回まで
- ラズパイ4Bにpyenvをインストールする(python 3.8.2)
- pyxelをインストールする(pyenv python3.8.2)
- pyxeleditorにおけるImageエディタの使い方
- pyxeleditorにおけるTileMapエディタの使い方
- pyxeleditorにおけるSoundエディタの使い方
- pyxeleditorにおけるMusicエディタの使い方
- pyxelのリソースにおける概念・制限まとめ
- pyxeleditorにおけるpyxresファイル形式まとめ
- pyxelのAPI調査
- pyxelで最小コード 窓を出す
- Pyxelで窓の境界線を消す
- 携帯ゲーム機の解像度
- pyxelで矩形を描画する
- pyxelで荒ぶる矩形
- pyxelでキーに応じて動く矩形
- pyxelで画像を描画する
- pyxelで画像をアニメーションする(スプライト。パラパラ漫画)
- pyxelで左右反転した画像を使ってアニメーションする
- pyxelでテキストを表示する
- pyxelで日本語を表示する1(ビットマップ・フォント)
- ビットマップフォント作成(TTF→PNG)
対象環境
- Raspbierry pi 4 Model B
- Raspbian buster 10.0 2019-09-26 ※
- bash 5.0.3(1)-release
- pyxel 1.3.1
$ uname -a Linux raspberrypi 4.19.97-v7l+ #1294 SMP Thu Jan 30 13:21:14 GMT 2020 armv7l GNU/Linux