feat: 新增卡牌等级系统并调整英雄合成规则
- 在 HeroAttrsComp 中添加 card_lv 属性,用于独立记录卡牌等级 - 修改 Hero 加载逻辑,支持传入 card_lv 参数 - 更新 HInfoComp 的 UI 刷新逻辑,根据英雄等级和卡牌等级显示不同的边框和等级图标 - 调整 MissionHeroComp 的合成规则:所需合成数量从 2 改为 3,最高合成等级从 3 改为 2 - 在召唤队列和合成流程中传递并处理 card_lv 数据,确保卡牌等级在合成过程中得以保留
This commit is contained in:
@@ -192,7 +192,8 @@ export class CardComp extends CCComp {
|
||||
cancel: false,
|
||||
reason: "",
|
||||
uuid: this.cardData.uuid,
|
||||
hero_lv: this.cardData.hero_lv
|
||||
hero_lv: this.cardData.hero_lv,
|
||||
card_lv: this.cardData.card_lv
|
||||
};
|
||||
oops.message.dispatchEvent(GameEvent.UseHeroCard, guard);
|
||||
if (guard.cancel) {
|
||||
|
||||
@@ -50,7 +50,19 @@ export class HInfoComp extends CCComp {
|
||||
|
||||
refresh() {
|
||||
if (!this.model) return;
|
||||
this.updateLevelUI();
|
||||
|
||||
const isHighLevel = (this.model.lv ?? 0) > 1;
|
||||
if (this.HF_node) this.HF_node.active = isHighLevel;
|
||||
if (this.NF_node) this.NF_node.active = !isHighLevel;
|
||||
|
||||
const activeFrameNode = isHighLevel ? this.HF_node : this.NF_node;
|
||||
if (activeFrameNode) {
|
||||
const cardLvStr = `lv${this.model.card_lv ?? 1}`;
|
||||
activeFrameNode.children.forEach(child => {
|
||||
child.active = (child.name === cardLvStr);
|
||||
});
|
||||
}
|
||||
|
||||
const heroUuid = this.model.hero_uuid ?? 0;
|
||||
if (heroUuid !== this.iconHeroUuid) {
|
||||
this.iconHeroUuid = heroUuid;
|
||||
@@ -87,16 +99,7 @@ export class HInfoComp extends CCComp {
|
||||
return current.getComponent(Label) || current.getComponentInChildren(Label);
|
||||
}
|
||||
|
||||
private updateLevelUI() {
|
||||
if (!this.model) return;
|
||||
const lvNode = this.node.getChildByName("lv");
|
||||
if (!lvNode) return;
|
||||
lvNode.active = true
|
||||
const lv2 = lvNode.getChildByName("lv2");
|
||||
if (lv2) lv2.active = this.model.lv >= 2;
|
||||
const lv3 = lvNode.getChildByName("lv3");
|
||||
if (lv3) lv3.active = this.model.lv >= 3;
|
||||
}
|
||||
|
||||
|
||||
private updateHeroAnimation(node: Node, uuid: number, token: number) {
|
||||
if (!node) return;
|
||||
|
||||
@@ -234,6 +234,7 @@ export class MissionCardComp extends CCComp {
|
||||
if (current >= heroMax) {
|
||||
const heroUuid = Number(payload?.uuid ?? 0);
|
||||
const heroLv = Math.max(1, Math.floor(Number(payload?.hero_lv ?? 1)));
|
||||
const cardLv = Math.max(1, Math.floor(Number(payload?.card_lv ?? 1)));
|
||||
if (this.canUseHeroCardByMerge(heroUuid, heroLv)) {
|
||||
payload.cancel = false;
|
||||
payload.reason = "";
|
||||
|
||||
@@ -31,15 +31,15 @@ export class MissionHeroCompComp extends CCComp {
|
||||
/** 当前英雄数量缓存 */
|
||||
current_hero_num:number=-1
|
||||
/** 合成规则:2 合 1 或 3 合 1 */
|
||||
merge_need_count:number=2
|
||||
merge_need_count:number=3
|
||||
/** 允许合成的最高等级 */
|
||||
merge_max_lv:number=3
|
||||
merge_max_lv:number=2
|
||||
/** 是否正在执行一次合成流程 */
|
||||
is_merging:boolean=false
|
||||
/** 是否正在消费召唤队列,防止并发处理 */
|
||||
is_processing_queue:boolean=false
|
||||
/** 召唤请求队列,保证召唤与合成串行 */
|
||||
summon_queue:{ uuid: number; hero_lv: number }[]=[]
|
||||
summon_queue:{ uuid: number; hero_lv: number; card_lv: number }[]=[]
|
||||
/** 预留英雄列表 */
|
||||
heros:any=[]
|
||||
onLoad(){
|
||||
@@ -84,19 +84,21 @@ export class MissionHeroCompComp extends CCComp {
|
||||
|
||||
/** 召唤请求入口:归一化参数并进入串行队列 */
|
||||
private async call_hero(event: string, args: any){
|
||||
const uuid = Number(args?.uuid ?? 1001);
|
||||
const hero_lv = Math.max(1, Number(args?.hero_lv ?? 1));
|
||||
this.summon_queue.push({ uuid, hero_lv });
|
||||
const payload = args ?? event;
|
||||
const uuid = Number(payload?.uuid ?? 1001);
|
||||
const hero_lv = Math.max(1, Number(payload?.hero_lv ?? 1));
|
||||
const card_lv = Math.max(1, Number(payload?.card_lv ?? 1));
|
||||
this.summon_queue.push({ uuid, hero_lv, card_lv });
|
||||
this.processSummonQueue();
|
||||
}
|
||||
/** 添加英雄:固定出生点上方生成,再落至落点 */
|
||||
private addHero(uuid:number=1001,hero_lv:number=1) {
|
||||
private addHero(uuid:number=1001,hero_lv:number=1, card_lv:number=1) {
|
||||
console.log("addHero uuid:",uuid)
|
||||
let hero = ecs.getEntity<Hero>(Hero);
|
||||
let scale = 1
|
||||
const landingPos = this.resolveHeroLandingPos(uuid);
|
||||
let spawnPos:Vec3 = v3(landingPos.x, landingPos.y + MissionHeroCompComp.HERO_DROP_HEIGHT, 0);
|
||||
hero.load(spawnPos,scale,uuid,landingPos.y,hero_lv);
|
||||
hero.load(spawnPos,scale,uuid,landingPos.y,hero_lv,card_lv);
|
||||
return hero;
|
||||
}
|
||||
|
||||
@@ -115,8 +117,8 @@ export class MissionHeroCompComp extends CCComp {
|
||||
}
|
||||
|
||||
/** 添加合成后的新英雄,并覆盖为聚合后的属性 */
|
||||
private addMergedHero(uuid:number, hero_lv:number, ap:number, hp_max:number): number {
|
||||
const hero = this.addHero(uuid, hero_lv);
|
||||
private addMergedHero(uuid:number, hero_lv:number, card_lv:number, ap:number, hp_max:number): number {
|
||||
const hero = this.addHero(uuid, hero_lv, card_lv);
|
||||
const model = hero.get(HeroAttrsComp);
|
||||
if (!model) return hero_lv;
|
||||
model.ap = Math.max(0, ap);
|
||||
@@ -184,7 +186,7 @@ export class MissionHeroCompComp extends CCComp {
|
||||
while (this.summon_queue.length > 0) {
|
||||
const payload = this.summon_queue.shift();
|
||||
if (!payload) continue;
|
||||
await this.handleSingleSummon(payload.uuid, payload.hero_lv);
|
||||
await this.handleSingleSummon(payload.uuid, payload.hero_lv, payload.card_lv);
|
||||
}
|
||||
} finally {
|
||||
this.is_processing_queue = false;
|
||||
@@ -192,8 +194,8 @@ export class MissionHeroCompComp extends CCComp {
|
||||
}
|
||||
|
||||
/** 处理单次召唤:先生成,再检测是否触发合成,再尝试链式合成 */
|
||||
private async handleSingleSummon(uuid: number, hero_lv: number) {
|
||||
this.addHero(uuid, hero_lv);
|
||||
private async handleSingleSummon(uuid: number, hero_lv: number, card_lv: number = 1) {
|
||||
this.addHero(uuid, hero_lv, card_lv);
|
||||
if (!this.canMergeLevel(hero_lv)) return;
|
||||
const needCount = this.getMergeNeedCount();
|
||||
const aliveHeroes = this.getAliveHeroes();
|
||||
@@ -201,8 +203,8 @@ export class MissionHeroCompComp extends CCComp {
|
||||
if (mergeHeroes.length !== needCount) return;
|
||||
this.is_merging = true;
|
||||
try {
|
||||
const mergedLv = await this.mergeGroupHeroes(mergeHeroes, uuid, hero_lv);
|
||||
await this.tryChainMerge(uuid, mergedLv);
|
||||
const mergedLv = await this.mergeGroupHeroes(mergeHeroes, uuid, hero_lv, card_lv);
|
||||
await this.tryChainMerge(uuid, mergedLv, card_lv);
|
||||
} finally {
|
||||
this.is_merging = false;
|
||||
}
|
||||
@@ -256,7 +258,7 @@ export class MissionHeroCompComp extends CCComp {
|
||||
}
|
||||
|
||||
/** 执行一次完整合成:聚合属性、销毁素材、播放特效、生成高一级英雄 */
|
||||
private async mergeGroupHeroes(mergeHeroes: Hero[], uuid: number, hero_lv: number): Promise<number> {
|
||||
private async mergeGroupHeroes(mergeHeroes: Hero[], uuid: number, hero_lv: number, card_lv: number): Promise<number> {
|
||||
let sumAp = 0;
|
||||
let sumHpMax = 0;
|
||||
for (let i = 0; i < mergeHeroes.length; i++) {
|
||||
@@ -269,11 +271,11 @@ export class MissionHeroCompComp extends CCComp {
|
||||
const spawnPos:Vec3 = v3(landingPos.x, landingPos.y + MissionHeroCompComp.HERO_DROP_HEIGHT, 0);
|
||||
await this.mergeDestroyAtBirth(mergeHeroes, spawnPos);
|
||||
await this.playMergeBoomFx(spawnPos);
|
||||
return this.addMergedHero(uuid, Math.min(this.merge_max_lv, hero_lv + 1), sumAp, sumHpMax);
|
||||
return this.addMergedHero(uuid, Math.min(this.merge_max_lv, hero_lv + 1), card_lv, sumAp, sumHpMax);
|
||||
}
|
||||
|
||||
/** 链式合成:当前等级合成完成后,继续尝试更高等级,直到条件不满足 */
|
||||
private async tryChainMerge(uuid: number, startLv: number) {
|
||||
private async tryChainMerge(uuid: number, startLv: number, card_lv: number) {
|
||||
let checkLv = Math.max(1, startLv);
|
||||
const needCount = this.getMergeNeedCount();
|
||||
let guard = 0;
|
||||
@@ -291,7 +293,7 @@ export class MissionHeroCompComp extends CCComp {
|
||||
if (mergeHeroes.length < needCount) {
|
||||
break;
|
||||
}
|
||||
checkLv = await this.mergeGroupHeroes(mergeHeroes, uuid, checkLv);
|
||||
checkLv = await this.mergeGroupHeroes(mergeHeroes, uuid, checkLv, card_lv);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user