実行ファイル化がうまくいかない!!!
タイトル通り、pyxel+PyxelUniversalFontだとpyxappの扱いが少々複雑になるようです。つまずいたので、ほぼ日本語オンリーになりますが記事で残しておきます。
環境
macbook air(M1)
python3.12.2
pyxel 2.2.3
pyxel package
pyxappを生成してくれるコマンドですね。最初に正解を言っておくと、
・pyファイル
・pyxresファイル
・その他のデータ、リソースファイル(db,csv,pickle等)
・PyxelUniversalFontに同梱されているフォントファイル!!!
をパッケージ化するディレクトリに入れておけば、正しく実行ファイル化できます。
app2html
PyxelUniversalFontを使っているゲームでは、これは諦めた方がいいです。というのも外部モジュールがhtml上のビルドで同梱されず、PyxelUniversalFontなどのimportが効かないためです。小規模なゲームであればpyxresファイルに無理やり描画内容を突っ込むというフィジカル解決法があるので、そちらをどうぞ。
「同梱されていないなら同梱すればいいじゃない」と思う方がいるかもしれません。実際私も試験的にPyxelUniversalFontのソースを直接pyxappに入れてhtml化してみました。結果、エラーメッセージが変化してpillowが同梱されていません、Javascriptかpythonで入れてくださいみたいなのが出ます。
つまり、pillowも同じように直接pyxappに入れてあげれば多分動くんでしょう。パワーによる同梱は可能です。ただ、倫理的というか著作権的にちょっと危なそうですし、パワーすぎる解決法なのでおすすめはしません。githubからとってきてライセンスとかreadmeとか全部捨ててビルドしたゲームをネット上で晒す勇気があなたにはありますか?
それでもhtml形式が欲しいんだ!という方は自力でpyxresにフォント実装するか、全てASCII化してpyxel.text
で描画しましょう。
app2exe
本命です。まず、app2htmlと違ってこいつは外部モジュールを使うことができます。そのため、PyxelUniversalFontも動きます。しかし、そのままソースファイルだけをディレクトリに突っ込んでパッケージにしたものを実行ファイルにすると、「指定されたフォントがありません」的なログが出ます。つまり、app2exeはスクリプトをインポートできてもライブラリパッケージに含まれるリソースまでは同梱してくれないのです。
なので、フォントリソースだけは手動で同梱する必要があります。
そのフォントリソースは自分のハードディスクから発掘しましょう。
which python
これをコンソールで打ち込むとそのコマンドのソースの場所を教えてくれます。これで大まかなpythonのファイルの位置を掴みます。掴んだら、それを頼りにしてpythonのバージョン別ディレクトリを探します。
/Users/username/.pyenv/shims/python
私の場合pyenv使ってバージョン管理してるので大元のディレクトリがpyenvですね。pyenvじゃない場合もpythonっぽい名前のディレクトリがホームディレクトリ直下とかライブラリ直下とかにあると思います。コマンドラインでもできますけど、コピーするときのパスがだるいのでGUIで開きに行きましょう。
.
から始まる名前は隠しファイルですよ!option+shift+.
で表示しないと見つからないですからね。
で、次に開くのはpyenvの場合「versions」です。ファイル構造は人によって色々あると思いますけど、最終的に「python〇〇.〇〇」みたいな名前のディレクトリが開ければOKです。
「python」「lib」「versions」「python〇〇.〇〇」この辺をぽんぽん開いてけば見つかるはず。
で、「python〇〇.〇〇」の中にある「site-packages」。これがpipで入れたライブラリを入れてるディレクトリです。この中に「PyxelUniversalFont」があるはずです。
それも開いたら、「fonts」というフォントリソースを格納してるディレクトリがあります。その中から任意のフォント.ttf(全部コピーしとけば確実)をコピーして自分がプログラムをいつも書いてるディレクトリにペーストしましょう。
こいつをpyxappに同梱すれば、app2exeで作られた実行ファイルが正常にフォントをレンダーしてくれます。
この説明だいぶわかりづらいと思うので、私の場合のフォントパス書いときますね。参考にしてください。
/Users/username/.pyenv/versions/3.12.2/lib/python3.12/site-packages/PyxelUniversalFont/fonts
雑記
pyxel packageについて
pyxel packageコマンドってちょっと使い方わかりづらくない?と思ったので補足。
pyxel package ディレクトリ 起動スクリプト.py
まず、プログラム動かすのに必要なファイルは全部一個のディレクトリに入れてください。起動スクリプトも含めてです。そしてそのディレクトリをコマンド実行時に指定します。起動スクリプトも指定する必要がありますが、この起動スクリプトっていうのはif __name__=="__main__"
が書いてあるファイルのことです。
ディレクトリには色々入れます。ソースコードやpyxresファイルはもちろん、pickleとかcsvとかsqliteとかopen()
とかで使ってるファイルも全部入れます。上記のフォントファイル.ttfも入れましょう。
pyxapp以外の実行ファイル化について
何かしらの原因でpyxappをうまく扱えないときに、pyinstallerやnuitkaなどといったその他のツールに頼ろうとするのはやめましょう。たとえエラーを吐くのだとしても、pyxappはpyxelプログラムに伴うリソースを自動で同梱し、いくつかのオプションも自動で指定してくれるフォーマットです。
この作っているのがゲーム前提だからこそやってくれている自動化部分をpyinstallerやnuitkaでは手動で設定する必要があり、pyxappで遭遇したエラーとは別の大量のエラーに襲われます(体験談)。
pyxappで出るエラーはちゃんと逃げずにトラブルシューティングしましょうね。