Files
heros/assets/script/game/hero/HeroViewComp.ts
2025-10-22 17:11:03 +08:00

782 lines
27 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { Vec3, _decorator , v3,Collider2D,Contact2DType,Label ,Node,Prefab,instantiate,ProgressBar, Component, Material, Sprite, math, clamp, Game, tween, Color, BoxCollider2D} from "cc";
import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS";
import { CCComp } from "../../../../extensions/oops-plugin-framework/assets/module/common/CCComp";
import { HeroSpine } from "./HeroSpine";
import { BoxSet, FacSet } from "../common/config/BoxSet";
import { smc } from "../common/SingletonModuleComp";
import { Timer } from "../../../../extensions/oops-plugin-framework/assets/core/common/timer/Timer";
import { Attrs, DBuff, SkillSet, BType, BuffConf, DbuffConf, TransformBuffs, AttrsType } from "../common/config/SkillSet";
import { BuffComp } from "./BuffComp";
import { oops } from "db://oops-framework/core/Oops";
import { GameEvent } from "../common/config/GameEvent";
import { FightSet, TooltipTypes } from "../common/config/Mission";
import { RandomManager } from "db://oops-framework/core/common/random/RandomManager";
import { AttrSet, HeroInfo, HeroUpSet } from "../common/config/heroSet";
const { ccclass, property } = _decorator;
/**
* ==================== BUFF 系统使用说明 ====================
*
* 1. 系统架构
* - BUFF_V/BUFFS_V: 数值型 buff持临时
* - BUFF_R/BUFFS_R: 百分比型 buff持临时
* - DBUFF_V/DBUFFS_V: 数值型 debuff持临时
* - DBUFF_R/DBUFFS_R: 百分比型 debuff持临时
*
* 2. 智能覆盖规则
* - 值更小:不添加(弱效果不覆盖强效果)
* - 值相同且临时:叠加时
* - 值更大:更新为新值(临时则更新值和时间
*
* 3. 性能优化
* - 增量计算:添删除时只重算受影响的属
* - 批量计算initBuffsDebuffs() 中使recalculateAttrs() 一次性计算所
*/
/** 角色显示组件 */
@ccclass('HeroViewComp') // 定义Cocos Creator 组件
@ecs.register('HeroView', false) // 定义ECS 组件
export class HeroViewComp extends CCComp {
BUFFCOMP:BuffComp=null!
as: HeroSpine = null!
status:String = "idle"
hero_uuid:number = 1001;
hero_name : string = "hero";
lv:number =1;
scale: number = 1; /** 角色阵营 1hero -1 :mon */
type: number = 0; /**角色类型 0近战-需要贴1远程-保持距离 2辅助 */
fac:number=0; //阵营 0hero 1monster
box_group:number = BoxSet.HERO;
is_dead:boolean = false; //是否摧毁
is_count_dead:boolean = false; //是否计数死亡
is_stop:boolean = false;
is_atking:boolean = false;
is_boss:boolean = false;
is_big_boss:boolean = false;
is_master:boolean =false;
is_friend:boolean =false;
is_kalami:boolean =false;
skills:any=[]
mp: number = 100;
hp: number = 100; /** 血*/
shield:number=0; //当前护甲
/** 基础属有初始值的基础属后续Attrs 属性计算时用到*/
base_ap: number = 0; //基础攻击
base_map: number = 0;
base_def: number = 5;
base_hp: number = 100;
base_mp: number = 100;
base_speed: number = 100; /** 角色移动速度 */
base_dis: number = 100;
Attrs:any=[]
// Buff/Debuff 字典结构,通过属性索引直接访
// 结构: { [attrIndex: number]: { value: number, remainTime?: number } }
DBUFF_V: Record<number, {value: number}> = {} // 持久型数debuff
DBUFF_R: Record<number, {value: number}> = {} // 持久型百分比 debuff
BUFF_V: Record<number, {value: number}> = {} // 持久型数buff
BUFF_R: Record<number, {value: number}> = {} // 持久型百分比 buff
DBUFFS_V: Record<number, {value: number, remainTime: number}> = {} // 临时型数debuff
DBUFFS_R: Record<number, {value: number, remainTime: number}> = {} // 临时型百分比 debuff
BUFFS_V: Record<number, {value: number, remainTime: number}> = {} // 临时型数buff
BUFFS_R: Record<number, {value: number, remainTime: number}> = {} // 临时型百分比 buff
atk_count: number = 0;
atked_count: number = 0;
private damageQueue: Array<{
damage: number,
isCrit: boolean,
delay: number,
anm:string,
}> = [];
private isProcessingDamage: boolean = false;
private damageInterval: number = 0.01; // 伤害数字显示间隔
onLoad() {
this.as = this.getComponent(HeroSpine);
//console.log("[HeroViewComp]:hero view comp ",this.FIGHTCON)
this.on(GameEvent.FightEnd,this.do_fight_end,this)
const collider = this.node.getComponent(BoxCollider2D);
this.scheduleOnce(()=>{
if (collider) collider.enabled = true; // 先禁
},1)
// let anm = this.node.getChildByName("anm")
// anm.setScale(anm.scale.x*0.8,anm.scale.y*0.8);
}
/** 视图层逻辑代码分离演示 */
start () {
this.as.idle()
this.BUFFCOMP=this.node.getComponent(BuffComp);
// console.log("[HeroViewComp]:heroview"+this.hero_name,this.Attrs)
/** 方向 */
this.node.setScale(this.scale,1);
this.node.getChildByName("top").setScale(this.scale,1);
if(this.is_boss){
this.node.getChildByName("top").position=v3(this.node.position.x,this.node.position.y+100,0)
}
/* 显示角色血*/
this.node.getChildByName("top").getChildByName("hp").active = true;
this.node.getChildByName("top").getChildByName("pow").active = true;
}
// ==================== BUFF系统初始====================
/**
* 初始化角色的 buff debuff
* HeroInfo 读取初始配置,建立属性系
*/
initAttrs() {
// 清空现有 buff/debuff
this.BUFF_V = {};
this.BUFFS_V = {};
this.BUFF_R = {};
this.BUFFS_R = {};
this.DBUFF_V = {};
this.DBUFFS_V = {};
this.DBUFF_R = {};
this.DBUFFS_R = {};
// 获取英雄配置
const heroInfo = HeroInfo[this.hero_uuid];
if (!heroInfo) return;
// 1. 重置为基础
this.Attrs[Attrs.HP_MAX] = this.base_hp;
this.Attrs[Attrs.MP_MAX] = this.base_mp;
this.Attrs[Attrs.DEF] = this.base_def;
this.Attrs[Attrs.AP] = this.base_ap;
this.Attrs[Attrs.MAP] = this.base_map;
this.Attrs[Attrs.SPEED] = this.base_speed;
this.Attrs[Attrs.DIS] = this.base_dis;
// 2. 初始化其他属性(无初始值的
for (const attrKey in this.Attrs) {
const attrIndex = parseInt(attrKey);
if(
attrIndex !== Attrs.HP_MAX &&
attrIndex !== Attrs.MP_MAX&&
attrIndex !== Attrs.DEF &&
attrIndex !== Attrs.AP &&
attrIndex !== Attrs.MAP &&
attrIndex !== Attrs.SPEED &&
attrIndex !== Attrs.DIS
) {
this.Attrs[attrIndex] = 0;
}
}
// 加载初始 buff
if (heroInfo.buff && heroInfo.buff.length > 0) {
for (const buffConf of heroInfo.buff) {
this.addBuff(buffConf);
}
}
// 加载初始 debuff
if (heroInfo.debuff && heroInfo.debuff.length > 0) {
for (const dbuffConf of heroInfo.debuff) {
this.addDebuff(dbuffConf);
}
}
}
// ==================== BUFF管理 ====================
/**
* 添加 buff 效果(智能覆盖)
* @param buffConf buff 配置 (来自 SkillSet.BuffConf heroSet.buff)
*
* 智能覆盖规则
* 1. 值更小:不添
* 2. 值相同且都是临时:叠加时
* 3. 值更大:更新为新值(临时则更新值和时间
*/
addBuff(buffConf: BuffConf) {
const isValue = buffConf.BType === BType.VALUE;
const isPermanent = buffConf.time === 0;
const attrIndex = buffConf.buff;
// 根据类型选择对应buff 字典
const permanentBuffs = isValue ? this.BUFF_V : this.BUFF_R;
const temporaryBuffs = isValue ? this.BUFFS_V : this.BUFFS_R;
if (isPermanent) {
// 添加持久buff
const existing = permanentBuffs[attrIndex];
if (existing) {
// 值更小,不添
if (buffConf.value <= existing.value) {
return;
}
// 值更大,更新
existing.value = buffConf.value;
} else {
// 没有同类型,直接添加
permanentBuffs[attrIndex] = { value: buffConf.value };
}
} else {
// 添加临时buff
const existing = temporaryBuffs[attrIndex];
if (existing) {
if (buffConf.value < existing.value) {
// 值更小,不添
return;
} else if (buffConf.value === existing.value) {
// 值相同,叠加时间
existing.remainTime += buffConf.time;
return; // 时间叠加不需要重算属
} else {
// 值更大,更新值和时间
existing.value = buffConf.value;
existing.remainTime = buffConf.time;
}
} else {
// 没有同类型,直接添加
temporaryBuffs[attrIndex] = {
value: buffConf.value,
remainTime: buffConf.time
};
}
}
this.recalculateSingleAttr(buffConf.buff);
}
// ==================== DEBUFF管理 ====================
/**
* 添加 debuff 效果(智能覆盖)
* @param dbuffConf debuff 配置 (来自 SkillSet.DbuffConf heroSet.debuff)
*
* 支持两种 debuff
* 1. 属性型 debuff直接修改属性值有对应的 Attrs
* 2. 状态型 debuff只缓存状态无对应的 Attrs用于状态检查
*
* 智能覆盖规则
* 1. 值更小:不添
* 2. 值相同且都是临时:叠加时
* 3. 值更大:更新为新值(临时则更新值和时间
*/
addDebuff(dbuffConf: DbuffConf) {
// 获取 debuff 对应的属性字
const isValue = dbuffConf.BType === BType.VALUE;
const isPermanent = dbuffConf.time === 0;
// 根据类型选择对应debuff 字典
const permanentDebuffs = isValue ? this.DBUFF_V : this.DBUFF_R;
const temporaryDebuffs = isValue ? this.DBUFFS_V : this.DBUFFS_R;
// 状态类 debuff 使用 debuff 类型作为 key属性类 debuff 使用 attrField 作为 key
const key = dbuffConf.debuff;
if (isPermanent) {
// 添加持久debuff
const existing = permanentDebuffs[key];
if (existing) {
// 值更小,不添
if (dbuffConf.value <= existing.value) {
return;
}
// 值更大,更新
existing.value = dbuffConf.value;
} else {
// 没有同类型,直接添加
permanentDebuffs[key] = { value: dbuffConf.value };
}
} else {
// 添加临时debuff
const existing = temporaryDebuffs[key];
if (existing) {
if (dbuffConf.value < existing.value) {
// 值更小,不添
return;
} else if (dbuffConf.value === existing.value) {
// 值相同,叠加时间
existing.remainTime += dbuffConf.time;
return; // 时间叠加不需要重算属
} else {
// 值更大,更新值和时间
existing.value = dbuffConf.value;
existing.remainTime = dbuffConf.time;
}
} else {
// 没有同类型,直接添加
temporaryDebuffs[key] = {
value: dbuffConf.value,
remainTime: dbuffConf.time
};
}
}
let attrField = TransformBuffs(dbuffConf.debuff,true);
// 只重新计算受影响的属性(状态类 debuff 不需要计算)
if (attrField > 0 ) {
this.recalculateSingleAttr(attrField);
}
}
// ==================== 属性计算系====================
/**
* 重新计算单个属性
* @param attrIndex 属性索引
*
* 计算公式:
* - 数值型属性:最终值 = (基础值 + 数值型buff - 数值型debuff) × (1 + 百分比buff/100 - 百分比debuff/100)
* - 百分比型属性:最终值 = 基础值 + 数值型buff - 数值型debuff + 百分比buff - 百分比debuff
*/
private recalculateSingleAttr(attrIndex: number) {
// 1. 获取基础值
const baseValues: Record<number, number> = {
[Attrs.HP_MAX]: this.base_hp,
[Attrs.MP_MAX]: this.base_mp,
[Attrs.DEF]: this.base_def,
[Attrs.AP]: this.base_ap,
[Attrs.MAP]: this.base_map,
[Attrs.SPEED]: this.base_speed,
[Attrs.SHIELD_MAX]: 0
};
const baseVal = baseValues[attrIndex] !== undefined ? baseValues[attrIndex] : 0;
// 2. 收集所有数值型 buff/debuff
let totalValue = baseVal;
// Buff直接使用 Attrs 索引
if (this.BUFF_V[attrIndex]) {
totalValue += this.BUFF_V[attrIndex].value;
}
if (this.BUFFS_V[attrIndex]) {
totalValue += this.BUFFS_V[attrIndex].value;
}
// Debuff需要通过 DBuff key 查找
const deKey = TransformBuffs(attrIndex, false);
if (deKey !== -1) {
if (this.DBUFF_V[deKey]) {
totalValue -= this.DBUFF_V[deKey].value;
}
if (this.DBUFFS_V[deKey]) {
totalValue -= this.DBUFFS_V[deKey].value;
}
}
// 3. 收集所有百分比型 buff/debuff
let totalRatio = 0; // 总百分比(可正可负)
// Buff直接使用 Attrs 索引
if (this.BUFF_R[attrIndex]) {
totalRatio += this.BUFF_R[attrIndex].value;
}
if (this.BUFFS_R[attrIndex]) {
totalRatio += this.BUFFS_R[attrIndex].value;
}
// Debuff需要通过 DBuff key 查找
if (deKey !== -1) {
if (this.DBUFF_R[deKey]) {
totalRatio -= this.DBUFF_R[deKey].value;
}
if (this.DBUFFS_R[deKey]) {
totalRatio -= this.DBUFFS_R[deKey].value;
}
}
// 4. 根据属性类型计算最终值
const attrType = AttrsType[attrIndex];
const isRatioAttr = attrType === BType.RATIO;
if (isRatioAttr) {
// 百分比型属性:直接加减
this.Attrs[attrIndex] = totalValue + totalRatio;
} else {
// 数值型属性:(基础值+数值) × (1 + 百分比/100)
this.Attrs[attrIndex] = Math.floor(totalValue * (1 + totalRatio / 100));
}
// 5. 确保属性值合理
this.clampSingleAttr(attrIndex);
}
/**
* 确保单个属性值合
*/
private clampSingleAttr(attrIndex: number) {
switch(attrIndex) {
case Attrs.HP_MAX:
case Attrs.MP_MAX:
this.Attrs[attrIndex] = Math.max(1, this.Attrs[attrIndex]);
break;
case Attrs.DEF:
case Attrs.AP:
case Attrs.MAP:
this.Attrs[attrIndex] = Math.max(1, this.Attrs[attrIndex]);
break;
case Attrs.CRITICAL:
case Attrs.DODGE:
case Attrs.HIT:
this.Attrs[attrIndex] = Math.max(0, Math.min(AttrSet.ATTR_MAX, this.Attrs[attrIndex])); //AttrSet.ATTR_MAX =85
break;
}
}
// ==================== 临时 BUFF/DEBUFF 更新 ====================
/**
* 更新临时 buff/debuff 的剩余时
* 应在 update 中定期调
* @param dt 时间
*/
updateTemporaryBuffsDebuffs(dt: number) {
const affectedAttrs = new Set<number>();
// 更新临时型数buff
for (const attrIndex in this.BUFFS_V) {
const buff = this.BUFFS_V[attrIndex];
buff.remainTime -= dt;
if (buff.remainTime <= 0) {
delete this.BUFFS_V[attrIndex];
affectedAttrs.add(parseInt(attrIndex));
}
}
// 更新临时型百分比 buff
for (const attrIndex in this.BUFFS_R) {
const buff = this.BUFFS_R[attrIndex];
buff.remainTime -= dt;
if (buff.remainTime <= 0) {
delete this.BUFFS_R[attrIndex];
affectedAttrs.add(parseInt(attrIndex));
}
}
// 更新临时型数debuff
for (const key in this.DBUFFS_V) {
const debuff = this.DBUFFS_V[key];
debuff.remainTime -= dt;
if (debuff.remainTime <= 0) {
delete this.DBUFFS_V[key];
const keyNum = parseInt(key);
const attrField = TransformBuffs(keyNum,true)
if(attrField > 0) affectedAttrs.add(attrField);
}
}
// 更新临时型百分比 debuff
for (const key in this.DBUFFS_R) {
const debuff = this.DBUFFS_R[key];
debuff.remainTime -= dt;
if (debuff.remainTime <= 0) {
delete this.DBUFFS_R[key];
const keyNum = parseInt(key);
const attrField = TransformBuffs(keyNum,true)
if(attrField > 0) affectedAttrs.add(attrField);
}
}
// 只重新计算受影响的属
affectedAttrs.forEach(attrIndex => {
this.recalculateSingleAttr(attrIndex);
});
}
public isStun() {
return this.DBUFFS_V[DBuff.STUN] !== undefined?true:false
}
public isFrost() {
return this.DBUFFS_V[DBuff.FROST] !== undefined?true:false
}
update(dt: number){
if(!smc.mission.play||smc.mission.pause) return
// if(this.is_dead) {
// this.ent.destroy();
// return
// }
this.BaseUp(dt)
// 更新所有按时间减少的buff和debuff
this.in_stop(dt);
// 处理伤害队列
this.processDamageQueue();
// 更新临时 buff/debuff 时间
this.updateTemporaryBuffsDebuffs(dt);
this.BUFFCOMP.hp_show(this.hp,this.Attrs[Attrs.HP_MAX])
this.BUFFCOMP.mp_show(this.mp,this.Attrs[Attrs.MP_MAX])
this.BUFFCOMP.show_shield(this.shield,this.Attrs[Attrs.SHIELD_MAX])
}
BaseUp(dt:number){
this.mp += HeroUpSet.MP*dt
this.hp += HeroUpSet.HP*dt
if(this.mp > this.Attrs[Attrs.MP_MAX]) this.mp = this.Attrs[Attrs.MP_MAX]
if(this.hp > this.Attrs[Attrs.HP_MAX]) this.hp = this.Attrs[Attrs.HP_MAX]
}
do_fight_end(){
this.as.do_buff()
}
get isActive() {
return this.ent.has(HeroViewComp) && this.node?.isValid;
}
//状态切
status_change(type:string){
this.status=type
if(type == "idle"){
this.as.idle()
// this.as.change_default("idle")
}
if(type == "move"){
this.as.move()
// this.as.change_default("move")
}
}
add_shield(shield:number){
this.shield = this.Attrs[Attrs.SHIELD_MAX] +=shield
if(this.shield>0) this.BUFFCOMP.show_shield(this.shield,this.Attrs[Attrs.SHIELD_MAX])
}
health(hp: number = 0,is_num:boolean=true) {
this.BUFFCOMP.heathed();
let real_hp=0
let hp_max=this.Attrs[Attrs.HP_MAX]
let lost_hp=hp_max-this.hp
if(is_num){
if(lost_hp > hp){
real_hp=Math.floor(hp);
}else{
real_hp=lost_hp;
}
}else{
if(lost_hp > hp/100*hp_max){
real_hp=Math.floor(hp/100*hp_max);
}else{
real_hp=lost_hp;
}
}
if(real_hp > 0){
this.hp+=real_hp;
this.BUFFCOMP.tooltip(TooltipTypes.health,real_hp.toFixed(0));
}
this.BUFFCOMP.hp_show(this.hp,this.Attrs[Attrs.HP_MAX])
// this.update_vm
}
/** 静止时间 */
in_stop (dt: number) {
}
count_atk_count(){ //主将攻击
if(this.fac==FacSet.MON) return
this.atk_count+=1
}
do_dead(){
this.do_dead_trigger()
//console.log("[HeroViewComp]:角色死亡",this.hero_uuid)
if(this.is_count_dead) return
this.is_count_dead=true
if(this.fac==FacSet.MON){
this.scheduleOnce(()=>{
this.do_drop()
},0.1)
}
if(this.fac==FacSet.HERO){
this.scheduleOnce(()=>{
oops.message.dispatchEvent(GameEvent.HeroDead,{hero_uuid:this.hero_uuid})
},0.1)
}
if(this.fac==FacSet.HERO){
//console.log("[HeroViewComp]:英雄死亡")
// oops.message.dispatchEvent(GameEvent.FightEnd,{victory:false})
}
}
do_drop(){
}
do_atked(remainingDamage:number,CAttrs:any,s_uuid:number){
let SConf=SkillSet[s_uuid]
this.do_atked_trigger()
if(this.check_dodge()) return
let is_crit = this.check_crit(CAttrs[Attrs.CRITICAL])
if(this == null) return;
let damage = this.count_damage(remainingDamage)
if(is_crit) {
damage = Math.floor(damage * (1 + (FightSet.CRIT_DAMAGE+CAttrs[Attrs.CRITICAL_DMG])/100))
}
// console.log(this.hero_name+"[HeroViewComp]:heroview :damage|hp|hp_max",damage,this.hp,this.Attrs[BuffAttr.HP_MAX])
damage=this.check_shield(damage)
if(damage <= 0) return
this.hp -= damage;
if(this.hp <= 0) {
if(this == null) return;
this.is_dead=true
if(this.BUFFCOMP){
this.BUFFCOMP.dead()
}
this.do_dead()
//console.log("[HeroViewComp]:dead,fac => "+(this.fac==FacSet.HERO?"hero":"monster"))
if(this.ent == null) return;
if(this.fac ==FacSet.HERO){
this.to_grave()
}else{
this.ent.destroy();
}
}
// this.update_vm
this.back()
this.showDamage(damage, is_crit,SConf.AtkedType);
}
//后退
back(){
if(this.fac==FacSet.MON) {
let tx=this.node.position.x+5
if(tx > 320) tx=320
tween(this.node).to(0.1, { position:v3(tx,this.node.position.y,0)}).start()
}
if(this.fac==FacSet.HERO) {
let tx=this.node.position.x-5
if(tx < -320) tx=-320
tween(this.node).to(0.1, { position:v3(tx,this.node.position.y,0)}).start()
}
}
//伤害计算 debuff 易伤
count_damage(remainingDamage:number){
return remainingDamage
}
check_shield(damage:number){
if(this.shield <= 0 ) return damage
if(this.shield >= damage){
this.shield -= damage
this.BUFFCOMP.tooltip(TooltipTypes.uskill,"*吸收*");
if(this.shield <= 0){
this.shield=this.Attrs[Attrs.SHIELD_MAX]=0
}
damage = 0
}
if(this.shield < damage){
damage=damage-this.shield
this.shield=0
this.Attrs[Attrs.SHIELD_MAX]=0
}
this.BUFFCOMP.show_shield(this.shield,this.Attrs[Attrs.SHIELD_MAX])
return damage
}
check_dodge(){
if(this.Attrs[Attrs.DODGE] > 0){
let random = Math.random()*100
if(random < this.Attrs[Attrs.DODGE]) {
this.BUFFCOMP.tooltip(TooltipTypes.uskill,"*闪避*");
return true
}
}
return false
}
check_crit(crit:number=0){
if(crit > 0){
let random = Math.random()*100
if(random < crit) {
//console.log("[HeroViewComp]:crit",crit,random)
return true
}
}
//console.log("[HeroViewComp]:crit",crit)
return false
}
do_dead_trigger(){ //死亡特殊处理
if(this.is_dead||this.fac==FacSet.MON) return
}
do_atked_trigger(){ //受伤特殊处理
if(this.is_dead||this.fac==FacSet.MON) return
}
to_grave(){
tween(this.node).to(0.5, { position:v3(-900,this.node.position.y+300,0)},{
onComplete: (target?: object) => {
this.node.setPosition(-900,this.node.position.y-300,0)
}
}).start()
}
// to_alive(){
// this.is_dead=false
// this.currentHp=this.currentHpMax*(100+this.hp_buff)/100
// this.BUFFCOMP.vmdata_update(true)
// this.node.setPosition(HeroPos[this.fight_pos].pos)
// this.BUFFCOMP.heathed()
// }
to_console(value:any,value2:any=null,value3:any=null){
//console.log("["+this.scale+this.hero_name+']'+value,value2,value3)
}
reset() {
this.is_dead = false;
const collider = this.getComponent(Collider2D);
if (collider) {
collider.off(Contact2DType.BEGIN_CONTACT);
}
this.scheduleOnce(() => {
this.node.destroy();
}, 0.1);
}
playSkillEffect(skill_id:number) {
let skill = SkillSet[skill_id]
switch(skill.act){
case "max":
this.as.max()
this.BUFFCOMP.tooltip(TooltipTypes.skill,skill.name,skill_id)
break
case "atk":
this.as.atk()
break
}
}
/** 显示伤害数字 */
showDamage(damage: number, isCrit: boolean,anm:string="atked") {
this.damageQueue.push({
damage,
isCrit,
delay: this.damageInterval,
anm
});
}
/** 处理伤害队列 */
private processDamageQueue() {
if (this.isProcessingDamage || this.damageQueue.length === 0) return;
this.isProcessingDamage = true;
const damageInfo = this.damageQueue.shift()!;
this.showDamageImmediate(damageInfo.damage, damageInfo.isCrit,damageInfo.anm);
// 设置延时处理下一个伤
this.scheduleOnce(() => {
this.isProcessingDamage = false;
}, this.damageInterval);
}
/** 立即显示伤害效果 */
private showDamageImmediate(damage: number, isCrit: boolean,anm:string="atked") {
// this.as.atked()
this.BUFFCOMP.hp_show(this.hp,this.Attrs[Attrs.HP_MAX])
this.BUFFCOMP.in_atked(anm,this.fac==FacSet.HERO?1:-1)
this.atked_count++;
if (isCrit) {
this.BUFFCOMP.hp_tip(TooltipTypes.crit, damage.toFixed(0), damage);
// //console.log("暴击伤害 + damage);
} else {
this.BUFFCOMP.hp_tip(TooltipTypes.life, damage.toFixed(0), damage);
// //console.log("普通伤害:" + damage);
}
}
}