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){
|
private async call_hero(event: string, args: any){
|
||||||
|
if (this.is_merging) return;
|
||||||
const uuid = Number(args?.uuid ?? 1001);
|
const uuid = Number(args?.uuid ?? 1001);
|
||||||
const hero_lv = Math.max(1, Number(args?.hero_lv ?? 1));
|
const hero_lv = Math.max(1, Number(args?.hero_lv ?? 1));
|
||||||
|
this.addHero(uuid, hero_lv);
|
||||||
const aliveHeroes = this.getAliveHeroes();
|
const aliveHeroes = this.getAliveHeroes();
|
||||||
const mergeHeroes = this.pickMergeHeroes(aliveHeroes, uuid, hero_lv);
|
const mergeHeroes = this.pickMergeHeroes(aliveHeroes, uuid, hero_lv, 3);
|
||||||
if (mergeHeroes.length === 2) {
|
if (mergeHeroes.length === 3) {
|
||||||
if (this.is_merging) return;
|
|
||||||
this.is_merging = true;
|
this.is_merging = true;
|
||||||
try {
|
try {
|
||||||
let sumAp = 0;
|
const mergedLv = await this.mergeGroupHeroes(mergeHeroes, uuid, hero_lv);
|
||||||
let sumHpMax = 0;
|
await this.tryChainMerge(uuid, mergedLv);
|
||||||
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);
|
|
||||||
} finally {
|
} finally {
|
||||||
this.is_merging = false;
|
this.is_merging = false;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.addHero(uuid, hero_lv);
|
|
||||||
}
|
}
|
||||||
/** 添加英雄 */
|
/** 添加英雄 */
|
||||||
private addHero(uuid:number=1001,hero_lv:number=1) {
|
private addHero(uuid:number=1001,hero_lv:number=1) {
|
||||||
@@ -99,14 +87,15 @@ export class MissionHeroCompComp extends CCComp {
|
|||||||
return hero;
|
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 hero = this.addHero(uuid, hero_lv);
|
||||||
const model = hero.get(HeroAttrsComp);
|
const model = hero.get(HeroAttrsComp);
|
||||||
if (!model) return;
|
if (!model) return hero_lv;
|
||||||
model.ap = Math.max(0, ap);
|
model.ap = Math.max(0, ap);
|
||||||
model.hp_max = Math.max(1, hp_max);
|
model.hp_max = Math.max(1, hp_max);
|
||||||
model.hp = model.hp_max;
|
model.hp = model.hp_max;
|
||||||
model.dirty_hp = true;
|
model.dirty_hp = true;
|
||||||
|
return model.lv;
|
||||||
}
|
}
|
||||||
|
|
||||||
private getAliveHeroes(): Hero[] {
|
private getAliveHeroes(): Hero[] {
|
||||||
@@ -121,7 +110,7 @@ export class MissionHeroCompComp extends CCComp {
|
|||||||
return heroes;
|
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[] = [];
|
const mergeHeroes: Hero[] = [];
|
||||||
for (let i = 0; i < aliveHeroes.length; i++) {
|
for (let i = 0; i < aliveHeroes.length; i++) {
|
||||||
const model = aliveHeroes[i].get(HeroAttrsComp);
|
const model = aliveHeroes[i].get(HeroAttrsComp);
|
||||||
@@ -129,11 +118,23 @@ export class MissionHeroCompComp extends CCComp {
|
|||||||
if (model.hero_uuid !== uuid) continue;
|
if (model.hero_uuid !== uuid) continue;
|
||||||
if (model.lv !== hero_lv) continue;
|
if (model.lv !== hero_lv) continue;
|
||||||
mergeHeroes.push(aliveHeroes[i]);
|
mergeHeroes.push(aliveHeroes[i]);
|
||||||
if (mergeHeroes.length === 2) break;
|
if (mergeHeroes.length === needCount) break;
|
||||||
}
|
}
|
||||||
return mergeHeroes;
|
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> {
|
private mergeDestroyAtBirth(mergeHeroes: Hero[], spawnPos: Vec3): Promise<void> {
|
||||||
return new Promise((resolve) => {
|
return new Promise((resolve) => {
|
||||||
let doneCount = 0;
|
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