012 ゴムひもの山歩き / 5段階の独立Pyxel教材

必要：Python 3.11以上、Pyxel 2.9.9、デスクトップで表示できる環境。
仮想環境内のPythonを使います。初回のpipインストールだけネット接続が必要です。
このフォルダーを展開して使います。最初にLESSON.mdを読むと、物理・操作・原作との差が分かります。
ゲーム画面はASCII、解説は日本語です。追加画像・日本語フォント・原作ファイルは実行に不要です。
各01〜05.pyは1本だけ別フォルダーへコピーしても起動できます。

Windows（PowerShellまたはコマンドプロンプト）
1. このフォルダーを開いたターミナルでPythonのバージョンを確認：
   py -3 --version
   3.11未満ならPython公式配布の3.11以上を用意してください。
2. 仮想環境を作り、この環境へだけインストール：
   py -3 -m venv .venv
   .venv\Scripts\python.exe -m pip install -r requirements.txt
3. 実行（Activateスクリプトの実行許可を変える必要はありません）：
   .venv\Scripts\python.exe -B 01_motion.py
   .venv\Scripts\python.exe -B 02_spring.py
   .venv\Scripts\python.exe -B 03_reel_release.py
   .venv\Scripts\python.exe -B 04_collision.py
   .venv\Scripts\python.exe -B 05_summit.py
4. 学習テスト：
   .venv\Scripts\python.exe -B test_stages.py

macOS / Linux（ターミナル）
1. このフォルダーへ移動します。空白を含むパスは引用符で囲みます：
   cd "/path/to/012_rope_hike"
   python3 --version
2. Python 3.11以上を確認して仮想環境を作成：
   python3 -m venv .venv
   .venv/bin/python -m pip install -r requirements.txt
3. 01から順に実行：
   .venv/bin/python -B 01_motion.py
   .venv/bin/python -B 02_spring.py
   .venv/bin/python -B 03_reel_release.py
   .venv/bin/python -B 04_collision.py
   .venv/bin/python -B 05_summit.py
4. 学習テスト：
   .venv/bin/python -B test_stages.py
Linuxでvenvが利用できない場合は、利用している配布版の公式手順でpython3-venvを用意してください。

本文の「python」は、上記の.venv内Pythonに読み替えます。
既に仮想環境をactivateしてあれば短いpythonコマンドでも構いません。

操作
左右：歩く。空中では少しだけ進路調整。
Space：接続／切離し（02以降）。押し直しで1回。保持では切り替わり続けません。
上下：接続中の自然長を短く／長く（03以降）。14〜42、毎秒12px。
Z：開始棚へ戻る（04）、最後に休んだ棚へ戻る（05）。落下数は増えません。
A/D：杭選択（05）。枠で選んだ杭が明るければ接続可能です。
P：停止／再開。再開時に同時押ししたSpaceは無視し、一度離して押し直します。
R：最初から。停止中も使えます。Esc：Pyxel標準の終了。
05では旗の棚でひもを離し、横移動せず0.25秒以上休めばSUMMIT!。
到着後はRでやり直します。制限時間はありません。

各段階
01_motion.py：位置・速度・加速度。広い床へ落ちる簡略練習。
02_spring.py：距離・向き・張力。自然長38固定。ひもを離すと勢いが残る。
03_reel_release.py：巻取り。接続中だけ自然長を変更。
04_collision.py：原作の膨張矩形と線分掃引。向こう岸への着地練習。終了条件なし。
05_summit.py：原作ルート3、中棚・2杭・チェックポイント・到着。原作の全UIではありません。

決まった操作を実行し、実Pyxelで画像と記録を保存する例
python -B 05_summit.py --headless-replay qa/05_summit_inputs.json --screenshot summit.png --report summit.json
初期状態だけの画像：
python -B 01_motion.py --headless-smoke --screenshot initial.png --report initial.json
初期smokeは状態を更新せず12フレーム描画します。ゲームの通常実行では時間が進みます。
全描画・単独ファイルQA再実行：python -B run_qa.py（数十秒、qa成果を上書き）
モデル・Controllerテスト：python -B test_stages.py（Pyxel不要、標準ライブラリのみ）

原作との任意の直接比較
PowerShell：$env:ORIGINAL_012_DIR="C:\path\to\games\012_rope_hike"
cmd：set "ORIGINAL_012_DIR=C:\path\to\games\012_rope_hike"
macOS/Linux：ORIGINAL_012_DIR="/path/to/games/012_rope_hike" python -B test_stages.py
Windowsは指定後にpython -B test_stages.pyを実行します。
原作を指定しなくても付属canonical_reference.jsonによる一致検証は動きます。
未指定なら外部原作の任意比較1件のみSKIPです。通常の教材試験は省略しません。

よくあるエラー
・No module named pyxel：インストールと実行のPythonが違わないか確認。
  .venv内Python -m pip show pyxelで2.9.9を確認します。
・python/pyが見つからない：Python 3.11以上を用意し、ターミナルを開き直します。
・can't open file：展開フォルダーへcdしたか確認。パスに空白があれば引用符を使います。
・ウィンドウが開かない／Display関連エラー：デスクトップ表示のあるセッションで試します。
  --headless-smokeは描画検証用で、操作用ウィンドウは開きません。
・SPACEでつながらない：02以降か、距離68以内か、04以降では岩が遮っていないか確認。
  05で違う杭を選んでいればA/Dを使います。停止・初期化後は一度Spaceを放します。
・ひもが止まった：04/05でROPE BLOCKEDならZで復帰。巻付き計算はありません。
・棚に乗っても終わらない：04は練習です。05では旗棚・ひも未接続・静止・休憩が必要。
・Replayエラー：UTF-8のJSON配列、heldとpressedの対応、対応キーの大文字表記を確認。
・pipが通信に失敗：接続・社内の公式設定を確認し、成功後に起動します。検証なしで通ったとは扱いません。

ライセンスと検証
LICENSEは原作のMIT通知全文です。全配布Pythonにも同じ通知を保持しています。
原作通知末尾のNoto/OFLは原作に同梱の字形を指します。この教材には字形を含めていません。
図形とプログラムは原作由来のMIT、追加の独自権利表示は作っていません。
QA.txtとqaに教材のテスト、PNG、入力、原作由来fixture、出典hash、凍結manifestを同梱。
実施：cloud Linuxの実Pyxel headless・合成入力・標準Pythonテスト・日本語と空白のパスで単独起動。
未実施：人の試遊、OSキーイベント、実Windows/macOS GUI、ブラウザ操作、音声出力確認。
Python 3.11以上を仕様とし、今回の実行環境はPython 3.12.14です。音源は実装していません。
これは登山・ロープ安全の教材ではありません。

権利表記の補足: 教材にはNoto由来の字形データを含みません。原作LICENSEからの参照を辿れるよう、原文のSIL OFLをassets/NOTO-LICENSE.txtに文書だけ同梱しています。
