2 つのコマンドで HTML 1 枚にまとめ、GitHub Pages に置く
完成した Candy Hunt を、インストールなしでブラウザから遊べる形にして公開します。 これで step1 は完了です。
手順は step0 の Star Voyager でやったものと同じです。 やり方そのものは step0 フェーズ 8 にくわしく書いてあるので、 このページは手順を短くおさらいし、step1 で新しく出てくることだけを厚く扱います。
pyxel package と pyxel app2html は、
フォルダ → 1 つのファイル → 1 枚の HTML と、順にまとめていくコマンドです。
実際に step1 で実行して、できたファイルの中身と大きさを確かめました。
<script src="https://cdn.jsdelivr.net/gh/kitao/pyxel@2.9.9/wasm/pyxel.js"></script>
ゲーム(6 KB)は埋め込まれていますが、Pyxel 本体は毎回ネットから読み込みます。
だからオフラインでは動きません。そしてバージョンが 2.9.9 と書き込まれているので、
あとで Pyxel を新しくしても、この HTML は作ったときのバージョンで動き続けます。
pyxel package は、指定したフォルダの中身を丸ごと詰め込みます。
「起動スクリプトと、それが読むファイルだけ」を選んでくれるわけではありません。
実際に step1 フォルダをパッケージ化したら、中身はこうなりました。
| 入ったもの | 大きさ | これは? |
|---|---|---|
step1/candy_hunt.py | 10,190 | ゲーム本体。当然入る |
step1/candy_hunt.pyxres | 589 | 絵と音。当然入る |
step1/.pyxapp_startup_script | 13 | Pyxel が作るメモ。
中身は candy_hunt.py という文字列だけ。どれで起動するかを記録している |
step1/tempCodeRunnerFile.py | 67 | これは要りません。VS Code の拡張機能が作った一時ファイルです |
tempCodeRunnerFile.py は、動作には影響しません。
ただし公開する HTML の中に、そのまま入って配られます。__pycache__ フォルダ(Python が自動で作る中間ファイル)は
Pyxel が自動で除いてくれます。これは気にしなくて大丈夫です(実測で確認)。
.gitignore に書いてあっても、パッケージには入ります
このリポジトリの .gitignore には、すでに
tempCodeRunnerFile.py が書いてあります。
それでもパッケージには入りました(実測)。.gitignore は Git に対する「これは記録しなくていい」という指示であって、
ファイルを消すものではありません。pyxel package は .gitignore を
まったく見ていません。ディスクにあるものは、そのまま入ります。ブラウザには、ユーザーが 1 度も操作していないページから音を出してはいけない という共通のルールがあります。広告が勝手に鳴り出すのを防ぐためのものです。
Pyxel はこれに合わせて、始める前に CLICK TO START をはさむ作りになっています。
このクリックが「ユーザーの操作」になるので、そのあとは自由に音を鳴らせます。
pyxel.playm() は、
フェーズ 9 で start_game() の中に置きました。
タイトル画面で Enter を押してから鳴り始めるということです。| コマンド | すること |
|---|---|
pyxel package APP_DIR STARTUP_SCRIPT |
フォルダを .pyxapp 1 つにまとめる。
出力名はフォルダ名で決まる |
pyxel play FILE.pyxapp |
できた .pyxapp を手元で動かして確かめる |
pyxel app2html FILE.pyxapp |
.pyxapp を HTML 1 枚にする |
python -m http.server |
手元で Web サーバーを立てて、公開前の HTML を確かめる |
pyxel package step1 step1/candy_hunt.py なら
step1.pyxapp ができます(candy_hunt.pyxapp ではありません)。
1 つのフォルダに作品を 2 つ入れると名前がぶつかって上書きされます。
くわしくは備忘録の
1 つのフォルダに複数の作品があるにまとめてあります。
まず step1/ の中を見て、ゲームに要らないファイルを消します。
.gitignore に書いてあるかどうかは関係ありません(上の警告のとおりです)。
step1/
├── candy_hunt.py ← 要る
├── candy_hunt.pyxres ← 要る
├── tempCodeRunnerFile.py ← 消す(VS Code の拡張が作った一時ファイル)
└── __pycache__/ ← 消さなくてよい(Pyxel が自動で除く)
リポジトリのいちばん上(step1 フォルダが見える場所)で実行します。
pyxel package step1 step1/candy_hunt.py
成功すると、追加されたファイルが 1 行ずつ表示され、
step1.pyxapp ができます。
ここに表示された一覧が、そのまま公開される中身です。目を通してください。
pyxel play step1.pyxapp
ブラウザにする前に、ここで必ず確かめます。
ここで動かなければ HTML にしても動きません。
とくに pyxel.load("candy_hunt.pyxres") のパスが合っているかは、
この段階で分かります。
pyxel app2html step1.pyxapp
step1.html ができます。
python -m http.server
そのまま http://localhost:8000/step1.html を開きます。
file:// という開き方になり、
ブラウザが wasm の読み込みを断ります。
必ず python -m http.server 経由(http://)で開いてください。
真っ黒のまま何も起きないときは、たいていこれです。
確かめること:
CLICK TO START をクリックしてタイトルが出るかEnter でやり直せるか
step1.html を docs/site/step1/candy_hunt.html という名前で置きます。
ファイル名がそのまま URL になるので、step1 ではなく作品名にします。
https://mrgarita.github.io/learning_pyxel/site/step1/candy_hunt.html
pyxel app2html は、リポジトリの直下に step1.html を作ります。
コピーで済ませると、直下にも 1 枚残ります。.gitignore にある step1/*.html は
step1 フォルダの中だけが対象なので、
直下の step1.html には効きません。
そのままにすると、git status に毎回顔を出します。
移動して、直下には残さないのがいちばん簡単です。
docs/site/step1/ には phase1.html 〜 phase10.html が並んでいます。
そこに作品の HTML を 1 枚足す形です。
step0 も docs/site/step0/star_voyager.html と、同じ置き方をしています。
app2html が出す HTML には、全画面にする仕組みが入っていません。
F11 も効きません(Pyxel がキー入力を横取りするため)。
ボタンを自分で足します。コードは備忘録の
Web に公開した Pyxel 作品を全画面にしたい にあります。
pyxel app2html はまっさらな HTML を上書き出力します。
手で足したボタンは毎回消えます。
ゲームを直して公開しなおすたびに、この作業が発生する——ということを覚えておいてください。
先に docs/site/step1/ へ置いてから、そこで足すと混乱しません。
2 か所です。step0 のときに作った並びに、1 行足す形になります。
docs/site/index.html)の「作品を公開しています」に
▶ Candy Hunt をブラウザでみる を足すdocs/site/step1/index.html)から、遊べる場所へ案内する
step1.pyxapp と step1.html はリポジトリの外に置いたままにします
(.gitignore に *.pyxapp を書いてあります)。
コミットするのは docs/ の中に置いたほうです。
push して数分待つと、公開 URL で遊べるようになります。
古い内容が出るときは Ctrl+F5 で強制再読み込みしてください。
公開まわりのトラブルは、step0 フェーズ 8 の一覧が そのまま使えます。ここではstep1 で新しく出るものだけ挙げます。
| 症状 | 見るところ |
|---|---|
| 公開した HTML に、身に覚えのないファイルが入っている | pyxel package はフォルダを丸ごと詰めます。
掃除してからパッケージ化しなおします |
CLICK TO START の前に音が鳴らない |
仕様です。ブラウザは、操作されていないページから音を出しません |
| クリックしたのに、まったく音が鳴らない | ① タブがミュートになっていないか(タブのスピーカーアイコン)。
② .pyxres を保存してからパッケージ化したか。
保存前の .pyxres を詰めていると、手元では鳴るのに Web で鳴りません |
| 矢印キーで動かない | ゲーム画面を 1 度クリックします。 ブラウザは、選ばれている場所にしかキー入力を送りません |
git status に step1.html が出てくる |
リポジトリ直下に残っています。docs/site/step1/ へ移動したか確認します
(.gitignore の step1/*.html は直下のファイルには効きません) |
| 全画面ボタンが消えた | app2html をやり直したためです。手で足し直します(3-7) |
| ゲームを直したのに、公開版が古いまま | package → app2html → 置きなおすの 3 つを全部やり直す必要があります。
.py を直しただけでは公開版は変わりません |
10 フェーズで、1 本のゲームが最後まで通りました。 身についたことを並べておきます。
| フェーズ | できるようになったこと |
|---|---|
| 1・2 | ドット絵を描いて動かす。絵はコードではなくエディタで作る |
| 3 | 当たり判定と乱数。関数に切り出して戻り値を返す |
| 4 | スコアの表示。数を覚えておく変数 |
| 5 | 追いかける動き。相対位置による場合分け |
| 6・7 | 画面遷移。状態を変数で持ち、処理を振り分ける |
| 8 | リストで複数を管理する。class の使いどころ |
| 9 | 音。チャンネルの割り当て、鳴らすタイミングの設計 |
| 10 | 公開。人に遊んでもらえる形にする |
4 に縮め、お化けの速さを動く回数で調整し、
出現時に点滅させ、音を重ならないように鳴らし分ける——
どれも「動く/動かない」ではなく、「気持ちいい/気持ちよくない」の調整です。
step1 で時間をかけたのは、ほとんどここでした。
step2 は「倉庫番」です。10 ステージ制とタイトル画面をつけます。 step1 と大きく変わるのは、次の 2 点です。
step1 で作った土台——シーンの切り替え、当たり判定、リストでの管理、音の鳴らし分け——は、 そのまま step2 でも使います。