feat(战斗系统): 实现英雄复活机制并优化结算界面

- 在MissionComp中添加复活次数管理及复活成功回调
- 修改VictoryComp支持复活功能,包括广告复活和英雄状态恢复
- 调整结算界面布局和按钮显示逻辑
- 优化游戏结束流程,合并FightEnd逻辑
- 修改HeroViewComp中realDeadTime为更合理的值
This commit is contained in:
walkpan
2026-01-03 18:50:00 +08:00
parent acb564123d
commit b8fb70c0cf
4 changed files with 140 additions and 24 deletions

View File

@@ -962,7 +962,7 @@
},
"_lpos": {
"__type__": "cc.Vec3",
"x": -215,
"x": 0,
"y": 0,
"z": 0
},
@@ -1695,7 +1695,7 @@
"__id__": 68
}
],
"_active": true,
"_active": false,
"_components": [
{
"__id__": 74
@@ -2071,7 +2071,7 @@
},
"_contentSize": {
"__type__": "cc.Size",
"width": 745,
"width": 315,
"height": 100
},
"_anchorPoint": {

View File

@@ -45,7 +45,7 @@ export class HeroViewComp extends CCComp {
status:String = "idle"
scale: number = 1; // 显示方向
box_group:number = BoxSet.HERO; // 碰撞组
realDeadTime:number=10
realDeadTime:number=2
deadCD:number=0
monDeadTime:number=0.5
// 血条显示相关

View File

@@ -22,6 +22,10 @@ export class MissionComp extends CCComp {
// VictoryComp:any = null;
// reward:number = 0;
// reward_num:number = 0;
/** 剩余复活次数 */
revive_times: number = 1;
rewards:any[]=[]
game_data:any={
exp:0,
@@ -32,10 +36,11 @@ export class MissionComp extends CCComp {
this.on(GameEvent.MissionStart,this.mission_start,this)
this.on(GameEvent.MonDead,this.do_mon_dead,this)
this.on(GameEvent.HeroDead,this.do_hero_dead,this)
this.on(GameEvent.FightEnd,this.fight_end,this)
// this.on(GameEvent.FightEnd,this.fight_end,this)
this.on(GameEvent.MissionEnd,this.mission_end,this)
this.on(GameEvent.DO_AD_BACK,this.do_ad,this)
this.on(GameEvent.CanUpdateLv,this.onLevelUp,this)
this.on(GameEvent.ReviveSuccess, this.onReviveSuccess, this)
}
protected update(dt: number): void {
if(!smc.mission.play||smc.mission.pause){
@@ -80,7 +85,6 @@ export class MissionComp extends CCComp {
do_mon_dead(event:any,data:any){
// console.log("[MissionComp] do_mon_dead",event,data)
smc.vmdata.mission_data.mon_num--
// 计算并增加经验
// data 应该是怪物组件或包含怪物信息的对象
if (data && data.uuid) {
@@ -108,12 +112,10 @@ export class MissionComp extends CCComp {
}
do_hero_dead(event:any,data:any){
// console.log("[MissionComp] do_hero_dead",event,data)
// smc.vmdata.mission_data.hero_num--
// if(smc.vmdata.mission_data.hero_num<=0) {
// oops.message.dispatchEvent(GameEvent.FightEnd,{victory:false})
// oops.gui.open(UIID.Victory,{victory:false,rewards:this.rewards,game_data:this.game_data})
// }
// console.log("[MissionComp] do_hero_dead",event,data)
// 收到 HeroDead 说明已经没有复活次数了,打开失败界面,等待玩家选择(复活或结束)
// oops.message.dispatchEvent(GameEvent.FightEnd,{victory:false}) // 暂时不分发结束事件
this.open_Victory(null,true)
}
do_ad(){
if(this.ad_back()){
@@ -158,9 +160,26 @@ export class MissionComp extends CCComp {
}
to_end_fight(){
oops.message.dispatchEvent(GameEvent.FightEnd,{victory:false})
oops.gui.open(UIID.Victory,{victory:false,rewards:this.rewards,game_data:this.game_data})
open_Victory(e:any,is_hero_dead: boolean = false){
// 暂停游戏循环和怪物行为
// smc.mission.play = false;
smc.mission.stop_mon_action = true;
// oops.message.dispatchEvent(GameEvent.FightEnd,{victory:false})
console.log("[MissionComp] open_Victory",is_hero_dead,this.revive_times)
oops.gui.open(UIID.Victory,{
victory:false,
rewards:this.rewards,
game_data:this.game_data,
can_revive: is_hero_dead && this.revive_times > 0
})
}
/** 复活成功回调,扣除次数 */
onReviveSuccess() {
if (this.revive_times > 0) {
this.revive_times--;
console.log(`[MissionComp] 玩家复活,剩余次数: ${this.revive_times}`);
}
}
@@ -176,6 +195,11 @@ export class MissionComp extends CCComp {
mission_end(){
// console.log("[MissionComp] mission_end")
// 合并 FightEnd 逻辑:清理组件、停止游戏循环
smc.mission.play=false
smc.mission.pause=false
this.cleanComponents()
this.node.active=false
}
@@ -188,6 +212,7 @@ export class MissionComp extends CCComp {
smc.vmdata.mission_data.level=0
smc.vmdata.mission_data.time=15*60
this.rewards=[] // 改为数组,用于存储掉落物品列表
this.revive_times = 1; // 每次任务开始重置复活次数
// console.log("[MissionComp]局内数据初始化",smc.vmdata.mission_data)
}

View File

@@ -5,6 +5,10 @@ import { oops } from "../../../../extensions/oops-plugin-framework/assets/core/O
import { smc } from "../common/SingletonModuleComp";
import { GameEvent } from "../common/config/GameEvent";
import { it } from "node:test";
import { HeroAttrsComp } from "../hero/HeroAttrsComp";
import { HeroViewComp } from "../hero/HeroViewComp";
import { FacSet } from "../common/config/GameSet";
import { Attrs } from "../common/config/HeroAttrs";
const { ccclass, property } = _decorator;
@@ -20,24 +24,38 @@ export class VictoryComp extends CCComp {
exp:0,
gold:0,
diamond:0
}
}
// 复活相关配置
private canRevive: boolean = false; // 是否可以复活由MissionComp传入
// private reviveCount: number = 0; // 已复活次数 - 移交 MissionComp 管理
/** 视图层逻辑代码分离演示 */
protected onLoad(): void {
// this.canRevive = true;
// this.reviveCount = 0;
}
onAdded(args: any) {
// console.log("[VictoryComp] onAdded",args,smc.items)
console.log("[VictoryComp] onAdded",args)
if(args.game_data){
this.game_data=args.game_data
}
this.node.getChildByName("btns").getChildByName("next").active=false
this.scheduleOnce(()=>{
this.node.getChildByName("btns").getChildByName("next").active=true
},0.2)
// 接收复活参数
if (args.can_revive !== undefined) {
this.canRevive = args.can_revive;
} else {
this.canRevive = false; // 默认不可复活
}
this.node.getChildByName("btns").getChildByName("next").active=!args.can_revive
this.node.getChildByName("btns").getChildByName("alive").active=args.can_revive
}
victory_end(){
this.clear_data()
oops.message.dispatchEvent(GameEvent.MissionEnd)
@@ -53,9 +71,82 @@ export class VictoryComp extends CCComp {
double_reward(){
// console.log("[VictoryComp]double_reward",smc.items,this.rewards)
}
/** 看广告复活 */
watch_ad_revive() {
if (!this.canRevive) {
console.log("已经复活过,无法再次复活");
return;
}
// TODO: 接入广告SDK这里先模拟广告播放成功回调
this.onAdReviveSuccess();
}
/** 广告复活成功回调 */
private onAdReviveSuccess() {
console.log("[VictoryComp] 广告复活成功");
// 1. 标记已复活
// this.reviveCount++;
this.canRevive = false;
// 2. 执行复活逻辑
this.doReviveHero();
// 2.1 通知 MissionComp 扣除次数
oops.message.dispatchEvent(GameEvent.ReviveSuccess);
// 3. 恢复游戏状态
// smc.mission.play = true;
smc.mission.stop_mon_action = false;
// 4. 关闭结算界面
oops.gui.removeByNode(this.node);
}
/** 执行英雄复活逻辑 */
private doReviveHero() {
// 查找所有英雄实体并复活
const heroes = ecs.query(ecs.allOf(HeroAttrsComp, HeroViewComp));
let hasRevived = false;
heroes.forEach(e => {
const attrs = e.get(HeroAttrsComp);
const view = e.get(HeroViewComp);
if (attrs.fac === FacSet.HERO && attrs.is_dead) {
// 重置属性
attrs.is_dead = false;
attrs.hp = attrs.Attrs[Attrs.HP_MAX]; // 满血复活
attrs.mp = attrs.Attrs[Attrs.MP_MAX];
attrs.is_reviving = false;
// 视图层复活
if (view) {
view.alive();
}
hasRevived = true;
console.log(`[VictoryComp] 复活英雄: ${attrs.hero_name}`);
}
});
if (hasRevived) {
// 发送复活事件(如果有需要)
// oops.message.dispatchEvent(GameEvent.HeroRevived);
} else {
console.warn("[VictoryComp] 未找到可复活的英雄实体");
}
}
restart(){
this.clear_data()
oops.message.dispatchEvent(GameEvent.MissionStart)
// 确保游戏结束事件被触发,以便重置状态
oops.message.dispatchEvent(GameEvent.MissionEnd)
this.scheduleOnce(()=>{
oops.message.dispatchEvent(GameEvent.MissionStart)
},0.5)
oops.gui.removeByNode(this.node)
}
item_show(e:any,val:any){