feat(英雄合并): 支持三合一合并并实现链式合并
- 将合并条件从两个英雄改为三个英雄 - 重构合并逻辑,提取 mergeGroupHeroes 方法处理合并过程 - 新增链式合并功能,当满足条件时自动触发连续合并 - 添加 countMergeHeroes 方法统计可合并英雄数量 - 优化代码结构,提高可维护性
This commit is contained in:
@@ -58,34 +58,22 @@ export class MissionHeroCompComp extends CCComp {
|
||||
}
|
||||
|
||||
private async call_hero(event: string, args: any){
|
||||
if (this.is_merging) return;
|
||||
const uuid = Number(args?.uuid ?? 1001);
|
||||
const hero_lv = Math.max(1, Number(args?.hero_lv ?? 1));
|
||||
this.addHero(uuid, hero_lv);
|
||||
const aliveHeroes = this.getAliveHeroes();
|
||||
const mergeHeroes = this.pickMergeHeroes(aliveHeroes, uuid, hero_lv);
|
||||
if (mergeHeroes.length === 2) {
|
||||
if (this.is_merging) return;
|
||||
const mergeHeroes = this.pickMergeHeroes(aliveHeroes, uuid, hero_lv, 3);
|
||||
if (mergeHeroes.length === 3) {
|
||||
this.is_merging = true;
|
||||
try {
|
||||
let sumAp = 0;
|
||||
let sumHpMax = 0;
|
||||
for (let i = 0; i < mergeHeroes.length; i++) {
|
||||
const model = mergeHeroes[i].get(HeroAttrsComp);
|
||||
if (!model) continue;
|
||||
sumAp += model.ap;
|
||||
sumHpMax += model.hp_max;
|
||||
}
|
||||
let hero_pos = 0;
|
||||
const landingPos:Vec3 = HeroPos[hero_pos].pos;
|
||||
const spawnPos:Vec3 = v3(landingPos.x, landingPos.y + MissionHeroCompComp.HERO_DROP_HEIGHT, 0);
|
||||
await this.mergeDestroyAtBirth(mergeHeroes, spawnPos);
|
||||
await this.playMergeBoomFx(spawnPos);
|
||||
this.addMergedHero(uuid, hero_lv + 1, sumAp, sumHpMax);
|
||||
const mergedLv = await this.mergeGroupHeroes(mergeHeroes, uuid, hero_lv);
|
||||
await this.tryChainMerge(uuid, mergedLv);
|
||||
} finally {
|
||||
this.is_merging = false;
|
||||
}
|
||||
return;
|
||||
}
|
||||
this.addHero(uuid, hero_lv);
|
||||
}
|
||||
/** 添加英雄 */
|
||||
private addHero(uuid:number=1001,hero_lv:number=1) {
|
||||
@@ -99,14 +87,15 @@ export class MissionHeroCompComp extends CCComp {
|
||||
return hero;
|
||||
}
|
||||
|
||||
private addMergedHero(uuid:number, hero_lv:number, ap:number, hp_max:number) {
|
||||
private addMergedHero(uuid:number, hero_lv:number, ap:number, hp_max:number): number {
|
||||
const hero = this.addHero(uuid, hero_lv);
|
||||
const model = hero.get(HeroAttrsComp);
|
||||
if (!model) return;
|
||||
if (!model) return hero_lv;
|
||||
model.ap = Math.max(0, ap);
|
||||
model.hp_max = Math.max(1, hp_max);
|
||||
model.hp = model.hp_max;
|
||||
model.dirty_hp = true;
|
||||
return model.lv;
|
||||
}
|
||||
|
||||
private getAliveHeroes(): Hero[] {
|
||||
@@ -121,7 +110,7 @@ export class MissionHeroCompComp extends CCComp {
|
||||
return heroes;
|
||||
}
|
||||
|
||||
private pickMergeHeroes(aliveHeroes: Hero[], uuid: number, hero_lv: number): Hero[] {
|
||||
private pickMergeHeroes(aliveHeroes: Hero[], uuid: number, hero_lv: number, needCount: number = 3): Hero[] {
|
||||
const mergeHeroes: Hero[] = [];
|
||||
for (let i = 0; i < aliveHeroes.length; i++) {
|
||||
const model = aliveHeroes[i].get(HeroAttrsComp);
|
||||
@@ -129,11 +118,23 @@ export class MissionHeroCompComp extends CCComp {
|
||||
if (model.hero_uuid !== uuid) continue;
|
||||
if (model.lv !== hero_lv) continue;
|
||||
mergeHeroes.push(aliveHeroes[i]);
|
||||
if (mergeHeroes.length === 2) break;
|
||||
if (mergeHeroes.length === needCount) break;
|
||||
}
|
||||
return mergeHeroes;
|
||||
}
|
||||
|
||||
private countMergeHeroes(aliveHeroes: Hero[], uuid: number, hero_lv: number): number {
|
||||
let count = 0;
|
||||
for (let i = 0; i < aliveHeroes.length; i++) {
|
||||
const model = aliveHeroes[i].get(HeroAttrsComp);
|
||||
if (!model) continue;
|
||||
if (model.hero_uuid !== uuid) continue;
|
||||
if (model.lv !== hero_lv) continue;
|
||||
count += 1;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
private mergeDestroyAtBirth(mergeHeroes: Hero[], spawnPos: Vec3): Promise<void> {
|
||||
return new Promise((resolve) => {
|
||||
let doneCount = 0;
|
||||
@@ -179,6 +180,41 @@ export class MissionHeroCompComp extends CCComp {
|
||||
});
|
||||
}
|
||||
|
||||
private async mergeGroupHeroes(mergeHeroes: Hero[], uuid: number, hero_lv: number): Promise<number> {
|
||||
let sumAp = 0;
|
||||
let sumHpMax = 0;
|
||||
for (let i = 0; i < mergeHeroes.length; i++) {
|
||||
const model = mergeHeroes[i].get(HeroAttrsComp);
|
||||
if (!model) continue;
|
||||
sumAp += model.ap;
|
||||
sumHpMax += model.hp_max;
|
||||
}
|
||||
let hero_pos = 0;
|
||||
const landingPos:Vec3 = HeroPos[hero_pos].pos;
|
||||
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, hero_lv + 1, sumAp, sumHpMax);
|
||||
}
|
||||
|
||||
private async tryChainMerge(uuid: number, startLv: number) {
|
||||
let checkLv = Math.max(1, startLv);
|
||||
let guard = 0;
|
||||
while (guard < 20) {
|
||||
guard += 1;
|
||||
const aliveHeroes = this.getAliveHeroes();
|
||||
const sameCount = this.countMergeHeroes(aliveHeroes, uuid, checkLv);
|
||||
if (sameCount < 3) {
|
||||
break;
|
||||
}
|
||||
const mergeHeroes = this.pickMergeHeroes(aliveHeroes, uuid, checkLv, 3);
|
||||
if (mergeHeroes.length < 3) {
|
||||
break;
|
||||
}
|
||||
checkLv = await this.mergeGroupHeroes(mergeHeroes, uuid, checkLv);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user