docs(rich-text): 新增富文本描边规范文档

替换原有的SkillSet/heroSet配置规则文档,新增Cocos Creator富文本描边使用规范,包含使用示例和注意事项。同时重构英雄列表组件,添加升级属性提升说明的富文本展示功能,使用统一的描边工具类美化文本显示。
This commit is contained in:
panFD
2026-09-08 21:40:34 +08:00
parent 57a50578fa
commit cfaed3b63f
3 changed files with 5435 additions and 3417 deletions

View File

@@ -60,90 +60,29 @@ alwaysApply: true
--- ---
# SkillSet / heroSet 配置规则 # RichText 描边规范
## 核心原则 ## 背景
1. **技能底座纯净化**:SkillSet 中的技能只定义基础行为(伤害、弹道、命中),**禁止**在基础配置中写死 `timed_buff_id` / `buff_type` 等效果字段 Cocos Creator 3.x 的 `cc.RichText` 原生支持 `<outline>` 标签,无需新增组件即可为富文本提供描边能力。
2. **效果由引用处注入**:英雄/怪物引用技能时,通过 `HSkillInfo.overrides` 按需附加 debuff/buff,实现"同一技能、不同效果"
3. **数值覆盖优先**:`ap`(伤害百分比)、`hit_count`、`crt` 等数值差异,统一由 `overrides` 覆写,而非新建相似技能
4. **Buff 统一百分比口径**:无论永久 buff(`buff_type`)还是计时 buff(`timed_buff_id`),修饰数值均按百分比/百分点结算;`ap`/`hp_max` 按基础值相对放大,概率类属性按百分点累加
## SkillSet 配置规范 ## 使用方式
### 技能 uuid 段位分配
| 段位 | 用途 | 示例 |
|------|------|------|
| 6001-6099 | 基础单体攻击(近战/远程通用底座) | 6001 飞剑、6004 攻击 |
| 6100-6199 | 中阶攻击技能(高阶特效/多命中) | 6101 火球、6102 飓风 |
| 6200-6299 | 高阶范围技能(AOE/必杀) | 6201 陨石术 |
| 6300-6399 | 辅助/治疗/护盾技能 | 6301 护盾、6302 治疗 |
| 6400-6499 | 永久属性强化(buff_type) | 6401 攻击强化 |
| 6500-6599 | 计时爆发技能(timed_buff_id) | 6501 复活 |
### 新增技能检查清单
- [ ] uuid 在对应段位内,且未与现有技能冲突
- [ ] `sp_name` / `icon` 与现有技能不重复(避免视觉混淆)
- [ ] `IType`(近战/远程/辅助)与 `RType`(弹道类型)匹配合理
- [ ] 基础配置**不含** `timed_buff_id` / `buff_type`(效果由引用处注入)
- [ ] `info` 描述只写基础效果,不写具体 debuff(如"造成攻击力100%的伤害")
## heroSet 配置规范
### 英雄 uuid 段位分配
| 段位 | 品质 | 说明 |
|------|------|------|
| 5001-5099 | card_lv=1 | 基础单体/默认范围 |
| 5101-5199 | card_lv=2 | 数值强化 |
| 5201-5299 | card_lv=3 | 范围扩大 |
| 5301-5399 | card_lv=4 | 数值+范围 |
| 5401-5499 | card_lv=5 | 双技能(+revive/field) |
### 怪物 uuid 段位分配
| 段位 | 类型 |
|------|------|
| 6001-6099 | 基础怪物(近战/远程/特殊位) |
| 6100-6199 | Boss 怪物 |
### 新增英雄/怪物检查清单
- [ ] `skills` 引用的技能 uuid 在 SkillSet 中存在
- [ ] 技能效果通过 `overrides` 按需注入,**禁止**直接修改 SkillSet 基础配置
- [ ] `overrides.ap` 明确写出(如 80/100/150),避免依赖基础配置的默认值
- [ ] `timed_buff_id` 指向 BuffList 中存在的 buff 配置
- [ ] 怪物技能引用优先使用 6001-6012 基础技能,Boss 可用 6101+ 中阶技能
### 触发技能配置规则
| 触发类型 | 字段 | 说明 |
|----------|------|------|
| 普通攻击 | `skills` | 携带技能,`overrides` 注入效果 |
| 受击触发 | `atked` | 按 s_uuid 分组,按 lv 升序 |
| 攻击后触发 | `atking` | 按 s_uuid 分组,按 lv 升序 |
| 死亡触发 | `dead` | 按 s_uuid 分组,按 lv 升序 |
| 战斗开始 | `fstart` | 按 s_uuid 分组,按 lv 升序 |
| 驻场光环 | `field` | `FieldEntry[]`,按 lv 升序 |
| 复活 | `revive` | `LvReviveEntry[]`,按 lv 升序 |
### 示例:同一技能不同效果
```typescript ```typescript
// SkillSet 6101 火球 — 纯伤害底座,无 debuff import { outlineRich } from "../common/RichOutline";
6101: {
uuid: 6101, name: "火球", sp_name: "fb-1", ...,
// 禁止写 timed_buff_id / buff_type
}
// heroSet 5004 破晓先知 — 冰冻版火球 // 默认黑色 2px 描边
skills: { 6101: { uuid: 6101, overrides: { ap: 80, timed_buff_id: 7003 } } } this.info_rich.string = outlineRich(desc);
// heroSet 5304 战吼术士 — 中毒版火球 // 自定义颜色与宽度
skills: { 6101: { uuid: 6101, overrides: { ap: 80, timed_buff_id: 7005 } } } this.info_rich.string = outlineRich(desc, "#000", 1);
// heroSet 6008 兽人火法 — 原版火球(ap=100,无 debuff)
skills: { 6101: { uuid: 6101 } }
``` ```
## 注意事项
- `<outline>` 为包裹型标签,需成对出现;内部可嵌套 `<color>`/`<size>` 等标签
- `width` 为像素宽度(int),`color` 支持 `#RGB`/`#RRGGBB`
- 空字符串直接返回,不包裹空标签
---

File diff suppressed because it is too large Load Diff

View File

@@ -17,13 +17,14 @@
* - CardLiteComp —— 轻量卡片组件 * - CardLiteComp —— 轻量卡片组件
* - buildHeroSkillDesc(HeroSkillText)—— 技能描述生成器(局外等级口径) * - buildHeroSkillDesc(HeroSkillText)—— 技能描述生成器(局外等级口径)
*/ */
import { _decorator, Animation, AnimationClip, Button, Label, Node, Prefab, Sprite, UITransform, Vec3, Widget, instantiate, resources, tween, Tween } from "cc"; import { _decorator, Animation, AnimationClip, Button, Label, Node, Prefab, RichText, Sprite, UITransform, Vec3, Widget, instantiate, resources, tween, Tween } from "cc";
import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS"; import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS";
import { CCComp } from "../../../../extensions/oops-plugin-framework/assets/module/common/CCComp"; import { CCComp } from "../../../../extensions/oops-plugin-framework/assets/module/common/CCComp";
import { oops } from "db://oops-framework/core/Oops"; import { oops } from "db://oops-framework/core/Oops";
import { mLogger } from "../common/Logger"; import { mLogger } from "../common/Logger";
import { HeroInfo, HeroList, SkillTriggerType, LvFieldEntry, LvTriggerEntry, TriggerGrouped, HSkillInfo, getHeroDisplayStats, LvBonusAttrsEntry } from "../common/config/heroSet"; import { HeroInfo, HeroList, SkillTriggerType, LvFieldEntry, LvTriggerEntry, TriggerGrouped, HSkillInfo, getHeroDisplayStats, LvBonusAttrsEntry } from "../common/config/heroSet";
import { buildHeroSkillDesc } from "../common/HeroSkillText"; import { buildHeroSkillDesc } from "../common/HeroSkillText";
import { outlineRich } from "../common/RichOutline";
import { GameEvent } from "../common/config/GameEvent"; import { GameEvent } from "../common/config/GameEvent";
import { HERO_UPGRADE_NEED_FRAGMENTS, RARITY_BG_COLORS } from "../common/config/GameSet"; import { HERO_UPGRADE_NEED_FRAGMENTS, RARITY_BG_COLORS } from "../common/config/GameSet";
import { CardLiteComp } from "./CardLiteComp"; import { CardLiteComp } from "./CardLiteComp";
@@ -105,6 +106,14 @@ export class HerosListComp extends CCComp {
@property(Node) @property(Node)
upgrade_anim_node = null! upgrade_anim_node = null!
/** 碎片需求/总量 Label(显示 当前碎片 / 下级需求) */
@property(Label)
fragment_label = null!
/** 升级提升加成说明 RichText(展示升级后的属性提升,数值绿色高亮) */
@property(RichText)
upgrade_info_label = null!
// ======================== 运行时状态 ======================== // ======================== 运行时状态 ========================
huuid: number = 0 huuid: number = 0
@@ -470,6 +479,16 @@ export class HerosListComp extends CCComp {
: `${growth.fragments} / ${needFragments}` : `${growth.fragments} / ${needFragments}`
this.setLabelText(this.fragment_node, fragmentText) this.setLabelText(this.fragment_node, fragmentText)
} }
// 独立碎片 Label(编辑器可直接绑定 Label 组件,与 fragment_node 二选一或并存)
if (this.fragment_label) {
const fragmentText = isMaxLv
? `${growth.fragments} / MAX`
: `${growth.fragments} / ${needFragments}`
this.fragment_label.string = fragmentText
}
// 升级提升加成说明
this.updateUpgradeInfoLabel(uuid, growth.lv, isMaxLv)
// 碎片图标:使用 ChipComp 渲染英雄图标(自动读取 HeroInfo 配置) // 碎片图标:使用 ChipComp 渲染英雄图标(自动读取 HeroInfo 配置)
if (this.chip_node) { if (this.chip_node) {
@@ -488,6 +507,39 @@ export class HerosListComp extends CCComp {
// ======================== 技能图标列表 ======================== // ======================== 技能图标列表 ========================
/**
* 刷新升级提升加成说明 RichText
* 展示口径:对比当前等级与下一等级,仅列出 AP/HP/DEF 属性差值,单行展示
* 数值用绿色高亮,整体通过 outlineRich 包裹描边标签
* @param uuid 英雄模板 uuid
* @param curLv 当前局外等级(≥1)
* @param isMaxLv 是否已满级
*/
private updateUpgradeInfoLabel(uuid: number, curLv: number, isMaxLv: boolean) {
if (!this.upgrade_info_label) return
const hero = HeroInfo[uuid]
if (!hero) { this.upgrade_info_label.string = ""; return }
if (isMaxLv) {
this.upgrade_info_label.string = outlineRich("已满级")
return
}
const nextLv = curLv + 1
const cur = getHeroDisplayStats(hero, curLv)
const nxt = getHeroDisplayStats(hero, nextLv)
// 属性提升差值:单行展示 AP/HP/DEF,数值绿色高亮
const parts: string[] = []
if (nxt.hp > cur.hp) parts.push(`生命<color=#00FF00>+${nxt.hp - cur.hp}</color>`)
if (nxt.ap > cur.ap) parts.push(`攻击<color=#00FF00>+${nxt.ap - cur.ap}</color>`)
if (nxt.def > cur.def) parts.push(`防御<color=#00FF00>+${nxt.def - cur.def}</color>`)
this.upgrade_info_label.string = parts.length > 0
? outlineRich(`升级属性提升:${parts.join(" ")}`)
: outlineRich(`升级至 Lv.${nextLv}`)
}
/** 图鉴面板展示的触发技能槽位(按触发时机排序:召唤→战斗开始→攻击后→受击后→死亡→常驻光环) */ /** 图鉴面板展示的触发技能槽位(按触发时机排序:召唤→战斗开始→攻击后→受击后→死亡→常驻光环) */
private static readonly PANEL_TRIGGER_TYPES: SkillTriggerType[] = [ private static readonly PANEL_TRIGGER_TYPES: SkillTriggerType[] = [
SkillTriggerType.Call, SkillTriggerType.Call,