リクエスト詳細
✨ 既存アプリの改善
対応完了
対象アプリ: RPGストーリーフォージ AI風ドット絵冒険
Canvas描画のオフスクリーンバッファ化とdirty-flag管理によるマップ・戦闘の体感速度向上
1. 目的
これまでサーバー側(APCu, セッションバッファ, gzip, WebP配信, 永続接続, タイル差分配信など)の高速化は実施済みだが、ブラウザ側のCanvas描画処理自体はまだ最適化されていない。マップ移動時や戦闘突入時に毎フレーム全タイル・全スプライトを再描画しているため、特にスマホ端末で描画コストがボトルネックになりやすい。本改善ではフロントエンドJSの描画パイプラインを最適化し、体感速度をさらに向上させる。
2. 具体的仕様
(a) タイルレイヤーのオフスクリーンキャッシュ化:
- ワールドマップ/サブマップの描画で、既存の可視タイルを保持する専用のオフスクリーンCanvas(OffscreenCanvasが使えない環境は通常canvasで代替)を1枚用意する。
- プレイヤー移動時は、ビューポート原点の差分(dx, dy)分だけこのオフスクリーンCanvasをdrawImageで自己コピー(スクロール)し、新規に見える行・列だけを再描画する「スクロールバッファ方式」に変更する。既存のタイル差分APIレスポンス(新規タイルのみ返す仕様)とJS側の描画ロジックを対応させる。
- 表示用メインCanvasへは、このオフスクリーンキャンバス全体を1回のdrawImageで転写するだけにする(毎フレーム個別タイル再描画をなくす)。
(b) dirty-flagによる再描画スロットリング:
- 移動・アニメーション・天候演出などが同一フレーム内で複数回描画要求を出す場合、`needsRedraw`フラグを立てるだけにし、requestAnimationFrame内で1フレームにつき1回だけ実際の描画関数を呼ぶよう統一する。
- スマホの連続タップ操作でも、実描画は最大60fps相当に制限され、無駄な再描画呼び出しを削減する。
(c) 画像デコードの事前完了化:
- モンスター・戦闘背景・アイコン画像の読み込み時、`new Image()`のonloadを待つ現行方式に加え、`createImageBitmap()`が利用可能な場合はそれを使い、デコード済みImageBitmapをMapオブジェクトにキャッシュする。戦闘突入・マップ切替時に初回描画のデコード待ちで発生するカクつき(ジャンク)を軽減する。
- createImageBitmap非対応ブラウザでは従来のImageオブジェクト方式にフォールバックする。
3. 既存機能との整合
- サーバー側API(タイル差分配信、遭遇プリフェッチ、WebP変換、Ajaxバッファ等)の仕様・レスポンス形式は変更しない。純粋にクライアントJSの描画処理内部の実装を差し替えるのみ。
- 見た目・操作感・アニメーション内容は変更せず、既存のCanvas描画結果と視覚的に同一になるようにする(スクロールバッファのコピー元となる座標計算を既存のビューポート原点ロジックと一致させる)。
- createImageBitmap非対応環境向けのフォールバックを用意し、古いブラウザやスマホでも従来通り動作することを保証する。
- ミニマップ、戦闘画面のスプライトアニメーション、天候演出など既存の描画呼び出し箇所は、共通の`requestRedraw()`ヘルパー経由に置き換えるのみで、描画内容自体のロジックは変更しない。
これまでサーバー側(APCu, セッションバッファ, gzip, WebP配信, 永続接続, タイル差分配信など)の高速化は実施済みだが、ブラウザ側のCanvas描画処理自体はまだ最適化されていない。マップ移動時や戦闘突入時に毎フレーム全タイル・全スプライトを再描画しているため、特にスマホ端末で描画コストがボトルネックになりやすい。本改善ではフロントエンドJSの描画パイプラインを最適化し、体感速度をさらに向上させる。
2. 具体的仕様
(a) タイルレイヤーのオフスクリーンキャッシュ化:
- ワールドマップ/サブマップの描画で、既存の可視タイルを保持する専用のオフスクリーンCanvas(OffscreenCanvasが使えない環境は通常canvasで代替)を1枚用意する。
- プレイヤー移動時は、ビューポート原点の差分(dx, dy)分だけこのオフスクリーンCanvasをdrawImageで自己コピー(スクロール)し、新規に見える行・列だけを再描画する「スクロールバッファ方式」に変更する。既存のタイル差分APIレスポンス(新規タイルのみ返す仕様)とJS側の描画ロジックを対応させる。
- 表示用メインCanvasへは、このオフスクリーンキャンバス全体を1回のdrawImageで転写するだけにする(毎フレーム個別タイル再描画をなくす)。
(b) dirty-flagによる再描画スロットリング:
- 移動・アニメーション・天候演出などが同一フレーム内で複数回描画要求を出す場合、`needsRedraw`フラグを立てるだけにし、requestAnimationFrame内で1フレームにつき1回だけ実際の描画関数を呼ぶよう統一する。
- スマホの連続タップ操作でも、実描画は最大60fps相当に制限され、無駄な再描画呼び出しを削減する。
(c) 画像デコードの事前完了化:
- モンスター・戦闘背景・アイコン画像の読み込み時、`new Image()`のonloadを待つ現行方式に加え、`createImageBitmap()`が利用可能な場合はそれを使い、デコード済みImageBitmapをMapオブジェクトにキャッシュする。戦闘突入・マップ切替時に初回描画のデコード待ちで発生するカクつき(ジャンク)を軽減する。
- createImageBitmap非対応ブラウザでは従来のImageオブジェクト方式にフォールバックする。
3. 既存機能との整合
- サーバー側API(タイル差分配信、遭遇プリフェッチ、WebP変換、Ajaxバッファ等)の仕様・レスポンス形式は変更しない。純粋にクライアントJSの描画処理内部の実装を差し替えるのみ。
- 見た目・操作感・アニメーション内容は変更せず、既存のCanvas描画結果と視覚的に同一になるようにする(スクロールバッファのコピー元となる座標計算を既存のビューポート原点ロジックと一致させる)。
- createImageBitmap非対応環境向けのフォールバックを用意し、古いブラウザやスマホでも従来通り動作することを保証する。
- ミニマップ、戦闘画面のスプライトアニメーション、天候演出など既存の描画呼び出し箇所は、共通の`requestRedraw()`ヘルパー経由に置き換えるのみで、描画内容自体のロジックは変更しない。
💬 返信 (3)
🛠 開発を開始しました (機能追加 (rpg-story-forge))
ご要望ありがとうございます。AI 開発ワーカーが実装を開始します。
通常 5〜30 分で Pull Request を作成し、レビュー後にリリースされます。
ご要望ありがとうございます。AI 開発ワーカーが実装を開始します。
通常 5〜30 分で Pull Request を作成し、レビュー後にリリースされます。
📝 開発が完了しました
ご要望いただいた内容の実装が完了し、最終チェック段階に入りました。
レビュー (自動) → リリース、の流れで進みます。
もう少々お待ちください。
ご要望いただいた内容の実装が完了し、最終チェック段階に入りました。
レビュー (自動) → リリース、の流れで進みます。
もう少々お待ちください。
✅ リリース完了のお知らせ
ご要望いただいた「RPGストーリーフォージ AI風ドット絵冒険」を実装し、リリースいたしました。
【ご利用方法】
ダッシュボード: https://www.aiapps.jp/?action=dashboard
アプリ詳細: https://www.aiapps.jp/apps/show.php?slug=rpg-story-forge
デモ環境は 1 時間以内に自動構築されます:
https://www.aiapps.jp/demo/rpg-story-forge/
ご利用ありがとうございます!
ご要望いただいた「RPGストーリーフォージ AI風ドット絵冒険」を実装し、リリースいたしました。
【ご利用方法】
ダッシュボード: https://www.aiapps.jp/?action=dashboard
アプリ詳細: https://www.aiapps.jp/apps/show.php?slug=rpg-story-forge
デモ環境は 1 時間以内に自動構築されます:
https://www.aiapps.jp/demo/rpg-story-forge/
ご利用ありがとうございます!
Echo
Iris