feat(HeroAtkSystem): Integrate visual feedback for attack and death events
- Added HeroViewComp integration to trigger visual effects during attacks and upon hero death. - Updated doAttack method to call do_atked and do_dead methods in HeroViewComp for enhanced visual representation. - Cleaned up console log messages for better clarity in debugging.
This commit is contained in:
@@ -4,6 +4,7 @@ import { Attrs } from "../common/config/HeroAttrs";
|
|||||||
import { FightSet } from "../common/config/Mission";
|
import { FightSet } from "../common/config/Mission";
|
||||||
import { SkillSet } from "../common/config/SkillSet";
|
import { SkillSet } from "../common/config/SkillSet";
|
||||||
import { HeroAttrsComp } from "./HeroAttrsComp";
|
import { HeroAttrsComp } from "./HeroAttrsComp";
|
||||||
|
import { HeroViewComp } from "./HeroViewComp";
|
||||||
|
|
||||||
/** 业务层对象 */
|
/** 业务层对象 */
|
||||||
@ecs.register('HeroAtk')
|
@ecs.register('HeroAtk')
|
||||||
@@ -46,6 +47,7 @@ export class HeroAtkSystem extends ecs.ComblockSystem implements ecs.ISystemUpd
|
|||||||
*/
|
*/
|
||||||
public doAttack(target: ecs.Entity, remainingDamage: number, attackerAttrs: any, skillId: number): number {
|
public doAttack(target: ecs.Entity, remainingDamage: number, attackerAttrs: any, skillId: number): number {
|
||||||
const targetModel = target.get(HeroAttrsComp);
|
const targetModel = target.get(HeroAttrsComp);
|
||||||
|
const targetView = target.get(HeroViewComp);
|
||||||
if (!targetModel || targetModel.is_dead) return 0;
|
if (!targetModel || targetModel.is_dead) return 0;
|
||||||
|
|
||||||
// 获取技能配置
|
// 获取技能配置
|
||||||
@@ -56,6 +58,7 @@ export class HeroAtkSystem extends ecs.ComblockSystem implements ecs.ISystemUpd
|
|||||||
|
|
||||||
// 闪避判定
|
// 闪避判定
|
||||||
if (this.checkDodge(targetModel)) {
|
if (this.checkDodge(targetModel)) {
|
||||||
|
// TODO: 触发闪避视图表现
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -75,17 +78,26 @@ export class HeroAtkSystem extends ecs.ComblockSystem implements ecs.ISystemUpd
|
|||||||
|
|
||||||
if (damage <= 0) return 0;
|
if (damage <= 0) return 0;
|
||||||
|
|
||||||
// 应用伤害
|
// 应用伤害到数据层
|
||||||
targetModel.hp -= damage;
|
targetModel.hp -= damage;
|
||||||
targetModel.atked_count++;
|
targetModel.atked_count++;
|
||||||
|
|
||||||
|
// ✅ 触发视图层表现(伤害数字、受击动画、后退)
|
||||||
|
if (targetView) {
|
||||||
|
targetView.do_atked(damage, isCrit, skillId);
|
||||||
|
}
|
||||||
|
|
||||||
// 检查死亡
|
// 检查死亡
|
||||||
if (targetModel.hp <= 0) {
|
if (targetModel.hp <= 0) {
|
||||||
this.doDead(target);
|
this.doDead(target);
|
||||||
|
// ✅ 触发死亡视图表现
|
||||||
|
if (targetView) {
|
||||||
|
targetView.do_dead();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.debugMode) {
|
if (this.debugMode) {
|
||||||
console.log(`[HeroBattleSystem] ${targetModel.hero_name} 受到 ${damage} 点伤害 (暴击: ${isCrit})`);
|
console.log(`[HeroAtkSystem] ${targetModel.hero_name} 受到 ${damage} 点伤害 (暴击: ${isCrit})`);
|
||||||
}
|
}
|
||||||
|
|
||||||
return damage;
|
return damage;
|
||||||
|
|||||||
@@ -93,13 +93,12 @@ export class HeroViewComp extends CCComp {
|
|||||||
* 注意:数据更新逻辑已移到 HeroAttrSystem,这里只负责显示
|
* 注意:数据更新逻辑已移到 HeroAttrSystem,这里只负责显示
|
||||||
*/
|
*/
|
||||||
update(dt: number){
|
update(dt: number){
|
||||||
if(!smc.mission.play||smc.mission.pause) return
|
if(!smc.mission.play || smc.mission.pause) return;
|
||||||
|
|
||||||
// ✅ View 层职责:处理表现相关的逻辑
|
// ✅ View 层职责:处理表现相关的逻辑
|
||||||
this.in_stop(dt); // 动画状态
|
|
||||||
this.processDamageQueue(); // 伤害数字显示队列
|
this.processDamageQueue(); // 伤害数字显示队列
|
||||||
|
|
||||||
// ✅ 更新显示(数据由 HeroAttrSystem 更新)
|
// ✅ 更新 UI 显示(数据由 HeroAttrSystem 更新)
|
||||||
this.hp_show(this.model.hp, this.model.Attrs[Attrs.HP_MAX]);
|
this.hp_show(this.model.hp, this.model.Attrs[Attrs.HP_MAX]);
|
||||||
this.mp_show(this.model.mp, this.model.Attrs[Attrs.MP_MAX]);
|
this.mp_show(this.model.mp, this.model.Attrs[Attrs.MP_MAX]);
|
||||||
this.show_shield(this.model.shield, this.model.Attrs[Attrs.SHIELD_MAX]);
|
this.show_shield(this.model.shield, this.model.Attrs[Attrs.SHIELD_MAX]);
|
||||||
@@ -236,16 +235,13 @@ export class HeroViewComp extends CCComp {
|
|||||||
get isActive() {
|
get isActive() {
|
||||||
return this.ent.has(HeroViewComp) && this.node?.isValid;
|
return this.ent.has(HeroViewComp) && this.node?.isValid;
|
||||||
}
|
}
|
||||||
//状态切
|
/** 状态切换(动画) */
|
||||||
status_change(type:string){
|
status_change(type:string){
|
||||||
this.status=type
|
this.status = type;
|
||||||
if(type == "idle"){
|
if(type === "idle"){
|
||||||
this.as.idle()
|
this.as.idle();
|
||||||
// this.as.change_default("idle")
|
} else if(type === "move"){
|
||||||
}
|
this.as.move();
|
||||||
if(type == "move"){
|
|
||||||
this.as.move()
|
|
||||||
// this.as.change_default("move")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
add_shield(shield:number){
|
add_shield(shield:number){
|
||||||
@@ -260,30 +256,35 @@ export class HeroViewComp extends CCComp {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** 静止时间 */
|
/**
|
||||||
in_stop (dt: number) {
|
* 死亡视图表现
|
||||||
|
* 由 HeroAtkSystem 调用,只负责视觉效果和事件通知
|
||||||
}
|
*/
|
||||||
|
|
||||||
|
|
||||||
do_dead(){
|
do_dead(){
|
||||||
// 死亡逻辑主要由 HeroBattleSystem 处理
|
// 防止重复触发
|
||||||
// 这里只保留视图层的表现逻辑
|
if(this.model.is_count_dead) return;
|
||||||
if(this.model.is_count_dead) return
|
this.model.is_count_dead = true; // 防止重复触发,必须存在防止重复调用
|
||||||
|
|
||||||
if(this.model.fac==FacSet.MON){
|
// 播放死亡特效
|
||||||
this.scheduleOnce(()=>{
|
this.dead();
|
||||||
this.do_drop()
|
|
||||||
},0.1)
|
|
||||||
}
|
|
||||||
if(this.model.fac==FacSet.HERO){
|
|
||||||
this.scheduleOnce(()=>{
|
|
||||||
oops.message.dispatchEvent(GameEvent.HeroDead,{hero_uuid:this.model.hero_uuid})
|
|
||||||
},0.1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
do_drop(){
|
|
||||||
|
|
||||||
|
// 根据阵营触发不同事件
|
||||||
|
if(this.model.fac === FacSet.MON){
|
||||||
|
// 怪物死亡:延迟触发掉落(暂时不发事件,等待实现)
|
||||||
|
// this.scheduleOnce(() => {
|
||||||
|
// oops.message.dispatchEvent(GameEvent.MonsterDead, {
|
||||||
|
// hero_uuid: this.model.hero_uuid,
|
||||||
|
// position: this.node.position
|
||||||
|
// });
|
||||||
|
// }, 0.2);
|
||||||
|
} else if(this.model.fac === FacSet.HERO){
|
||||||
|
// 英雄死亡:延迟触发死亡事件
|
||||||
|
this.scheduleOnce(() => {
|
||||||
|
oops.message.dispatchEvent(GameEvent.HeroDead, {
|
||||||
|
hero_uuid: this.model.hero_uuid
|
||||||
|
});
|
||||||
|
}, 0.2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
do_atked(damage:number,isCrit:boolean,s_uuid:number){
|
do_atked(damage:number,isCrit:boolean,s_uuid:number){
|
||||||
@@ -308,13 +309,16 @@ export class HeroViewComp extends CCComp {
|
|||||||
}
|
}
|
||||||
// 伤害计算和战斗逻辑已迁移到 HeroBattleSystem
|
// 伤害计算和战斗逻辑已迁移到 HeroBattleSystem
|
||||||
|
|
||||||
do_dead_trigger(){ //死亡特殊处理
|
/** 死亡触发器(预留,用于天赋/特殊效果) */
|
||||||
if(this.model.is_dead||this.model.fac==FacSet.MON) return
|
do_dead_trigger(){
|
||||||
|
if(this.model.is_dead || this.model.fac === FacSet.MON) return;
|
||||||
|
// 预留:天赋触发、复活检查等
|
||||||
}
|
}
|
||||||
do_atked_trigger(){ //受伤特殊处理
|
|
||||||
if(this.model.is_dead||this.model.fac==FacSet.MON) return
|
|
||||||
|
|
||||||
|
/** 受击触发器(预留,用于天赋/特殊效果) */
|
||||||
|
do_atked_trigger(){
|
||||||
|
if(this.model.is_dead || this.model.fac === FacSet.MON) return;
|
||||||
|
// 预留:反击、护盾触发等
|
||||||
}
|
}
|
||||||
|
|
||||||
to_grave(){
|
to_grave(){
|
||||||
@@ -326,8 +330,9 @@ export class HeroViewComp extends CCComp {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** 调试日志(已禁用) */
|
||||||
to_console(value:any, value2:any=null, value3:any=null){
|
to_console(value:any, value2:any=null, value3:any=null){
|
||||||
//console.log("["+this.scale+this.hero_name+']'+value,value2,value3)
|
// 调试用,生产环境已禁用
|
||||||
}
|
}
|
||||||
|
|
||||||
reset() {
|
reset() {
|
||||||
|
|||||||
Reference in New Issue
Block a user