docs: 新增 shmup-player-sprite 项目级技能(主角机三帧精灵生产流水线文档)
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
@@ -0,0 +1,121 @@
|
||||
---
|
||||
name: shmup-player-sprite
|
||||
description: 竖版射击游戏主角机三帧精灵(平飞/左滚转/右滚转)生产流水线。Use when 生成或调整玩家机 sprite、shmup aircraft sprite、bank/roll 滚转侧身帧、调试飞机贴图滚转效果、或为 1942 式竖版射击游戏制作新机型的三帧美术。关键词:主角机、玩家飞机、滚转身、bank frames、P-38、雷光、plane_funnel。
|
||||
---
|
||||
|
||||
# 竖版主角机三帧精灵生产流水线
|
||||
|
||||
为本项目(1942 式竖版射击)生产主角机三帧动画精灵:平飞基准帧 + 左/右滚转帧。
|
||||
|
||||
**核心思路:AI 只负责生成一张严格对称的平飞基准图;滚转帧用高度图浮雕投影确定性推导**,避免 AI 生图的不可控性。
|
||||
|
||||
## 工具位置
|
||||
|
||||
流水线脚本在本项目 `tools/gen_plane_sprites.py`(git 跟踪,单一数据源)。机型档案在 `tools/profiles/*.json`(内置 `p38`,另有 `plane_funnel`)。
|
||||
|
||||
迁移到其他项目:把 `tools/gen_plane_sprites.py` 拷过去,参照脚本内 `BUILTIN_PROFILES["p38"]` 写新机型的 JSON profile 即可。
|
||||
|
||||
## 快速开始
|
||||
|
||||
```bash
|
||||
# 密钥:环境变量 APIYI_API_KEY,或 tools/.apikey(已 gitignore,勿提交)
|
||||
|
||||
# 1. 生成基准图(唯一需要 AI 的一步)
|
||||
python tools/gen_plane_sprites.py --profile tools/profiles/<机型>.json base
|
||||
python tools/gen_plane_sprites.py check assets/raw/<name>-base.png --symmetry # 对称度应 >95%
|
||||
|
||||
# 2. 确定性生成左右滚转帧(零 API)
|
||||
python tools/gen_plane_sprites.py --profile tools/profiles/<机型>.json relief
|
||||
|
||||
# 3. 裁边 + 统一缩放 + 居中落地 assets/art/
|
||||
python tools/gen_plane_sprites.py --profile tools/profiles/<机型>.json process
|
||||
|
||||
# 4. 校验三帧后 godot --import
|
||||
python tools/gen_plane_sprites.py check assets/art/<name>.png
|
||||
```
|
||||
|
||||
## 几何模型(理解一切的基础)
|
||||
|
||||
滚转侧身帧的正确语义:**飞机不动,相机在飞机 Up-Right 平面内从正上方移到右上方 θ 角处(等距、看向机心)**。正交投影下:
|
||||
|
||||
```
|
||||
x' = x·cosθ − h·sinθ y' = y
|
||||
```
|
||||
|
||||
三个视觉后果,缺一不可:
|
||||
1. **翼展按 cosθ 压缩**——整机变窄,纵向(机头到机尾)长度不变
|
||||
2. **有高度的部件向画面左移** h·sinθ(θ=45° 时座舱盖偏移 ≈ 高度的 0.7 倍)
|
||||
3. **朝向相机的侧面露出**——机身/发动机舱右缘出现一条暗色侧面带
|
||||
|
||||
反面辨析:只压缩(无侧面露出)看起来仍是正俯视;机翼一高一低(2D 斜切)是"相机自己 roll",不是相机移动。
|
||||
|
||||
## 关键步骤与校验标准
|
||||
|
||||
### 1. base — AI 文生图基准帧
|
||||
|
||||
Prompt 四个硬约束,少一个都不行:
|
||||
- **正俯视**("Top-down view, seen from directly above")
|
||||
- **严格左右对称**("PERFECTLY LEFT-RIGHT SYMMETRIC")——对称是 relief 高度图正确的前提,也便于镜像出右滚转帧
|
||||
- **机头正上**("nose pointing STRAIGHT UP")
|
||||
- **透明背景**(gpt-image-1 原生支持 `background: "transparent"`)
|
||||
|
||||
校验:`check --symmetry`,对称度 >95%、四角 alpha=0 才放行。不合格重新生成,不要带伤进入下一步。
|
||||
|
||||
### 2. relief — 高度图浮雕投影(推荐,确定性)
|
||||
|
||||
零 API,从基准图严格推导:
|
||||
1. **高度图 = 剪影距离变换**(chamfer distance transform):管状结构(机身/发动机舱/尾撑)自动获得圆顶高度,薄结构(机翼/尾翼)自动低平——无需手绘高度图
|
||||
2. **逐像素投影** `x' = x·cosθ − h·sinθ`:陡坡(朝相机的侧面)被行内拉伸,缝隙用加暗色填充 → 新侧面露出;背侧坡压缩覆盖
|
||||
3. **右滚转帧 = 左帧水平镜像**,两侧严格对称
|
||||
|
||||
调参旋钮(profile 的 `relief` 节,或 CLI `--angle/--height/--side-dark` 覆盖):
|
||||
|
||||
| 参数 | p38 默认 | 作用 |
|
||||
|---|---|---|
|
||||
| `angle` | 45 | 相机偏角。越大翼展越窄、侧面越宽;48px 精灵建议 30-45 |
|
||||
| `height` | 48 | 机身最大高度(原始图像素)。控制座舱/机脊的横向位移量 |
|
||||
| `side_dark` | 0.4 | 露出侧面的最大暗度(0-1) |
|
||||
| `slope_th` | 0.3 | 高度梯度阈值,超过才视为侧面加暗;调低则机翼边缘也带暗面 |
|
||||
|
||||
### 3. process — 裁边缩放落地
|
||||
|
||||
**统一缩放系数是隐藏的关键约束**:以基准图外接框算出 `scale = min(W/bw, H/bh)`,三帧共用。各帧独立缩放会导致同一架飞机跨帧纵向尺寸不一致(视觉上尾翼"离机身更远")。机身纵向长度是滚转不变量,必须跨帧锁定。
|
||||
|
||||
### 备选:bank — AI 图生图滚转帧
|
||||
|
||||
如果一定要 AI 重绘滚转帧(追求真实光影细节),prompt 纪律:
|
||||
- **直接描述飞机姿态**("banking LEFT at 20°, left wing lower, right side sliver visible"),**绝不描述相机移动**("camera moved" 会被画成前视 3/4 插画)
|
||||
- 显式钉死:机头正上、机身竖直、翼尖同高、整机完整(枚举 `bank_parts` 所有部件)、螺旋桨机加"螺旋桨侧视不翻脸"(profile 的 `propellers: true`,喷气机设 false)
|
||||
- 生成后用 `align` 校正朝向(模板匹配 ±90° 搜索;不行就 `align --rotate <度数>` 手动)
|
||||
- **不要用二阶矩主轴法找角度**——滚转的机翼会带偏主轴
|
||||
|
||||
## 踩坑记录(血泪教训)
|
||||
|
||||
| 坑 | 现象 | 解法 |
|
||||
|---|---|---|
|
||||
| 文生图直接说 "bank/roll" | 模型自由发挥:机翼消失、整机画斜 | 基准帧只生成平飞;滚转交给 relief |
|
||||
| prompt 描述相机移动 | 画成前视 3/4 插画(螺旋桨翻脸) | 描述飞机姿态,不提相机 |
|
||||
| 垂直剪切(shear)模拟滚转 | 飞机被拉斜,2D 平面感 | 那是相机自旋,几何错误 |
|
||||
| 只水平压缩(无侧面) | 仍是正俯视,无滚转感 | 必须有高度驱动的侧面露出 |
|
||||
| 逐帧独立缩放 | 尾翼看似离机身更远 | 统一缩放系数(锚定基准图) |
|
||||
| 半分辨率高度图直接采样 | 机翼出现 2×2 方块暗纹 | 高度图双线性升回全分辨率再采样 |
|
||||
| 陡坡均匀压暗 | 机身整体发暗发糊 | 渐变加暗:脊线亮→边缘暗,且仅陡坡 |
|
||||
|
||||
## 产物约定
|
||||
|
||||
```
|
||||
assets/raw/{name}-base.png AI 原始基准图(保留,勿删——relief 的输入)
|
||||
assets/raw/{name}-bank-left.png 滚转帧原始图
|
||||
assets/raw/{name}-bank-right.png
|
||||
assets/art/{name}.png 最终三帧(48×56 或 profile 指定尺寸)
|
||||
assets/art/{name}-bank-left.png
|
||||
assets/art/{name}-bank-right.png
|
||||
```
|
||||
|
||||
游戏侧接线约定(本项目 `scripts/player.gd` 已实现):三帧贴图切换 + 迟滞阈值(进入 0.45 / 退出 0.25),缺图回退平飞帧;滚转帧**不做**代码旋转/缩放变换。
|
||||
|
||||
## 环境依赖
|
||||
|
||||
- Python 3.10+,Pillow(仅标准库 + PIL,无 numpy/scipy)
|
||||
- AI 步骤(仅 `base` / `bank`)需要 OpenAI 兼容图像接口(默认 apiyi,gpt-image-1)
|
||||
- 密钥:`APIYI_API_KEY` 环境变量,或 `tools/.apikey`(**必须 gitignore**)
|
||||
Reference in New Issue
Block a user