007 ころがる切手 — Python / Pyxel 2.9.9

Windows: Python 3.10以降を用意し、setup.batを一度実行。以後play.bat。
macOS/Linux: bash setup.sh の後 bash play.sh。
開発環境では既存の ../../../pyxel_pilot/.venv も利用可能。
配布物に仮想環境は同梱しません。ネットワークは初回のPyxel導入だけに必要。

操作
方向キー / WASD: 紙を傾ける。離しても滑り、逆入力で制動。
P: 停止 / 続ける。R: 現在の面を初期状態へ即再開。
ESC: 面選択へ戻す（進行をリセット）。タイトルでA/D: 面選択、Space: 開始、Q: 終了。
クリア後N: 次の面、R: 同じ面。F12: media/manual_runtime.pngへ画面を保存。

3面
A: 一直線で封筒へ停止。壁に当てて戻る方法も有効。
B: 滑る直線から直角へ。角の先の赤枠・黒穴は常時見える。
   丸い台座は中心から4px未満・速度8px/s未満で登録。落下時は台座へ速度0で戻る。
C: 上の普通紙は安全。下は折り目と危険な角。距離は同じで、速さの差を選ぶ。
制限時間はありません。ゆっくり安全に進んでも通常クリアです。

実装・単位
論理遊び場192x128px、16pxタイル、丸い切手の当たり半径3px。
60回/秒の固定更新。位置px、速度px/s、加速度80px/s²、最大速度45px/s。
ドラッグ普通紙3/s、折り目平行0.6/s、垂直6/s。指数減衰と定加速度の解を毎更新に使用。
斜め加速度は正規化。軸別壁解決で法線速度だけ0。移動は最大0.75pxの小刻み判定。
穴は描画した黒い12x12pxの内部へ中心が入ると落下。赤枠は警告で穴判定外。
封筒の中心±4pxに切手中心が入り、速度8px/s未満を18更新続けると封が閉じます。
これは中心基準の配送判定で、切手全体が封筒の絵に完全内包される判定ではありません。
「経過」は更新回数/60。停止中・結果中は増えません。実際の壁時計時間とは区別しています。

検証
python -m unittest -v
python experiment.py
python tools/test_portability.py （Pyxel導入済みPythonで実行）
python app.py --baseline （同じ面の折り目だけ普通紙へ戻す比較）
python app.py --headless --demo （25秒分の固定更新・実Pyxel描画GIFを作成）
18 tests。test_results.txt / experiment_results.json / portability_results.txt参照。
CP932を暗黙既定とするPath I/O模擬、日本語＋空白パス、無関係CWDの読み込みを検査。
Windows実機のバッチ・音・画面は未検証。ゲームは音を使いません。
日本語字形はNoto Sans CJK由来の必要文字のみ。assets/NOTO-LICENSE.txt (SIL OFL 1.1)。
コードはLICENSE.txt (MIT)。依存Pyxelのライセンスは配布元に従います。

媒体
media/rolling_automatic_demo.gif: 再生29.96秒、25秒分の固定更新、自動の方向入力。画面にも自動操作と表示。
media/runtime_*.png: 同じ実行のPyxel画面。media/manual_runtime.png: native GUI試験のF12。
人の試遊・楽しさ確認は未実施。MANUAL_QA.txtとNOTE_JA.txtに確認範囲と未知を分離。

GIFは10ms刻みのため60Hzの各画像が20msとなり、再生は29.96秒です。
表示されるゲーム時間は60Hzの固定更新基準で、GIF再生時間とは異なります。
