# Tai Chi Visual Effect Design

## 1. 设计目标

Tai Chi 是一个连续演化的全屏视觉特效，用动画表现：

> 一画开天 → 阴阳分化 → 太极成形 → 四层演化 → 八卦归位

整个过程不是多个互不相关的画面切换，而是一条连续时间线。前一阶段已经存在的图形应尽量作为下一阶段的动画起点，避免突然消失、重新生成或位置跳变。

视觉基调：

- 背景保持应用当前主题背景，不额外覆盖不透明底色。
- 文字以 `ColorBase.primary_text` 和 `ColorBase.secondary_text` 为主。
- 强调色统一使用 `ThemeColor.alpha_theme_color(alpha)`。
- 强调色只承担轮廓、卦线、微光和轨迹作用，不使用高饱和实色大面积填充。
- 所有位置和尺寸根据 `Control.size` 动态计算，支持不同窗口比例。

## 2. 文件职责

| 文件 | 职责 |
| --- | --- |
| `TaiChi.gd` | 总控制器，驱动各阶段、维护 Shader 图层并决定当前绘制阶段。 |
| `TaiChiOpeningFlow.gd` | 绘制“一画开天”的水平线和开场文字。 |
| `TaiChiDualityFlow.gd` | 将一条线分化为阳爻和阴爻。 |
| `TaiChiFormationFlow.gd` | 将两仪线条变形成完整太极。 |
| `TaiChiEvolutionFlow.gd` | 太极缩小、移动，并从下到上生成四层结构。 |
| `TaiChiBaguaFlow.gd` | 将横排八卦连续移动成圆阵，并将太极移到圆心。 |
| `TaiChiLineAura.gdshader` | 开场线条和两仪阶段的柔和流动光效。 |
| `TaiChiFill.gdshader` | 绘制黑白太极填充图案。 |

## 3. 总时间线

阶段按以下顺序自动启动：

1. Opening：`2.25s`
2. Duality：`2.2s`
3. Formation：`3.2s`
4. Evolution：`14.4s`
5. Bagua：`5.8s`
6. Carousel：八卦各展示一次，每卦 `4.8s`
7. Hexagram：上下卦相重并生成六十四卦，`10.8s`

`TaiChi._process()` 每帧推进当前阶段。当一个阶段的 `progress()` 达到 `1.0` 时，启动下一个阶段。

所有 Flow 均遵循相同生命周期：

- `reset()`：清空时间并停用。
- `begin()`：从零开始并激活。
- `advance(delta)`：累加时间，返回画面是否需要重绘。
- `progress()`：返回经过缓动处理的 `0.0–1.0` 进度。

## 4. 阶段一：一画开天

实现文件：`TaiChiOpeningFlow.gd`

### 步骤

1. 在画面中下部确定水平线中心。
2. 水平线从中心向左右两端同时延伸。
3. “一画开天”四个字同步出现。
4. 文字从中心向外展开，避免像普通淡入字幕。
5. Shader 在水平线周围添加非常轻的流动光带。

### 完成条件

`line_progress() == 1.0` 后启动两仪阶段。

## 5. 阶段二：两仪分化

实现文件：`TaiChiDualityFlow.gd`

### 步骤

1. 开场水平线分离成上下两行。
2. 上行保持完整，表示阳。
3. 下行从中心打开缺口，表示阴。
4. 左右辅助文字随动画后半段出现。
5. 开场标题逐渐退场。

### 完成条件

`progress() == 1.0` 后启动太极成形阶段。

## 6. 阶段三：太极成形

实现文件：`TaiChiFormationFlow.gd`

### 步骤

1. 阳爻弯曲为太极外圆的构造线。
2. 阴爻两段分别收束为上下两个鱼眼。
3. 中央 S 形分界线由上至下绘制。
4. 构造线逐渐退去。
5. `TaiChiFill.gdshader` 的黑白填充逐渐显现。
6. 太极下方显示“易有太极，是生两仪”及英文副标题。

鱼眼不能通过“横线各点直接插值到完整圆周”的方式生成，否则中间帧会发生路径交叉并形成绳结。当前实现把横线视为高度为零的椭圆：先逐渐增加椭圆纵向半径，再同步移动中心、收缩横向半径，最终得到无自交的圆。

### 关键进度

- `outer_progress()`：外圆构造。
- `upper_inner_progress()`：上方鱼眼。
- `lower_inner_progress()`：下方鱼眼。
- `divider_progress()`：S 形分界。
- `fill_progress()`：黑白填充。

### 完成条件

`progress() == 1.0` 后启动四层演化阶段。

## 7. 阶段四：太极缩小和标题退场

实现文件：`TaiChiEvolutionFlow.gd`

该阶段前半部分先处理太极和标题，再开始生成层级。缩小与移动不能同时发生。

### 步骤

1. 太极保持在成形阶段的中心位置。
2. `shrink_progress()` 驱动太极半径从大尺寸缓慢缩小。
3. 原标题保持相同字距和排版同步缩小。
4. 标题在缩小后半段逐渐透明并完全消失。
5. 太极缩小完成后保持原位，不再执行层级阶段的位置移动。
6. 四层结构和下方中英文说明都以太极中心为布局基准。

最终横坐标使用：

```gdscript
content_area(canvas_size).get_center().x
```

这不是整个窗口的几何中心，而是“阳”和“阴”两个内容格之间的正中间。

## 8. 阶段五：四层结构生成

实现文件：`TaiChiEvolutionFlow.gd`

四层从下到上排列：

1. 太极
2. 两仪
3. 四象
4. 八卦

`row_from_bottom == 0` 表示太极层，`row_from_bottom == 3` 表示最上层。

### 层级位置

- 最下层与缩小后保持不动的太极中心对齐。
- 最上层位于画面高度约 `16%`。
- 中间层通过线性插值均匀分布。
- 两仪、四象和八卦的爻线统一使用 `54px` 最终宽度。
- 层级标题的中心位于画面宽度约 `20%` 处，更靠近图案区域。
- 内容区域从画面宽度 `25%` 开始，占据约 `50%`，中心与太极对齐。

### 启动顺序

`row_progress()` 让各层从下到上依次启动，并保留少量时间重叠，使整体动画连续而不拖沓。

每层内部由 `item_progress()` 继续拆分：

- 左侧图案最先启动。
- 后续图案依次延迟。
- 每个图案拥有独立的完整飞行时间。

### 天外飞入动画

除太极以外的图案都从画面顶部之外飞入。

`flying_position()` 的计算过程：

1. 起点 Y 位于 `-70px` 以上，确保图案初始不可见。
2. 起点 X 在画面中心附近形成扇形分布。
3. 使用缓动插值从起点飞向目标位置。
4. 偶数和奇数索引使用相反的横向弧线。
5. 中段弧线偏移最大，起点和终点偏移为零。
6. 图案从小尺寸逐渐恢复到最终尺寸。
7. 飞行中段绘制低透明度短拖尾。
8. 到达目标位置时拖尾自动归零。

当前 Evolution 总时长为 `14.4s`，用于保证飞行过程足够舒缓。

## 9. 爻象编码规则

两仪、四象和八卦统一由爻线图形表示，并在图形上方显示中文名称。各爻从画面上方向下绘制，最低有效位对应最上面一爻。

- 两仪名称与编码：`["阳", "阴"]`、`[1, 0]`。
- 四象名称与编码：`["太阳", "少阴", "少阳", "太阴"]`、`[3, 2, 1, 0]`。
- 八卦名称与编码：`["乾", "兑", "离", "震", "巽", "坎", "艮", "坤"]`、`[7, 6, 5, 4, 3, 2, 1, 0]`。

标准编码如下：

| 卦名 | 图形 | 二进制 | 十进制 |
| --- | --- | --- | --- |
| 乾 | ☰ | `111` | 7 |
| 兑 | ☱ | `110` | 6 |
| 离 | ☲ | `101` | 5 |
| 震 | ☳ | `100` | 4 |
| 巽 | ☴ | `011` | 3 |
| 坎 | ☵ | `010` | 2 |
| 艮 | ☶ | `001` | 1 |
| 坤 | ☷ | `000` | 0 |

`TaiChiEvolutionFlow` 中的名称与编码常量是唯一数据来源。横排阶段和圆阵阶段必须共同使用八卦编码数组，禁止分别维护两套编码。

## 10. 阶段六：八卦归位

实现文件：`TaiChiBaguaFlow.gd`

四层完全生成后，八个横排卦象移动成圆阵。

### 无缝交接

1. `TaiChi.gd` 调用 `evolution.draw(..., false)`，停止由 Evolution 绘制八卦行。
2. Bagua Flow 在完全相同的源坐标绘制同一组卦象。
3. 初始尺寸、线距、透明度和文字位置与横排阶段一致。
4. 因此画面中没有“旧图消失、新图出现”的一帧跳变。

### 卦象移动

1. 八个卦象仍按横排从左到右依次启动。
2. 每个卦象从原横排位置直接移动。
3. 中途加入向上的浅弧线，使轨迹更自然。
4. 卦象移动时同步旋转为径向方向。
5. 卦线宽度、线距和整体尺寸逐渐放大。
6. 卦名和图案使用同一轨迹同步移动。

### 最终方位

- 上：乾
- 左上：兑
- 左：离
- 左下：震
- 右上：巽
- 右：坎
- 右下：艮
- 下：坤

这些方位由 `TARGET_ANGLES` 定义。

## 11. 太极进入圆心

太极不淡出，也不创建替代图片。

### 步骤

1. 使用 Evolution 阶段最终的太极坐标作为起点。
2. `taiji_progress()` 独立控制太极移动时间。
3. 太极缓慢移动到 `canvas_size * 0.5`。
4. 移动过程中半径逐渐增加到短边的约 `15.5%`。
5. Shader 始终使用同一个 `FillLayer`，所以黑白图案连续稳定。

## 12. 圆阵框架

当卦象接近最终位置后，`frame_progress()` 开始绘制圆阵：

1. 从正上方顺时针绘制第一条外圆。
2. 绘制第二条较淡的外圆。
3. 绘制包围中央太极的内圆。
4. 沿外圆依次生成 64 个刻度。
5. 每隔 8 个刻度使用较长线段，标记八卦主方位。

圆环和刻度使用低 Alpha 主题色，不能压过中央太极和八个卦象。

## 13. 主题色与透明度

禁止直接使用不透明主题色绘制大面积元素。

推荐形式：

```gdscript
ThemeColor.alpha_theme_color(alpha)
```

主要透明度范围：

- 卦线：约 `0.32–0.58`，取决于阶段和强调程度。
- 单元格边框：约 `0.24`。
- 亮格填充：约 `0.07`。
- 拖尾：最高约 `0.055`。
- 圆环：约 `0.09–0.16`。
- 刻度：最高约 `0.20`。

主题色变化时，`TaiChi.on_theme_changed()` 会更新 Shader 参数并触发重绘。

## 14. 绘制层级

`TaiChi.gd` 中的主要绘制层：

1. `LineAura`：`z_index = -2`，开场和两仪阶段光效。
2. `FillLayer`：`z_index = -1`，Shader 太极填充。
3. `_draw()`：构造线、层级结构、卦象、圆环和文字。

进入太极成形阶段后，LineAura 隐藏。FillLayer 从成形阶段一直复用到最终圆阵。

## 15. 响应式规则

- 太极尺寸基于窗口短边计算。
- 层级 Y 坐标按窗口高度比例分布。
- 内容区按窗口宽度比例计算。
- 字号使用窗口高度比例，并通过 `clampi()` 限制最小和最大值。
- 圆阵半径使用窗口短边的约 `34%`。
- 小窗口下仍需保证太极、文字和圆环不互相覆盖。

## 16. 测试要求

测试场景：

```text
res://agent/test/visual/tai_chi_unit/TaiChiTest.tscn
```

关键断言包括：

- 各 Flow 能正确开始、推进和结束。
- 四层必须按从下到上的顺序启动。
- 飞行图案初始位置位于画面外，结束位置等于目标位置。
- 横排八卦编码必须为 `[7, 6, 5, 4, 3, 2, 1, 0]`。
- Bagua 阶段必须保持从左到右的启动顺序。
- 最终太极中心必须等于画布中心。
- 最终太极半径必须大于四层结构中的小太极半径。
- Shader 图层必须存在，并使用正确的透明主题色。

修改动画后至少执行：

```powershell
godot --headless --path . res://agent/test/visual/tai_chi_unit/TaiChiTest.tscn
```

新增脚本或修改复杂绘制函数时，还应显式检查脚本解析：

```powershell
godot --headless --path . --check-only --script res://agent/ui/visuals/tai_chi/TaiChiEvolutionFlow.gd
godot --headless --path . --check-only --script res://agent/ui/visuals/tai_chi/TaiChiBaguaFlow.gd
```

## 17. 后续修改原则

1. 优先延续已有图形，不用淡出后重新创建的方式模拟移动。
2. 修改卦象编码时只改 `TRIGRAM_VALUES`。
3. 修改层级位置时同时检查太极与“两仪”中心对齐。
4. 修改八卦源位置时确保 Bagua Flow 与 Evolution Flow 使用相同坐标公式。
5. 增加主题色强度时优先调整 Alpha，不要改为不透明颜色。
6. 修改阶段时长后，检查快速 Agent 任务结束时是否仍有足够播放时间。
7. 所有新增函数遵循项目 GDScript 规范：显式返回类型，且无显式 `return` 的命名函数以 `pass` 结束。

## 18. 阶段七：八卦说明轮播

实现文件：`TaiChiCarouselFlow.gd`

圆阵稳定后依次展示八卦，并为六十四卦阶段保留圆阵结构。

### 入场步骤

1. 太极围绕自身中心旋转约一圈半。
2. 太极在旋转过程中逐渐透明，最终完全消失。
3. 外侧双圆环、内圆和 64 个刻度开始持续缓慢旋转。
4. 八个卦象保持固定方位，确保文字和图案始终可读。
5. 中央区域由太极图案平滑交接为八卦说明。

### 轮播内容

每一卦展示三层信息：

- 自然象征：天、泽、火、雷、风、水、山、地。
- 对应说明：乾为天、兑为泽、离为火、震为雷、巽为风、坎为水、艮为山、坤为地。
- 核心特性：例如乾的“刚健 · 自强 · 创造”和坤的“柔顺 · 承载 · 包容”。
- 《象传》原文：显示在圆阵内部下方，并与当前卦同步切换。

### 轮播规则

1. 按圆阵顺时针方向播放：乾、巽、坎、艮、坤、震、离、兑。
2. 每项持续 `4.8s`。
3. 开头 `18%` 时间淡入，结尾 `18%` 时间淡出。
4. 中央主字进入时带轻微向上稳定的位移。
5. 当前卦象在外圈同步提亮并轻微呼吸放大。
6. 八项结束后不再回到乾，而是进入六十四卦生成阶段。

## 19. 阶段八：八卦相荡与六十四卦

实现文件：`TaiChiHexagramFlow.gd`

1. 八卦说明轮播结束后，旋转圆环平滑减速并回正。
2. 八个三爻卦分成内外两层，表现上卦与下卦的组合关系。
3. 外圈八卦保持固定，内圈八卦每轮旋转一个方位，形成一组新的上下卦关系。
4. 每轮同时绘制八个扇形组合框，分别框住八组内外卦象。
5. 当前八组组合生成六爻卦后，分别飞入八个扇区内属于自己的位置。
6. 飞行动画结束后内圈再次旋转，共执行八轮，使每个扇区最终拥有八个六爻卦。
7. 六十四卦生成完成后，中央显示“六十四卦”、“变动不居，周流六虚”和注解“（变化之象，周流不息）”。
8. 全景只显示微型六爻图形，不同时显示 64 个名称，避免小窗口信息拥挤。

最终落位采用伏羲先天六十四卦圆图的二进制次序，而不是生成轮次顺序：

- 第一半圆由乾 `63` 递减至复 `32`。
- 第二半圆从坤 `0` 递增，经剥至姤 `31`，最后与乾相接。
- 八轮旋转仍决定卦象何时生成；六爻编码决定它最终飞往圆图中的哪个位置。

六爻编码延续现有绘制约定：最低有效位位于图形最上方，因此组合公式为：

```gdscript
hexagram_value = upper_trigram | (lower_trigram << 3)
```
