feat(hero card): add upgrade reminder feature
1. 新增英雄升级配置判定模块,封装升级条件校验逻辑 2. 为卡牌组件添加可升级标识节点和刷新逻辑 3. 实现英雄列表面板统一刷新所有卡牌的升级标识 4. 监听英雄成长变更事件实时更新升级提示状态
This commit is contained in:
@@ -4560,6 +4560,9 @@
|
|||||||
"lvl_node": {
|
"lvl_node": {
|
||||||
"__id__": 293
|
"__id__": 293
|
||||||
},
|
},
|
||||||
|
"canup_node": {
|
||||||
|
"__id__": 304
|
||||||
|
},
|
||||||
"_id": ""
|
"_id": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
77
assets/script/game/common/config/heroUpSet.ts
Normal file
77
assets/script/game/common/config/heroUpSet.ts
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
/**
|
||||||
|
* @file heroUpSet.ts
|
||||||
|
* @description 英雄局外升级规则与判定逻辑(纯逻辑模块,无 UI / 无单例依赖)
|
||||||
|
*
|
||||||
|
* 职责:
|
||||||
|
* 1. 封装 HERO_UPGRADE_NEED_FRAGMENTS 升级消耗表的查询口径(满级判定)。
|
||||||
|
* 2. 提供"是否可升级"的统一判定,供 smc.upgradeHero / HerosListComp / CardLiteComp 复用。
|
||||||
|
*
|
||||||
|
* 关键设计:
|
||||||
|
* - 不直接引用 smc 单例,由调用方传入成长数据(lv / fragments),保持纯函数可测试。
|
||||||
|
* - 升级表 key 为目标等级:need = HERO_UPGRADE_NEED_FRAGMENTS[lv + 1],查不到即满级。
|
||||||
|
*/
|
||||||
|
import { HERO_UPGRADE_NEED_FRAGMENTS } from "./GameSet";
|
||||||
|
|
||||||
|
/** 英雄升级状态快照 */
|
||||||
|
export interface HeroUpgradeState {
|
||||||
|
/** 当前局外等级 */
|
||||||
|
lv: number;
|
||||||
|
/** 下一级(满级时为当前等级) */
|
||||||
|
nextLv: number;
|
||||||
|
/** 当前拥有碎片数 */
|
||||||
|
fragments: number;
|
||||||
|
/** 升到下一级所需碎片数(满级为 0) */
|
||||||
|
needFragments: number;
|
||||||
|
/** 是否已满级 */
|
||||||
|
isMaxLv: boolean;
|
||||||
|
/** 是否满足升级条件(未满级且碎片充足) */
|
||||||
|
canUpgrade: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 英雄最高局外等级(升级表最大 key - 1) */
|
||||||
|
export const HERO_MAX_LV: number = Math.max(...Object.keys(HERO_UPGRADE_NEED_FRAGMENTS).map(Number)) - 1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询从当前等级升到下一级所需的碎片数。
|
||||||
|
* @param lv 当前局外等级
|
||||||
|
* @returns 所需碎片数;已满级返回 undefined
|
||||||
|
*/
|
||||||
|
export function getHeroUpgradeNeedFragments(lv: number): number | undefined {
|
||||||
|
return HERO_UPGRADE_NEED_FRAGMENTS[lv + 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断英雄当前等级是否已满级。
|
||||||
|
* @param lv 当前局外等级
|
||||||
|
*/
|
||||||
|
export function isHeroMaxLv(lv: number): boolean {
|
||||||
|
return getHeroUpgradeNeedFragments(lv) === undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断英雄是否满足升级条件(未满级且碎片充足)。
|
||||||
|
* @param lv 当前局外等级
|
||||||
|
* @param fragments 当前拥有碎片数
|
||||||
|
*/
|
||||||
|
export function canHeroUpgrade(lv: number, fragments: number): boolean {
|
||||||
|
const need = getHeroUpgradeNeedFragments(lv);
|
||||||
|
return need !== undefined && fragments >= need;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 汇总英雄升级状态快照(供 UI 一次性取用,避免重复查表)。
|
||||||
|
* @param lv 当前局外等级
|
||||||
|
* @param fragments 当前拥有碎片数
|
||||||
|
*/
|
||||||
|
export function getHeroUpgradeState(lv: number, fragments: number): HeroUpgradeState {
|
||||||
|
const need = getHeroUpgradeNeedFragments(lv);
|
||||||
|
const isMax = need === undefined;
|
||||||
|
return {
|
||||||
|
lv,
|
||||||
|
nextLv: isMax ? lv : lv + 1,
|
||||||
|
fragments,
|
||||||
|
needFragments: need ?? 0,
|
||||||
|
isMaxLv: isMax,
|
||||||
|
canUpgrade: !isMax && fragments >= (need as number),
|
||||||
|
};
|
||||||
|
}
|
||||||
9
assets/script/game/common/config/heroUpSet.ts.meta
Normal file
9
assets/script/game/common/config/heroUpSet.ts.meta
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"ver": "4.0.24",
|
||||||
|
"importer": "typescript",
|
||||||
|
"imported": true,
|
||||||
|
"uuid": "621f3327-35b6-4b26-92f6-7f3c2abe74b7",
|
||||||
|
"files": [],
|
||||||
|
"subMetas": {},
|
||||||
|
"userData": {}
|
||||||
|
}
|
||||||
@@ -6,22 +6,28 @@
|
|||||||
* 1. 管理英雄图鉴中单张英雄卡牌的 **显示**(名称、图标动画、卡池等级、英雄等级)。
|
* 1. 管理英雄图鉴中单张英雄卡牌的 **显示**(名称、图标动画、卡池等级、英雄等级)。
|
||||||
* 2. 接收英雄 UUID 并渲染对应卡面。
|
* 2. 接收英雄 UUID 并渲染对应卡面。
|
||||||
* 3. 点击卡牌时通过事件通知父组件(HerosListComp)切换选中英雄详情。
|
* 3. 点击卡牌时通过事件通知父组件(HerosListComp)切换选中英雄详情。
|
||||||
|
* 4. 英雄碎片满足升级条件时显示 canup 标识。
|
||||||
*
|
*
|
||||||
* 关键设计:
|
* 关键设计:
|
||||||
* - 轻量展示组件,仅用于英雄展示,无拖拽使用、无锁定、无费用扣除等交互。
|
* - 轻量展示组件,仅用于英雄展示,无拖拽使用、无锁定、无费用扣除等交互。
|
||||||
* - 英雄卡图标加载 idle 动画剪辑并提取首帧静态展示。
|
* - 英雄卡图标加载 idle 动画剪辑并提取首帧静态展示。
|
||||||
* - 通过 iconVisualToken 防止异步加载竞态。
|
* - 通过 iconVisualToken 防止异步加载竞态。
|
||||||
|
* - canup 标识监听 HERO_GROWTH_UPDATE 事件实时刷新(碎片变动/升级后自动更新)。
|
||||||
*
|
*
|
||||||
* 依赖:
|
* 依赖:
|
||||||
* - HeroInfo(heroSet)—— 用于渲染英雄卡面信息
|
* - HeroInfo(heroSet)—— 用于渲染英雄卡面信息
|
||||||
|
* - canHeroUpgrade(heroUpSet)—— 英雄升级条件判定
|
||||||
* - smc —— 全局单例,访问图标图集缓存与英雄局外等级
|
* - smc —— 全局单例,访问图标图集缓存与英雄局外等级
|
||||||
*/
|
*/
|
||||||
import { mLogger } from "../common/Logger";
|
import { mLogger } from "../common/Logger";
|
||||||
import { _decorator, AnimationClip, EventTouch, Label, Node, NodeEventType, Sprite, SpriteFrame, Tween, tween, UIOpacity, Vec3, resources } from "cc";
|
import { _decorator, AnimationClip, EventTouch, Label, Node, NodeEventType, Sprite, SpriteFrame, Tween, tween, UIOpacity, Vec3, resources } 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 { HeroInfo } from "../common/config/heroSet";
|
import { HeroInfo } from "../common/config/heroSet";
|
||||||
import { getLvColor, CARD_LV_BG_COLORS } from "../common/config/GameSet";
|
import { getLvColor, CARD_LV_BG_COLORS } from "../common/config/GameSet";
|
||||||
|
import { canHeroUpgrade } from "../common/config/heroUpSet";
|
||||||
|
import { GameEvent } from "../common/config/GameEvent";
|
||||||
import { smc } from "../common/SingletonModuleComp";
|
import { smc } from "../common/SingletonModuleComp";
|
||||||
|
|
||||||
const { ccclass, property } = _decorator;
|
const { ccclass, property } = _decorator;
|
||||||
@@ -55,6 +61,10 @@ export class CardLiteComp extends CCComp {
|
|||||||
@property(Label)
|
@property(Label)
|
||||||
lvl_node: Label = null!
|
lvl_node: Label = null!
|
||||||
|
|
||||||
|
/** 可升级标识节点(碎片满足升级条件时显示) */
|
||||||
|
@property(Node)
|
||||||
|
canup_node: Node = null!
|
||||||
|
|
||||||
// ======================== 运行时状态 ========================
|
// ======================== 运行时状态 ========================
|
||||||
|
|
||||||
card_uuid: number = 0
|
card_uuid: number = 0
|
||||||
@@ -108,9 +118,24 @@ export class CardLiteComp extends CCComp {
|
|||||||
clear() {
|
clear() {
|
||||||
this.card_uuid = 0;
|
this.card_uuid = 0;
|
||||||
this.applyEmptyUI();
|
this.applyEmptyUI();
|
||||||
|
if (this.canup_node) this.canup_node.active = false;
|
||||||
this.node.active = false;
|
this.node.active = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 刷新可升级标识:碎片满足升级条件时显示 canup 节点。
|
||||||
|
* 渲染时自动调用一次;升级后由 HerosListComp 统一触发刷新。
|
||||||
|
*/
|
||||||
|
refreshCanUp() {
|
||||||
|
if (!this.canup_node) return;
|
||||||
|
if (!this.hasCard()) {
|
||||||
|
this.canup_node.active = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const growth = smc.getHeroGrowth(this.card_uuid);
|
||||||
|
this.canup_node.active = canHeroUpgrade(growth.lv, growth.fragments);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 设置选中态:选中卡微微放大,取消选中恢复原尺寸。
|
* 设置选中态:选中卡微微放大,取消选中恢复原尺寸。
|
||||||
* @param selected 是否选中
|
* @param selected 是否选中
|
||||||
|
|||||||
@@ -168,6 +168,15 @@ export class HerosListComp extends CCComp {
|
|||||||
if (this.huuid) {
|
if (this.huuid) {
|
||||||
this.updateHeroDetail(this.huuid)
|
this.updateHeroDetail(this.huuid)
|
||||||
}
|
}
|
||||||
|
this.refreshAllCardsCanUp()
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 升级/碎片变动后统一刷新所有卡片的可升级标识(升级入口仅在本面板,无需卡片各自监听事件) */
|
||||||
|
private refreshAllCardsCanUp() {
|
||||||
|
if (!this.cards_node) return
|
||||||
|
this.cards_node.children.forEach(cardNode => {
|
||||||
|
cardNode.getComponent(CardLiteComp)?.refreshCanUp()
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
closeHeros() {
|
closeHeros() {
|
||||||
|
|||||||
Reference in New Issue
Block a user