---
name: sprite_entity_renderer.aicomponent
description: 精灵实体渲染器。用 Phaser Image 精灵替代 Graphics API 手绘，实现更美观的棋盘实体渲染。管理精灵生命周期、方向旋转、缩放、着色和动画临时精灵。
triggers: 精灵渲染,sprite renderer,Image替代Graphics,实体渲染,旋转方向,sprite rotation,entity render
---

# 精灵实体渲染器（Sprite Entity Renderer）

## 说明

当棋盘上的实体（汽车、箭头、动物等）使用 AI 生成的图片而非 Graphics API 绘制时，需要管理精灵的**创建/销毁/旋转/缩放/动画**。本 skill 提供标准化的渲染模式。

**核心思路：单图 + 旋转**
- 只需一张朝固定方向的图片
- 通过 `setRotation(angle)` 实现任意方向
- 通过 `setTint(color)` 实现颜色变化（如阻挡时变红）

## Scaffold

| 目标路径 | 来源 | 说明 |
|---------|-----|------|
| `src/game/scenes/GameUI/SpriteEntityRenderer.ts` | `ref/SpriteEntityRenderer.ts` | 完整渲染器 |

## Imports

- `phaser.aicomponent`（硬依赖：Phaser Image API）
- `board_entity_sprite.aiimage`（配套：图片资源来源）
- `grid_board_layout.aicomponent`（硬依赖：格子坐标）

## 核心接口

```typescript
class SpriteEntityRenderer {
  constructor(scene: any, textureKey: string, defaultFacing: "up" | "down");

  /** 渲染所有实体（销毁旧精灵 → 创建新精灵） */
  renderAll(entities: EntityData[], container: Container): void;

  /** 清除所有精灵 */
  clear(): void;

  /** 创建临时精灵（用于消除动画） */
  createTempSprite(x: number, y: number, direction: string, container: Container): Image;

  /** 方向→旋转角度 */
  directionToAngle(direction: string): number;
}

interface EntityData {
  x: number;        // 格子列
  y: number;        // 格子行
  direction: string; // "up" | "down" | "left" | "right"
  tint?: number;     // 可选着色
}
```

## Recipe

| 决策 | 原因 |
|------|------|
| **单图 + 旋转替代四方向图** | 只需维护一张图，旋转由代码处理；减少资产数量，AI 生图只需一次 |
| **精灵对象池（clear+rebuild）** | 每帧销毁旧精灵并重建，比跟踪差量更简单可靠；在 Phaser 中精灵创建开销小，试玩广告帧数要求不极端 |
| **临时精灵用于消除动画** | 消除动画时保留独立精灵放入动画容器，与主渲染层解耦；动画结束后容器销毁，无需回收到对象池 |
| **替代 Graphics 而非共存** | SpriteEntityRenderer 设计为 PathRenderer 的精灵模式替代品；两者通过同一接口协作，不共存 |

## Adapter

- **Role**: `spriteEntityRenderer` — 棋盘实体（箭头头部）的 Phaser Image 精灵渲染器
- **Provides**: `SpriteEntityRenderer` 类（`renderAll()`、`clear()`、`createTempSprite()`、`directionToAngle()`），`EntityData` 类型
- **Requires**: `phaser.aicomponent`（Image API）、`board_entity_sprite.aiimage`（图片资源纹理 key）、`grid_board_layout.aicomponent`（格子坐标→像素坐标）
- **Consumed by**: `path_renderer.aicomponent`（精灵渲染模式时调用 `renderAll()`）、`path_animation.aicomponent`（消除动画时调用 `createTempSprite()`）
- **Integration point**: `src/game/scenes/GameUI/SpriteEntityRenderer.ts` → PathRenderer 在 sprite 模式下持有实例

## 与 PathRenderer 的替换关系

**Before（Graphics API）：**
```typescript
// 每帧在 Graphics 对象上绘制多边形
renderGridPaths(level, progress) {
  g.clear();
  for (path of level.paths) {
    drawSegments(g, path);  // 画折线
    drawArrowHead(g, path); // 画三角形
  }
}
```

**After（Sprite Renderer）：**
```typescript
// 管理精灵对象池
renderGridPaths(level, progress) {
  this.spriteRenderer.clear();
  const entities = level.paths
    .filter(notRemoved)
    .map(p => ({ x: p.head.x, y: p.head.y, direction: p.direction }));
  this.spriteRenderer.renderAll(entities, boardContainer);
}
```

## 方向映射规则

```typescript
// 构造函数指定图片默认朝向
const renderer = new SpriteEntityRenderer(scene, "car", "down");

// 内部映射逻辑：
// 若 defaultFacing = "down":
//   down  → 0        (不旋转)
//   up    → π        (180°)
//   left  → π/2      (90° 顺时针)
//   right → -π/2     (-90°)
//
// 若 defaultFacing = "up":
//   up    → 0
//   down  → π
//   right → π/2
//   left  → -π/2
```

## 动画集成

消除动画时创建临时精灵放入容器：

```typescript
// 在 AnimationManager 中
const car = spriteRenderer.createTempSprite(hx, hy, path.direction, container);

scene.tweens.add({
  targets: container,
  x: dx * slideDistance,
  y: dy * slideDistance,
  alpha: 0,
  duration: 400,
  onComplete: () => container.destroy(), // 精灵随容器销毁
});
```

## Skill Definition

```yaml
tools:
  - read_file
  - write_file
inputs:
  - source: ref/SpriteEntityRenderer.ts
outputs:
  - renderer: SpriteEntityRenderer class
```
