feat: 添加冰冻效果并移除调试组件
- 在 GameSet 中添加冰冻时间常量 FROST_TIME - 在 HeroAttrsComp 中新增 toFrost 方法用于处理冰冻状态 - 在 HeroAtkSystem 中增加冰冻判定,命中时触发冰冻效果并显示冰冻特效 - 简化 HeroViewComp 中的冰冻特效方法,移除眩晕特效方法 - 删除调试用的 HSkillComp 组件及其 meta 文件 - 调整 HeroBuffSystem 的计时器间隔,使冰冻状态更平滑地递减
This commit is contained in:
@@ -18,8 +18,7 @@ export enum BoxSet {
|
||||
LETF_END = -420,
|
||||
RIGHT_END = 420,
|
||||
//游戏地平线
|
||||
GAME_LINE = -90
|
||||
|
||||
GAME_LINE = -90,
|
||||
//攻击距离
|
||||
}
|
||||
|
||||
@@ -88,6 +87,8 @@ export enum FightSet {
|
||||
BACK_RANG=30,//后退范围
|
||||
FiIGHT_TIME=60*10,//战斗时间
|
||||
BACK_CHANCE=40,//击退概率
|
||||
FROST_TIME=1,//冰冻时间
|
||||
|
||||
}
|
||||
|
||||
export enum IndexSet {
|
||||
|
||||
@@ -117,6 +117,7 @@ export class HeroAtkSystem extends ecs.ComblockSystem implements ecs.ISystemUpd
|
||||
// 暴击判定
|
||||
// 使用施法者的暴击率属性(damageEvent.Attrs 快照),- 被攻击者的暴击抗性属
|
||||
const isCrit = this.checkChance(damageEvent.Attrs[Attrs.critical]);
|
||||
|
||||
// 计算基础伤害
|
||||
let damage = this.dmgCount(damageEvent,TAttrsComp);
|
||||
|
||||
@@ -147,16 +148,15 @@ export class HeroAtkSystem extends ecs.ComblockSystem implements ecs.ISystemUpd
|
||||
|
||||
mLogger.log(this.debugMode, 'HeroAtkSystem', ` 英雄${TAttrsComp.hero_name} (uuid: ${TAttrsComp.hero_uuid}) 受到 eid:${casterEid} 的 伤害 ${damage},${isCrit?"暴击":"普通"}攻击,技能ID ${damageEvent.s_uuid}`);
|
||||
|
||||
// 击退判定
|
||||
// 使用施法者的击退概率属性(damageEvent.Attrs 快照) - 被攻击者的控制抗性
|
||||
// 击退成功后需要清理施法者的相关天赋buff
|
||||
// 击退和冰冻判定
|
||||
const isBack = this.checkChance((damageEvent.Attrs[Attrs.back_chance] || 0));
|
||||
|
||||
|
||||
// ✅ 触发视图层表现(伤害数字、受击动画、后退)
|
||||
const isFrost = this.checkChance(damageEvent.Attrs[Attrs.freeze_chance]);
|
||||
// ✅ 触发视图层表现(伤害数字、受击动画、后退,冰冻)
|
||||
if (targetView) {
|
||||
targetView.do_atked(damage, isCrit, damageEvent.s_uuid, isBack);
|
||||
targetView.playEnd(skillConf.endAnm);
|
||||
if(isFrost) TAttrsComp.toFrost();
|
||||
targetView.in_iced(TAttrsComp.frost_end_time);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ import { BuffConf } from "../common/config/SkillSet";
|
||||
import { HeroDisVal, HType } from "../common/config/heroSet";
|
||||
import { mLogger } from "../common/Logger";
|
||||
import { Timer } from "db://oops-framework/core/common/timer/Timer";
|
||||
import { FightSet } from "../common/config/GameSet";
|
||||
@ecs.register('HeroAttrs')
|
||||
export class HeroAttrsComp extends ecs.Comp {
|
||||
public debugMode: boolean = false;
|
||||
@@ -134,12 +135,9 @@ export class HeroAttrsComp extends ecs.Comp {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 把配置值统一转换为“可直接写入容器和结算”的数值
|
||||
* - RATIO 会在写入前转换为 VALUE
|
||||
* - BOOLEAN 保持原类型
|
||||
*/
|
||||
|
||||
toFrost(time: number=1) {
|
||||
this.frost_end_time += FightSet.FROST_TIME*time;
|
||||
}
|
||||
|
||||
/**
|
||||
* 通用属性修改应用
|
||||
@@ -291,7 +289,7 @@ export class HeroAttrsComp extends ecs.Comp {
|
||||
|
||||
@ecs.register('HeroBuffSystem')
|
||||
export class HeroBuffSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate {
|
||||
private timer =new Timer(0.2)
|
||||
private timer =new Timer(0.1)
|
||||
filter(): ecs.IMatcher {
|
||||
return ecs.allOf(HeroAttrsComp);
|
||||
}
|
||||
@@ -300,7 +298,7 @@ export class HeroBuffSystem extends ecs.ComblockSystem implements ecs.ISystemUpd
|
||||
if(this.timer.update(this.dt)){
|
||||
const attrsComp = e.get(HeroAttrsComp);
|
||||
if(attrsComp.frost_end_time > 0){
|
||||
attrsComp.frost_end_time -= 0.2;
|
||||
attrsComp.frost_end_time -= 0.1;
|
||||
if(attrsComp.frost_end_time <= 0){
|
||||
attrsComp.frost_end_time = 0;
|
||||
}
|
||||
|
||||
@@ -261,17 +261,8 @@ export class HeroViewComp extends CCComp {
|
||||
}
|
||||
|
||||
/** 冰冻特效 */
|
||||
private in_iced(t: number = 1, ap: number = 0) {
|
||||
const node = this.spawnTimedFx("game/skill/buff/iced", this.node, t);
|
||||
|
||||
}
|
||||
|
||||
/** 眩晕特效 */
|
||||
private in_yun(t: number = 1, ap: number = 0) {
|
||||
const node = this.spawnTimedFx("game/skill/buff/buff_yun", this.node, t);
|
||||
if (!node) return;
|
||||
let height = this.node.getComponent(UITransform).height;
|
||||
node.setPosition(v3(0, height));
|
||||
in_iced(t: number = 1) {
|
||||
this.spawnTimedFx("game/skill/buff/iced", this.node, t);
|
||||
}
|
||||
|
||||
/** 技能提示 */
|
||||
|
||||
@@ -1,193 +0,0 @@
|
||||
import { _decorator, instantiate, Label, Node, Prefab, UITransform, v3, Vec3 } from 'cc';
|
||||
import { CCComp } from 'db://oops-framework/module/common/CCComp';
|
||||
import { ecs } from 'db://oops-framework/libs/ecs/ECS';
|
||||
import { SkillSet } from '../common/config/SkillSet';
|
||||
import { BoxSet, FacSet } from '../common/config/GameSet';
|
||||
import { smc } from '../common/SingletonModuleComp';
|
||||
import { Skill } from '../skill/Skill';
|
||||
import { mLogger } from '../common/Logger';
|
||||
const { ccclass, property } = _decorator;
|
||||
|
||||
@ccclass('HSkillComp')
|
||||
@ecs.register('HSkillComp', false)
|
||||
export class HSkillComp extends CCComp {
|
||||
debugMode: boolean = false;
|
||||
private readonly panelName: string = 'skill_debug_panel';
|
||||
private readonly panelWidth: number = 680;
|
||||
private readonly panelHeight: number = 1180;
|
||||
private readonly colCount: number = 4;
|
||||
private readonly cellWidth: number = 160;
|
||||
private readonly cellHeight: number = 68;
|
||||
private readonly startX: number = -240;
|
||||
private readonly startY: number = 560;
|
||||
@property(Prefab)
|
||||
btnPrefab: Prefab | null = null;
|
||||
|
||||
private panelNode: Node | null = null;
|
||||
private buttonNodes: Node[] = [];
|
||||
private mockCasterNode: Node | null = null;
|
||||
private mockCasterView: any = null;
|
||||
private currentSkill: Skill | null = null;
|
||||
|
||||
protected onLoad(): void {
|
||||
this.ensurePanel();
|
||||
}
|
||||
|
||||
start() {
|
||||
this.renderSkillButtons();
|
||||
}
|
||||
|
||||
start_test() {
|
||||
this.node.active = true;
|
||||
const home = this.node.parent?.getChildByName('mission_home');
|
||||
if (home) {
|
||||
home.active = false;
|
||||
}
|
||||
this.renderSkillButtons();
|
||||
}
|
||||
|
||||
end_test() {
|
||||
const home = this.node.parent?.getChildByName('mission_home');
|
||||
if (home) {
|
||||
home.active = true;
|
||||
}
|
||||
this.node.active = false;
|
||||
}
|
||||
|
||||
update_data(uuid: number) {
|
||||
this.renderSkillButtons();
|
||||
}
|
||||
|
||||
private ensurePanel() {
|
||||
let panel = this.node.getChildByName(this.panelName);
|
||||
if (!panel) {
|
||||
panel = new Node(this.panelName);
|
||||
panel.parent = this.node;
|
||||
const transform = panel.addComponent(UITransform);
|
||||
transform.setContentSize(this.panelWidth, this.panelHeight);
|
||||
panel.setPosition(0, 640, 0);
|
||||
}
|
||||
this.panelNode = panel;
|
||||
}
|
||||
|
||||
private renderSkillButtons() {
|
||||
this.ensurePanel();
|
||||
const prefab = this.getBtnPrefab();
|
||||
if (!prefab || !this.panelNode || !this.panelNode.isValid) {
|
||||
return;
|
||||
}
|
||||
this.clearButtons();
|
||||
const skillIds = Object.keys(SkillSet).map(Number).sort((a, b) => a - b);
|
||||
skillIds.forEach((skillId, index) => {
|
||||
const btnNode = instantiate(prefab);
|
||||
btnNode.parent = this.panelNode;
|
||||
const row = Math.floor(index / this.colCount);
|
||||
const col = index % this.colCount;
|
||||
btnNode.setPosition(
|
||||
this.startX + col * this.cellWidth,
|
||||
this.startY - row * this.cellHeight,
|
||||
0
|
||||
);
|
||||
const label = btnNode.getChildByName('Label')?.getComponent(Label);
|
||||
if (label) {
|
||||
const conf = SkillSet[skillId];
|
||||
label.string = `${skillId} ${conf?.name ?? ''}`;
|
||||
}
|
||||
btnNode.on(Node.EventType.TOUCH_END, () => this.playDebugSkill(skillId), this);
|
||||
this.buttonNodes.push(btnNode);
|
||||
});
|
||||
}
|
||||
|
||||
private clearButtons() {
|
||||
this.buttonNodes.forEach(node => {
|
||||
if (!node || !node.isValid) {
|
||||
return;
|
||||
}
|
||||
node.off(Node.EventType.TOUCH_END);
|
||||
node.destroy();
|
||||
});
|
||||
this.buttonNodes.length = 0;
|
||||
}
|
||||
|
||||
private getBtnPrefab(): Prefab | null {
|
||||
if (this.btnPrefab) {
|
||||
return this.btnPrefab;
|
||||
}
|
||||
mLogger.error(this.debugMode, 'HSkillComp', '[HSkillComp] 未绑定 Btn 预制体,请在编辑器中设置 btnPrefab');
|
||||
return null;
|
||||
}
|
||||
|
||||
private getSkillParent(): Node {
|
||||
const layer = smc.map?.MapView?.scene?.entityLayer?.node?.getChildByName('SKILL');
|
||||
if (layer && layer.isValid) {
|
||||
return layer;
|
||||
}
|
||||
return this.node;
|
||||
}
|
||||
|
||||
private ensureMockCaster(parent: Node, startPos: Vec3): any {
|
||||
if (!this.mockCasterNode || !this.mockCasterNode.isValid) {
|
||||
this.mockCasterNode = new Node('debug_caster');
|
||||
this.mockCasterNode.parent = parent;
|
||||
this.mockCasterNode.setScale(v3(1, 1, 1));
|
||||
this.mockCasterNode.active = false;
|
||||
} else if (this.mockCasterNode.parent !== parent) {
|
||||
this.mockCasterNode.parent = parent;
|
||||
}
|
||||
this.mockCasterNode.setPosition(startPos);
|
||||
const mockAttrs = {
|
||||
hero_name: '技能调试器',
|
||||
ap: 100,
|
||||
critical: 0,
|
||||
critical_dmg: 50,
|
||||
freeze_chance: 0,
|
||||
back_chance: 0,
|
||||
puncture: 0,
|
||||
wfuny: 0,
|
||||
fac: FacSet.HERO
|
||||
};
|
||||
const mockEntity = {
|
||||
eid: -10086,
|
||||
get: () => mockAttrs
|
||||
};
|
||||
this.mockCasterView = {
|
||||
node: this.mockCasterNode,
|
||||
box_group: BoxSet.HERO,
|
||||
ent: mockEntity
|
||||
};
|
||||
return this.mockCasterView;
|
||||
}
|
||||
|
||||
private playDebugSkill(skillId: number) {
|
||||
const conf = SkillSet[skillId];
|
||||
if (!conf) {
|
||||
return;
|
||||
}
|
||||
this.destroyCurrentSkill();
|
||||
const parent = this.getSkillParent();
|
||||
const startPos = v3(-260, -40, 0);
|
||||
const targetPos = v3(260, -40, 0);
|
||||
const caster = this.ensureMockCaster(parent, startPos);
|
||||
const skill = ecs.getEntity<Skill>(Skill);
|
||||
skill.load(startPos.clone(), parent, skillId, targetPos, caster, 0);
|
||||
this.currentSkill = skill;
|
||||
}
|
||||
|
||||
private destroyCurrentSkill() {
|
||||
if (!this.currentSkill) {
|
||||
return;
|
||||
}
|
||||
this.currentSkill.destroy();
|
||||
this.currentSkill = null;
|
||||
}
|
||||
|
||||
reset() {
|
||||
this.destroyCurrentSkill();
|
||||
this.clearButtons();
|
||||
if (this.mockCasterNode && this.mockCasterNode.isValid) {
|
||||
this.mockCasterNode.destroy();
|
||||
this.mockCasterNode = null;
|
||||
}
|
||||
this.node.destroy();
|
||||
}
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
{"ver":"4.0.24","importer":"typescript","imported":true,"uuid":"34b93128-7505-4579-91c9-a93e9f1040ad","files":[],"subMetas":{},"userData":{}}
|
||||
@@ -214,7 +214,6 @@ export class Skill extends ecs.Entity {
|
||||
sDataCom.Attrs[Attrs.critical] = cAttrsComp.critical + addCrt;
|
||||
sDataCom.Attrs[Attrs.freeze_chance] = cAttrsComp.freeze_chance + addFrz;
|
||||
sDataCom.Attrs[Attrs.back_chance] = cAttrsComp.back_chance + addBck;
|
||||
|
||||
sDataCom.s_uuid=s_uuid
|
||||
sDataCom.fac=cAttrsComp.fac
|
||||
sDataCom.ext_dmg=ext_dmg
|
||||
|
||||
Reference in New Issue
Block a user