🚂 運転士ぽいぽい開発日記 #4 ~枕木が3回も色を変えた日~

どうも~!鉄道星の神様(ただのおっさん)、4日目の活動報告である。

Stage 3でスコアシステムを実装し、「ゲームっぽいもの」が完成した。今回のStage 4では、「線路が線路に見えない問題」に挑戦し、枕木の色を3回も変えるという迷走っぷりを発揮。さらに内部構造を大改革し、ゲームフローも完成。そして気づいたらマップエディタの土台まで完成していた。我ながらどこに向かっているのか分からない開発だった。

🎯 Stage 4: 本格的なゲームへ(のはずだった)

今回実装したのは、「線路をそれっぽく見せる」という地味な作業…のはずが、いつの間にか壮大なリファクタリングと未来への布石まで完了していた。

【本日の成果物】

  • ✅ マップデータ構造実装(ノードベース線路システム)← 突然の大工事
  • ✅ 線路描画を枕木風に改良 ← 今日の主役のはずだった
  • ✅ HP回復速度調整(1秒で2HP)← 実は4HP/秒だった事件
  • ✅ タイトル画面・クリア画面・ゲームオーバー画面 ← ついでに完成
  • ✅ 目標スコア表示(+500でクリア、-300でゲームオーバー)
  • ✅ マップデータJSON化とローダー実装 ← 気づいたらできてた
  • ✅ 管理画面(マップエディタ準備)← なぜ作った

😅 開発中の珍事件簿

事件その1: 「線路が駅につながってない!」

開発者:「あれ?線路が駅の手前でプツッと途切れてる…浮いてる…?」

Claude:「駅ノードを全部スキップしてるからですね(真顔)」

開発者:「いや、駅は描画しないでしょ」

Claude:「駅『出口』からは線路を引かないと接続しませんよ」

開発者:「…ああああああ!!」

原因:「駅ノードはスキップ」という雑な実装。入口も出口も全部無視した結果、線路が駅に届かない謎空間が発生。

解決:駅出口ノードからは線路を描画。駅入口ノード(線路の終点)のみスキップに変更。

教訓:「全部スキップ」は思考停止。「何をスキップすべきか」を考えよう。

事件その2: 「枕木が黒い!木材なのに!」(3回変えた伝説)

第1ラウンド: グレーvs黒

開発者:「枕木をグレー(stroke: 80)にしたのに黒いんですけど…」

Claude:「前の描画設定が残ってますね。push/popで隔離しましょう」

原因:レールの黒色設定(stroke: 0)が枕木まで侵食。描画状態管理の失敗。

解決:push()/pop()で描画状態を保存・復元。これでグレーに…なったが。

第2ラウンド: グレーvs焦げ茶

開発者:「でもグレーって木材感ゼロだよね。焦げ茶(101, 67, 33)にしよう」

Claude:「いいですね」

(30秒後)

開発者:「…焦げ茶、黒と見分けつかなくない?」

Claude:「確かに」

第3ラウンド: 焦げ茶vs明るい茶色(決着)

開発者:「明るい茶色(139, 90, 43)にしたら完璧では?」

Claude:「それで行きましょう」

開発者:「やっと線路っぽくなった…!(感涙)」

教訓:描画の状態管理は重要。そして色選びはもっと重要。枕木の色だけで1時間溶けた。

事件その3: 「枕木の間隔が不均等!分岐の布石?」

開発者:「1マスに4本枕木があるけど、真ん中の間隔だけ広い…これ、将来の分岐用ブロック対応?」

Claude:「いえ、単なるバグです(断言)」

開発者:「えっ」

Claude:「ノードの両端を避けて枕木を配置してるので、ノード境界で間隔が空くんです」

開発者:「なるほど…じゃあ始点から描画して、終点は描画しない、にすれば?」

Claude:「それです!次のノードの始点で描画されるから重複しない」

開発者:「やった!等間隔になった!」

原因:for (let i = 1; i <= tieCount) で両端を避ける配置。ノード境界で間隔が空く。

解決:for (let i = 0; i < tieCount) で始点から配置。終点は次のノードが担当。

教訓:バグを「将来の機能の布石」と思い込むのはやめよう。ただのバグだ。

事件その4: 「HP回復が速すぎて無限HP爆誕」

開発者:「食堂で休憩してたら、HPがモリモリ回復してる…」

Claude:「0.5秒で2HP回復してますからね」

開発者:「え、設定は1秒で2HPのはず…」

Claude:「HP_RECOVERY_INTERVAL = 30フレーム = 0.5秒です。つまり実質4HP/秒」

開発者:「仕様書と実装が違うううう!

設定ミス:30フレーム(0.5秒)で2HP回復 → 1秒で4HP回復という超回復マシン爆誕。

修正:60フレーム(1秒)で2HP回復に変更。やっと仕様通りに。

教訓:数値設定は実際にプレイして確認すべき。仕様書を信じるな、実装を信じろ(逆では?)。

🏗️ 大規模リファクタリング: マップデータ構造(突然の大工事)

「線路をそれっぽく見せたい」という小さな願いから始まったはずが、なぜかマップデータ構造全体の大改革に発展した。

【変更前】

  • 駅・線路データがハードコード ← つらい
  • trackPoints配列で線路管理 ← 拡張性ゼロ
  • ステージ追加が困難 ← というか無理

【変更後】

  • ノードベース線路システム ← かっこいい
  • JSON形式でマップデータ管理 ← 拡張性∞
  • MapLoaderで動的読み込み ← プロっぽい
  • バリデーション機能付き ← 安心

これにより、ステージ2、3、4…と無限に追加可能になった!というか、そもそもステージ2を作りたかっただけなのに、なぜここまで…。

🎨 ゲームフロー完成(ついでに)

マップデータ構造の改革に夢中になっていたら、気づいたらゲームフローも完成していた。

【ゲームフロー】

  1. タイトル画面 – 「運転士ぽいぽい」ロゴ表示(将来は画像に差し替え予定)
  2. 待機画面 – ゲームスタートボタン(押さないと始まらない安心設計)
  3. プレイ中 – スコア目標表示、一時停止可能(今回追加:タイトルへ戻るボタン)
  4. クリア (+500点) – 次のステージへ / タイトルへ戻る
  5. ゲームオーバー (-300点) – 再チャレンジ / タイトルへ戻る

「一時停止画面にもタイトルへ戻るボタンが欲しい」という要望に即対応。いつでも逃げられる優しい設計になった。

🗺️ マップエディタへの第一歩(なぜ今日?)

「2面目を作りたい」→「マップビューアが必要」→「どうせならマップエディタ作ろう」→「基盤から整えよう」という典型的な機能膨張が発生。

【実装した基盤】

  • 📁 ディレクトリ構造設計(maps/official/ と maps/user/に分離)
  • 📄 stage1.jsonにマップデータを切り出し(16KB、いい感じ)
  • 🔧 MapLoaderクラス実装(読み込み、バリデーション、エクスポート機能付き)
  • 🎛️ 管理画面(admin/index.html)作成(なぜか完成度高い)

【将来の展望(妄想)】

  • Phase 1: マップエディタ(ドラッグ&ドロップで線路配置)
  • Phase 2: バリデーション(クリア可能性チェック、無限ループ検出)
  • Phase 3: オンライン機能(マップ共有、評価システム、ランキング)

ユーザーが自分でマップを作って共有できる未来が見えてきた!…が、そもそもステージ2を作りたかっただけなんだよな。

📊 今日の数字

  • 実装した関数: 15個以上(数えるの諦めた)
  • 修正したバグ: 7件(報告したくない事件多数)
  • 新規ファイル: 4個(JSON、ローダー、管理画面、設計書)
  • コード行数変更: 約500行(たぶん)
  • 枕木の色変更回数: 3回(グレー→焦げ茶→明るい茶色)← 今日のMVP
  • 予定外の大規模リファクタリング: 1回(なぜやった)

🎯 次回予告

次回はマップエディタ実装に着手…のはず。

  • グリッド上で駅・線路を配置
  • ドラッグ&ドロップで線路を引く
  • リアルタイムプレビュー
  • JSON形式でエクスポート

そして、マップエディタで作ったステージ2、3を実際にプレイできるようになる…予定。予定は未定だけど。

🙏 開発の感想

今回は「線路をそれっぽく見せる」という小さな目標から始まったはずが、

  • 🎨 枕木の色を3回変更(黒→グレー→焦げ茶→明るい茶色)
  • 🏗️ マップデータ構造を全面改革(なぜ)
  • 🎮 完全なゲームフローが完成(ついでに)
  • 🗺️ マップエディタの土台完成(予定外)

という壮大なスケールの作業になった。

「プロトタイプ」から「本格的なゲーム」へと進化した感じがする。そして何より、ユーザーが自分でマップを作れる未来が見えてきたのが最高にワクワクする!

…でも、そもそもステージ2を作りたかっただけなんだよなぁ(大事なことなので2回言った)。

次回こそマップエディタ!…たぶん!🚂✨


コメント

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です