# 画面設計書 44-タイルマップエディタ

## 概要

本ドキュメントは、Godot Engineエディタにおけるタイルマップエディタ（TileMapEditorPlugin / TileSetEditorPlugin）の画面設計書である。TileMapLayerおよびTileSetリソースを編集するための画面仕様を定義する。

### 本画面の処理概要

タイルマップエディタは、2Dゲームのタイルベースのマップ作成を支援するエディタである。TileSetリソース（タイルの定義）とTileMapLayer（タイルの配置）の2つの要素を統合的に編集できる。ペイント、ライン、矩形、バケットなど複数の描画ツールを提供し、効率的なマップ作成を可能にする。

**業務上の目的・背景**：2Dゲーム開発において、タイルベースのマップ作成は最も一般的な手法である。本エディタは、タイルセットの作成からマップへの配置まで、一連のワークフローを直感的に行えるよう設計されている。アトラスソースのサポートにより、大規模なタイルセットも効率的に管理できる。パターン機能により、繰り返し使用する構造物を簡単に配置できる。

**画面へのアクセス方法**：シーン内のTileMapまたはTileMapLayerノードを選択すると、エディタ下部のドックパネルにタイルマップエディタが表示される。TileSetリソースをダブルクリックするとTileSetエディタが表示される。

**主要な操作・処理内容**：
1. タイル選択：TileSetからペイントするタイルを選択
2. ペイント：キャンバス上にタイルを描画
3. ライン描画：直線状にタイルを配置
4. 矩形描画：矩形領域にタイルを配置
5. バケット塗り：連続領域を一括でタイル配置
6. 消しゴム：配置されたタイルを削除
7. ピッカー：キャンバス上のタイルを選択
8. レイヤー選択：複数レイヤーがある場合に編集対象を切り替え
9. TileSet編集：タイルの物理形状、ナビゲーション、カスタムデータを設定

**画面遷移**：TileMapLayerノード選択時にTileMapLayerEditorが表示され、関連するTileSetがあればTileSetEditorも連動して表示される。

**権限による表示制御**：エディタ機能のため、特定の権限制御は存在しない。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| F-044 | タイルマップ編集 | 主機能 | TileMapLayerのタイル配置 |
| - | TileSetEditor | 補助機能 | TileSetリソースの編集 |
| - | TileMapLayerEditor | 補助機能 | TileMapLayerの編集 |
| - | TilesEditorUtils | 補助機能 | パターンプレビュー、ソース同期 |
| - | EditorUndoRedoManager | 補助機能 | 編集操作のUndo/Redo対応 |
| - | CanvasItemEditor | 補助機能 | 2Dビューポートでの描画・入力処理 |

## 画面種別

ドックパネル + キャンバスオーバーレイ（エディタプラグイン）

## URL/ルーティング

該当なし（エディタプラグインとして実装）

## 入出力項目

### 入力項目

| 項目名 | 項目ID | データ型 | 必須 | 入力形式 | バリデーション | 説明 |
|--------|--------|----------|------|----------|----------------|------|
| TileMapLayer | tile_map_layer | TileMapLayer* | 必須 | ノード参照 | 有効なTileMapLayer | 編集対象のタイルマップレイヤー |
| TileSet | tile_set | Ref<TileSet> | 必須 | リソース参照 | 有効なTileSet | 使用するタイルセット |

### 出力項目

| 項目名 | データ型 | 説明 |
|--------|----------|------|
| 編集済みTileMapLayer | TileMapLayer* | タイル配置が更新されたレイヤー |
| 編集済みTileSet | Ref<TileSet> | タイル定義が更新されたリソース |

## 表示項目

### TileMapLayerEditorツールバー

| 項目名 | 項目ID | データ型 | 説明 |
|--------|--------|----------|------|
| レイヤーセレクタ | - | OptionButton | 編集対象レイヤーの選択 |
| ペイントツール | - | Button | ペイントモード切替（D キー） |
| ラインツール | - | Button | ライン描画モード切替（L キー） |
| 矩形ツール | - | Button | 矩形描画モード切替（R キー） |
| バケットツール | - | Button | バケット塗りモード切替（B キー） |
| 消しゴムツール | - | Button | 消しゴムモード切替（E キー） |
| ピッカーツール | - | Button | タイルピッカーモード切替（P キー） |

### TileSetソースリスト

| 項目名 | 項目ID | データ型 | 説明 |
|--------|--------|----------|------|
| ソースリスト | - | TileSetSourceItemList | タイルソース一覧 |
| ソートボタン | - | MenuButton | ソース並び替えオプション |

### TileAtlasView

| 項目名 | 項目ID | データ型 | 説明 |
|--------|--------|----------|------|
| アトラスビュー | - | TileAtlasView | タイルアトラスの表示・選択エリア |
| ズームスライダー | - | - | 表示倍率調整 |

### TileSetEditorパネル

| 項目名 | 項目ID | データ型 | 説明 |
|--------|--------|----------|------|
| タブコンテナ | - | TabContainer | 編集モードタブ（Tiles/Terrain等） |
| プロパティエディタ | - | - | 選択タイルのプロパティ編集 |

## イベント仕様

### 1-タイル選択イベント

**トリガー**: TileAtlasViewでのタイルクリック

**処理内容**:
1. 選択されたタイル座標を取得
2. ペイント用のタイルデータを設定
3. 選択表示を更新

**関連メソッド**: TileAtlasView内の選択処理

### 2-ペイントイベント

**トリガー**: キャンバス上でのマウスドラッグ（ペイントモード時）

**処理内容**:
1. マウス位置をタイル座標に変換
2. 選択タイルをそのセルに配置
3. Undo/Redoアクションを記録
4. キャンバスを再描画

**関連メソッド**: `forward_canvas_gui_input()` (L490-491)

### 3-ライン描画イベント

**トリガー**: キャンバス上でのドラッグ開始〜終了（ラインモード時）

**処理内容**:
1. 始点を記録
2. ドラッグ中はプレビューを表示
3. ドラッグ終了時に始点〜終点間の全セルにタイルを配置

**関連メソッド**: TileMapLayerEditor内のライン処理

### 4-バケット塗りイベント

**トリガー**: キャンバス上でのクリック（バケットモード時）

**処理内容**:
1. クリック位置のセルを取得
2. 同じタイルまたは空セルの連続領域を検索
3. 全該当セルに選択タイルを配置
4. Undo/Redoアクションを記録

**関連メソッド**: TileMapLayerEditor内のバケット処理

### 5-レイヤー変更イベント

**トリガー**: レイヤーセレクタの選択変更

**処理内容**:
1. 新しいレイヤーを編集対象に設定
2. エディタを更新
3. TileSetも必要に応じて切り替え

**関連メソッド**: `_select_layer()` (L388-397)

### 6-TileSet変更検知イベント

**トリガー**: TileMapLayerのchangedシグナル

**処理内容**:
1. 変更フラグを設定
2. 遅延呼び出しで_update_tile_map()を実行
3. TileSetが変更されていれば再編集

**関連メソッド**: `_tile_map_layer_changed()` (L355-361), `_update_tile_map()` (L371-386)

### 7-ソースリストソートイベント

**トリガー**: ソートメニューでのオプション選択

**処理内容**:
1. ソートオプションを設定（ID/ID逆順/名前/名前逆順）
2. ソースリストを再ソート
3. リスト表示を更新

**関連メソッド**: `set_sorting_option()` (L201-203), `get_sorted_sources()` (L205-231)

### 8-パターンプレビュー生成イベント

**トリガー**: queue_pattern_preview()呼び出し

**処理内容**:
1. プレビューキューにアイテムを追加
2. バックグラウンドスレッドでSubViewportを使用してレンダリング
3. コールバックでImageTextureを返却

**関連メソッド**: `queue_pattern_preview()` (L145-153), `_thread()` (L71-143)

## データベース更新仕様

### 操作別データベース影響一覧

本画面はデータベースを使用せず、シーンファイル（.tscn）内のTileMapLayerデータおよびTileSetリソース（.tres）を更新する。

| 操作（イベント） | 対象データ | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| タイル配置 | TileMapLayer.cells | INSERT/UPDATE | セルにタイルを配置 |
| タイル削除 | TileMapLayer.cells | DELETE | セルからタイルを削除 |
| TileSetソース追加 | TileSet.sources | INSERT | アトラスソースを追加 |
| TileSetソース削除 | TileSet.sources | DELETE | アトラスソースを削除 |
| タイルプロパティ変更 | TileSetAtlasSource.tiles | UPDATE | タイルの物理・カスタムデータを更新 |

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|-------------|------|---------------|----------|
| - | ショートカット | "Paint Tool" | D キー |
| - | ショートカット | "Line Tool" | L キー |
| - | ショートカット | "Rect Tool" | R キー |
| - | ショートカット | "Bucket Tool" | B キー |
| - | ショートカット | "Eraser Tool" | E キー |
| - | ショートカット | "Picker Tool" | P キー |
| - | ショートカット | "Cut" | Ctrl+X |
| - | ショートカット | "Copy" | Ctrl+C |
| - | ショートカット | "Paste" | Ctrl+V |
| - | ショートカット | "Cancel" | Escape |
| - | ショートカット | "Delete" | Delete |
| - | ツールチップ | "Source ID: %d" | ソースリストホバー時 |
| - | ツールチップ | "Source ID: %d\nTexture path: %s" | アトラスソースホバー時 |

## 例外処理

| 例外条件 | 処理内容 |
|---------|----------|
| TileSetがnull | TileSetEditorを非表示、編集不可 |
| TileMapLayerノード削除 | _tile_map_layer_removed()で親TileMapを再編集 |
| レイヤー数0のTileMap | エディタを非表示、レイヤーセレクタを非表示 |
| パターンプレビュースレッド終了 | pattern_thread_exit設定、スレッド終了待機 |

## 備考

- TilesEditorUtilsはシングルトンとして実装され、複数エディタ間でのソース同期を担当
- パターンプレビューはバックグラウンドスレッドで生成され、UIブロッキングを回避
- TileSetSourceItemListのアイコンサイズは60x60ピクセル（エディタスケール適用後）
- ソースリストのソートは4種類：ID順、ID逆順、名前順、名前逆順
- 最小サイズは200ピクセル（エディタスケール適用後）

---

## コードリーディングガイド

本画面を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

TileSetとTileMapLayerの関係を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | tile_set.h | `scene/resources/2d/tile_set.h` | TileSet、TileSetSource、TileSetAtlasSourceクラス |
| 1-2 | tile_map_layer.h | `scene/2d/tile_map_layer.h` | TileMapLayerクラス、CellData構造体 |
| 1-3 | tiles_editor_plugin.h | `editor/scene/2d/tiles/tiles_editor_plugin.h` | TilesEditorUtils、SourceSortOption |

**読解のコツ**: TileSetはソースの集合を管理し、各ソース（主にTileSetAtlasSource）が実際のタイル定義を持つ。TileMapLayerはセルとタイルの対応を管理する。

#### Step 2: プラグイン構造を理解する

エディタプラグインの構成を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | tiles_editor_plugin.h | `editor/scene/2d/tiles/tiles_editor_plugin.h` | TileMapEditorPlugin、TileSetEditorPlugin |
| 2-2 | tiles_editor_plugin.cpp | `editor/scene/2d/tiles/tiles_editor_plugin.cpp` | コンストラクタ（L502-516, L551-565） |

**主要処理フロー**:
1. **L502-516**: TileMapEditorPluginコンストラクタでTileMapLayerEditorを作成
2. **L551-565**: TileSetEditorPluginコンストラクタでTileSetEditorを作成
3. **L297-314**: TilesEditorUtilsコンストラクタでショートカット登録

#### Step 3: 編集操作を理解する

タイル配置とキャンバス入力処理を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | tiles_editor_plugin.cpp | `editor/scene/2d/tiles/tiles_editor_plugin.cpp` | forward_canvas_gui_input()（L490-491） |
| 3-2 | tile_map_layer_editor.h | `editor/scene/2d/tiles/tile_map_layer_editor.h` | TileMapLayerEditorクラス |

**主要処理フロー**:
- forward_canvas_gui_input()でキャンバス入力をエディタに転送
- forward_canvas_draw_over_viewport()でオーバーレイ描画

#### Step 4: パターンプレビューを理解する

バックグラウンドスレッドでのプレビュー生成を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | tiles_editor_plugin.cpp | `editor/scene/2d/tiles/tiles_editor_plugin.cpp` | _thread()（L71-143）、queue_pattern_preview()（L145-153） |

**主要処理フロー**:
- **L71-143**: バックグラウンドスレッドでSubViewportを使用したレンダリング
- **L88-139**: TileMapLayerを作成しパターンを設定、ImageTextureを生成
- **L145-153**: キュー追加とセマフォでのスレッド起床

### プログラム呼び出し階層図

```
TileMapEditorPlugin::edit()
    │
    ├─ TileMap選択時
    │      └─ _edit_tile_map()
    │             └─ _edit_tile_map_layer() [最初のレイヤー]
    │
    └─ TileMapLayer選択時
           └─ _edit_tile_map_layer()
                  ├─ editor->edit(p_tile_map_layer)
                  ├─ changedシグナル接続
                  │      └─ _tile_map_layer_changed()
                  │             └─ _update_tile_map() [遅延呼び出し]
                  │
                  └─ tile_set_plugin_singleton->edit(tile_set)
                         └─ TileSetEditor::edit()

forward_canvas_gui_input()
    └─ editor->forward_canvas_gui_input()
           └─ TileMapLayerEditor入力処理
                  ├─ ペイント処理
                  ├─ ライン処理
                  ├─ 矩形処理
                  └─ バケット処理

TilesEditorUtils::queue_pattern_preview()
    ├─ キューに追加
    └─ セマフォpost
           └─ _thread() [バックグラウンド]
                  ├─ SubViewport作成
                  ├─ TileMapLayer作成・パターン設定
                  ├─ レンダリング待機
                  └─ callback.call(pattern, texture)
```

### データフロー図

```
[入力]                          [処理]                              [出力]

TileMapLayer選択          ─────▶ edit()                      ─────▶ TileMapLayerEditor表示
                                 └─ _edit_tile_map_layer()          TileSetEditor表示

キャンバス入力            ─────▶ forward_canvas_gui_input()  ─────▶ タイル配置
  - マウスドラッグ               └─ TileMapLayerEditor処理           Undo/Redoアクション
  - クリック

TileMapPattern            ─────▶ queue_pattern_preview()     ─────▶ ImageTexture
                                 └─ _thread() [バックグラウンド]      └─ callback呼び出し

ソート設定                ─────▶ get_sorted_sources()        ─────▶ ソート済みソースリスト
  - ID/名前                      └─ SourceNameComparator
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| tiles_editor_plugin.cpp | `editor/scene/2d/tiles/tiles_editor_plugin.cpp` | ソース | メインプラグイン実装 |
| tiles_editor_plugin.h | `editor/scene/2d/tiles/tiles_editor_plugin.h` | ヘッダ | プラグインクラス定義 |
| tile_map_layer_editor.cpp | `editor/scene/2d/tiles/tile_map_layer_editor.cpp` | ソース | TileMapLayerエディタ実装 |
| tile_map_layer_editor.h | `editor/scene/2d/tiles/tile_map_layer_editor.h` | ヘッダ | TileMapLayerエディタ定義 |
| tile_set_editor.cpp | `editor/scene/2d/tiles/tile_set_editor.cpp` | ソース | TileSetエディタ実装 |
| tile_set_editor.h | `editor/scene/2d/tiles/tile_set_editor.h` | ヘッダ | TileSetエディタ定義 |
| tile_atlas_view.cpp | `editor/scene/2d/tiles/tile_atlas_view.cpp` | ソース | アトラスビュー実装 |
| tile_set.cpp | `scene/resources/2d/tile_set.cpp` | ソース | TileSetリソース実装 |
| tile_map_layer.cpp | `scene/2d/tile_map_layer.cpp` | ソース | TileMapLayerノード実装 |
| tile_map.cpp | `scene/2d/tile_map.cpp` | ソース | TileMapノード実装（レイヤーコンテナ） |
| editor_undo_redo_manager.cpp | `editor/editor_undo_redo_manager.cpp` | ソース | Undo/Redo管理 |
