---
name: camera_controller_3d.aicomponent
description: 3D 相机控制器，专为棋盘/拼图类游戏设计。支持自动棋盘俯瞰、平滑过渡、屏幕震动、多种视角模式。
triggers: 需要在 Three.js 3D 场景中管理相机位置/角度/视锥，或需要棋盘俯瞰/震动/过渡动画时触发。
---

# 3D 相机控制器（3D Camera Controller）

## 说明

本 skill 是 Three.js 3D 项目独有的组件（2D Phaser 无等价概念）。提供棋盘类游戏所需的相机管理：

- **自动棋盘俯瞰**：根据 rows/cols/cellSize 计算最优相机位置，确保棋盘完整可见
- **视角模式**：top-down-fixed / isometric-45 / orbit-debug
- **屏幕震动**：推出失败/阻挡时的反馈
- **平滑过渡**：关卡切换时的相机动画

## Scaffold

| 目标路径 | 来源 | 说明 |
|---------|-----|------|
| `src/game/utils/CameraController.ts` | `ref/CameraController.ts` | 相机控制器 |

## Imports

- `threejs.aicomponent`（硬依赖）

## Recipe

| 决策 | 原因 |
|------|------|
| **setupForBoard 自动计算** | 手动计算相机距离以使棋盘完整可见涉及 FOV + 三角函数；封装成一次调用，消除每个关卡都需要手动调参的工作 |
| **震动在原始位置叠加随机偏移** | 不修改 base position，震动结束后自然回到原位；避免震动后相机位移的 bug |
| **`update()` 每帧调用模式** | 使用 lerp/smoothstep 实现过渡动画，需要每帧推进；比 Tween 库更可控，支持动画途中中断或叠加 |
| **orbit-debug 模式** | 开发时可自由旋转检查 3D 场景；`enableOrbitControls: false` 从 `threejs.aicomponent` 主配置关闭不影响此控制器 |

## Adapter

- **Role**: `cameraController3D` — Three.js 棋盘俯瞰相机控制器（自动定位 + 震动 + 过渡动画）
- **Provides**: `CameraController` 类（`setupForBoard()`、`shake()`、`transitionTo()`、`update(dt)`）
- **Requires**: `threejs.aicomponent`（THREE.Camera API）
- **Consumed by**: 3D 模式的 `game_scene.aicomponent` 或自定义 BaseScene 子类（在 `onInit()` 初始化，`onUpdate()` 中每帧调用 `update(dt)`）
- **Integration point**: `src/game/utils/CameraController.ts` → BaseScene 子类的 `protected onInit()` 中实例化

## 使用示例

```typescript
import { CameraController } from "../utils/CameraController";
import * as THREE from "three";

// 在 BaseScene 子类中
protected onInit(): void {
  this.cameraCtrl = new CameraController(this._camera!, "top-down-fixed");

  // 自动定位相机使棋盘完整可见
  this.cameraCtrl.setupForBoard(level.rows, level.cols, cellSize);
}

// 推出失败时震动
this.cameraCtrl.shake(0.15, 300);

// 关卡切换过渡
this.cameraCtrl.transitionTo(
  new THREE.Vector3(newX, newY, newZ),
  new THREE.Vector3(lookX, 0, lookZ),
  800  // 毫秒
);

// 每帧更新（处理震动和过渡动画）
protected onUpdate(dt: number): void {
  this.cameraCtrl.update(dt);
}
```

## 相机模式

| 模式 | 视角 | 适用场景 |
|------|------|---------|
| `top-down-fixed` | 60° 俯瞰 | 拼图/三消游戏（推荐） |
| `isometric-45` | 45° 等距视角 | 策略/建造类 |
| `orbit-debug` | 自由轨道（OrbitControls） | 开发调试 |

## 关键设计

- **setupForBoard()** 使用 FOV 和三角函数计算相机距离：`distance = (maxDim / 2) / tan(fov / 2) * margin`
- **shake()** 通过在原始位置上叠加随机偏移实现，不影响 base position
- **transitionTo()** 使用 smoothstep lerp 插值 position + lookAt 目标
- **update()** 每帧调用，处理震动衰减和过渡进度

## Skill Definition

```yaml
tools:
  - read_file
  - write_file
inputs:
  - source: ref/CameraController.ts
outputs:
  - cameraController: CameraController class with setupForBoard/shake/transitionTo/update
```
