Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
8 changes: 7 additions & 1 deletion .agent/rules/ui-guidelines.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,13 @@
- 交互提示:带轻微背景增强可读性,可使用 animate-pulse
- 所有提示默认 pointer-events-none,除非需要交互

### 6. 组件扩展规则(新增)
### 6. board-shell 缩放下的 HUD/Overlay 反模式(新增)
- **反模式**:在 `MobileBoardShell` 内部直接渲染 `fixed/absolute` 的 HUD/Overlay。
- 原因:board-shell 会在移动端横屏使用 `transform: scale(...)`,导致 `fixed` 参照缩放容器而非 viewport,出现偏移。
- **正确做法**:新 HUD/Overlay 必须通过 HUD portal 渲染到 `#hud-root`(使用 `HudPortal` / `getHudPortalRoot`)。
- **历史实现**:旧代码不强制重构,但新增/修复必须改为 portal。

### 7. 组件扩展规则(新增)
- 对已内置居中/定位的浮层组件,**禁止用 containerClassName 完全替换默认定位类**(例如 left-0/right-0/translate 居中)。
- 如需允许交互或调整样式,优先使用显式 props(如 allowPointerEvents / layout),或在 containerClassName **追加**样式,避免破坏默认居中布局。

Expand Down
70 changes: 70 additions & 0 deletions .windsurf/skills/atlas-crop/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
---
name: atlas-crop
description: 通用图集裁切与抽样验收流程;支持不规则网格配置、全局偏移与批量导出 slot 图片。
---

# 通用图集裁切(可复用)

用于从任意图集裁出单元图块,并做抽样检查(关键内容是否被裁掉、是否偏移)。
**目标**:裁切结果与运行时渲染一致,关键内容不被裁掉。

## 适用场景
- 新图集出现轻微左/右偏,需要微调裁切偏移
- 需要批量导出 `slot-xx.webp/png` 做目检
- 使用不规则网格(colStarts/rowStarts/colWidths/rowHeights)裁切

## 先决条件
- Python 3
- Pillow(若缺失:`pip install pillow`)

## 脚本
```
./.windsurf/skills/atlas-crop/scripts/extract-atlas-crops.py
```

## 快速流程
1. **准备配置 JSON(或规则网格参数)**
- **SpriteAtlasConfig(网格)**:`imageW`/`imageH`/`cols`/`rows`/`colStarts`/`colWidths`/`rowStarts`/`rowHeights`
- **SpriteAtlasConfig(frames 列表)**:`imageW`/`imageH` + `frames: [{x,y,width,height}]`
- **TexturePacker(frames map)**:`meta.size.w/h` + `frames: { key: { frame: {x,y,w,h}} }`
- **规则网格(无 JSON)**:使用 `--grid-rows/--grid-cols` + 可选 `--cell-w/--cell-h/--gap-x/--gap-y/--start-x/--start-y`
2. **执行裁切脚本(在仓库根目录运行)**
```bash
python ./.windsurf/skills/atlas-crop/scripts/extract-atlas-crops.py \
--image "<图集路径>" \
--config "<配置JSON路径>" \
--out "<输出目录>" \
--shift-x -0.5 \
--max-index 31
```
3. **抽样验收(必须)**
- 先看整图理解结构,再看单卡是否偏移/被裁
- 如仍偏移:微调 `shift-x`/`shift-y`(0.5~1px 级别)后重跑

## 验收要点(必看)
- 关键内容完整可见(如角标、角标数字、右侧符号等)
- 边界不过裁、不留异常大空白
- 若图集本身有“空白/占位”区域,需先确认结构再判定是否异常

## 注意事项
- **不要提交 `temp/` 产物**,仅用于目检与交付。
- **运行时偏移与脚本偏移必须一致**,否则裁切结果与实际渲染不一致。
- 输出目录建议包含时间戳,避免残留旧 slot 误判。

## 项目内图集类型分类(摘要)
- **A. SpriteAtlasConfig(不规则网格)**:卡牌/棋盘图集常用(手写 `colStarts/rowStarts`)。
- **B. SpriteAtlasConfig(frames 列表)**:非规则复合排版可用(逐帧数组)。
- **C. TexturePacker JSON(frames map)**:状态图标/特效图集(`meta.size` + `frames.{key}.frame`)。
- **D. Lazy Grid(仅 rows/cols)**:运行时用图片尺寸生成均匀网格(SmashUp)。

更完整的项目内使用清单见:`./.windsurf/skills/atlas-crop/references/boardgame-atlas-usage.md`

## DiceThrone 示例(可选)
```bash
python ./.windsurf/skills/atlas-crop/scripts/extract-atlas-crops.py \
--image "public/assets/i18n/zh-CN/dicethrone/images/gunslinger/compressed/ability-cards.webp" \
--config "public/assets/atlas-configs/dicethrone/ability-cards-common.atlas.json" \
--out "temp/dicethrone/atlas-crops-YYYYMMDD-HHMMSS/gunslinger" \
--shift-x -5 \
--max-index 31
```
59 changes: 59 additions & 0 deletions .windsurf/skills/atlas-crop/references/boardgame-atlas-usage.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# BoardGame 图集使用清单(按类型分门别类)

> 目的:快速判断“这是哪种图集格式”,以及对应的裁切/注册链路。

## 类型 A:SpriteAtlasConfig(不规则网格)
**特征**:`imageW/imageH + rows/cols + colStarts/rowStarts/colWidths/rowHeights`
**用途**:卡牌、棋盘、骰子等“按格切”的大图集
**裁切建议**:使用 `extract-atlas-crops.py --config <atlas.json>`

### DiceThrone
- 配置:`public/assets/atlas-configs/dicethrone/ability-cards-common.atlas.json`
- 运行时:`src/games/dicethrone/ui/cardAtlas.ts`(可叠加角色全局偏移)
- 说明:新角色可能存在轻微左/右偏;需要同步运行时偏移与脚本偏移

### Summoner Wars
- 配置:`src/games/summonerwars/ui/cardAtlas.ts`(手写 HERO/CARDS/PORTAL/DICE)
- 说明:**不是均匀网格**,下半部分有黑色填充;必须手写 rowHeights

---

## 类型 B:SpriteAtlasConfig(frames 列表)
**特征**:`imageW/imageH + frames: [{x,y,width,height}]`
**用途**:非规则排版、需要精确逐帧裁切
**裁切建议**:`extract-atlas-crops.py --config <frames-list.json>`

> 当前仓库未发现明确落地示例,但引擎类型已支持(`src/engine/primitives/spriteAtlas.ts`)。

---

## 类型 C:TexturePacker JSON(frames map)
**特征**:`meta.size.w/h + frames.{key}.frame{x,y,w,h}`
**用途**:状态图标/特效图集等“语义帧”
**裁切建议**:`extract-atlas-crops.py --config <status-icons-atlas.json>`(输出文件名=frame key)

### DiceThrone(状态图标)
- JSON:`public/assets/i18n/zh-CN/dicethrone/images/<hero>/status-icons-atlas.json`
- 运行时:`src/games/dicethrone/ui/statusEffects.tsx`
- 规则:`buildLocalizedImageSet` 需要去掉 `.png` 扩展名(见 `docs/ai-rules/asset-pipeline.md`)

---

## 类型 D:Lazy Grid(仅 rows/cols)
**特征**:只声明 `rows/cols`,运行时用图片实际尺寸生成均匀网格
**用途**:大量 POD/批量图集
**裁切建议**:
- 如果有图片:`extract-atlas-crops.py --grid-rows N --grid-cols M --image ...`
- 或先将 rows/cols 转成 SpriteAtlasConfig 后用 `--config`

### SmashUp
- 懒注册:`src/components/common/media/cardAtlasRegistry.ts`(`registerLazyCardAtlasSource`)
- 配置来源:`public/assets/atlas-configs/smashup/pod-atlas-config.json`
- 入口:`src/games/smashup/ui/cardAtlas.ts`

---

## 通用注意事项
- 图集配置 JSON **与语言无关**,放 `public/assets/atlas-configs/<gameId>/`
- 图集图片 **必须走 i18n/compressed** 路径(见 `docs/ai-rules/asset-pipeline.md`)
- 裁切偏移必须与运行时偏移一致(否则“裁切正确但渲染偏”)
Loading
Loading