diff --git a/assets/script/game/common/config/SkillSet.ts b/assets/script/game/common/config/SkillSet.ts index e8804da1..f34ab2d6 100644 --- a/assets/script/game/common/config/SkillSet.ts +++ b/assets/script/game/common/config/SkillSet.ts @@ -145,6 +145,9 @@ export interface SkillConfig { IType:IType, // 技能类型(近战/远程/辅助) RType:RType, // 技能运行类型(直线/贝塞尔/固定起点/固定终点) EType:EType, // 结束条件(动画结束/时间结束/距离结束/碰撞/次数结束) + bezier_start_y?:number, // 贝塞尔起始抬升高度 + bezier_mid_y?:number, // 贝塞尔中间高度增量 + bezier_arc?:number, // 贝塞尔弧度系数 time?:number, // timeEnd 持续时间(秒) kind?:SkillKind, // 主效果类型 crt?:number, // 额外暴击率 @@ -199,17 +202,17 @@ export const SkillSet: Record = { 6101: { uuid:6101,name:"普通射击",sp_name:"arrow",icon:"1135",TGroup:TGroup.Enemy,readyAnm:"",endAnm:"",act:"atk", DTType:DTType.single,ap:100,hit_count:1,hitcd:0.2,speed:720,with:0,ready:0.1,EAnm:0,DAnm:"",IType:IType.remote, - RType:RType.linear,EType:EType.collision,buffs:[],info:"对单个目标造成100%攻击的伤害", + RType:RType.bezier,EType:EType.collision,bezier_start_y:20,bezier_mid_y:140,bezier_arc:1.05,buffs:[],info:"对单个目标造成100%攻击的伤害", }, 6102: { uuid:6102,name:"冰冻射击",sp_name:"arrow_blue",icon:"1135",TGroup:TGroup.Enemy,readyAnm:"",endAnm:"",act:"atk", DTType:DTType.single,ap:100,hit_count:1,hitcd:0.2,speed:720,with:0,ready:0.1,EAnm:0,DAnm:"",IType:IType.remote, - RType:RType.linear,EType:EType.collision,buffs:[],info:"对单个目标造成100%攻击的伤害", + RType:RType.bezier,EType:EType.collision,bezier_start_y:20,bezier_mid_y:150,bezier_arc:1.1,buffs:[],info:"对单个目标造成100%攻击的伤害", }, 6103: { uuid:6103,name:"暴击射击",sp_name:"arrow_red",icon:"1135",TGroup:TGroup.Enemy,readyAnm:"",endAnm:"",act:"atk", DTType:DTType.single,ap:100,hit_count:1,hitcd:0.2,speed:720,with:0,ready:0.1,EAnm:0,DAnm:"",IType:IType.remote, - RType:RType.linear,EType:EType.collision,buffs:[],info:"对单个目标造成100%攻击的伤害", + RType:RType.bezier,EType:EType.collision,bezier_start_y:20,bezier_mid_y:145,bezier_arc:1.08,buffs:[],info:"对单个目标造成100%攻击的伤害", }, //大招 6104: { @@ -222,12 +225,12 @@ export const SkillSet: Record = { 6201: { uuid:6201,name:"蓝波",sp_name:"ball_blue",icon:"1126",TGroup:TGroup.Enemy,readyAnm:"",endAnm:"",act:"atk", DTType:DTType.single,frz:0,ap:100,hit_count:1,hitcd:0.3,speed:720,with:90,ready:0.1,EAnm:0,DAnm:"",IType:IType.remote, - RType:RType.linear,EType:EType.collision,buffs:[],info:"对单个目标造成100%攻击的伤害,冰冻率20%", + RType:RType.bezier,EType:EType.collision,buffs:[],info:"对单个目标造成100%攻击的伤害,冰冻率20%", }, 6202: { uuid:6202,name:"绿波",sp_name:"ball_green",icon:"1126",TGroup:TGroup.Enemy,readyAnm:"",endAnm:"",act:"atk", DTType:DTType.single,ap:100,hit_count:1,hitcd:0.3,speed:720,with:90,ready:0.1,EAnm:0,DAnm:"",IType:IType.remote, - RType:RType.linear,EType:EType.collision,buffs:[],info:"对单个目标造成100%攻击的伤害", + RType:RType.bezier,EType:EType.collision,buffs:[],info:"对单个目标造成100%攻击的伤害", }, 6203: { uuid:6203,name:"红波",sp_name:"ball_red",icon:"1126",TGroup:TGroup.Enemy,readyAnm:"",endAnm:"",act:"atk", diff --git a/assets/script/game/skill/SMoveComp.ts b/assets/script/game/skill/SMoveComp.ts index 0f057ceb..f4ee9acc 100644 --- a/assets/script/game/skill/SMoveComp.ts +++ b/assets/script/game/skill/SMoveComp.ts @@ -65,6 +65,9 @@ export class SMoveDataComp extends ecs.Comp { /** 贝塞尔曲线控制点 */ controlPoint: Vec3 = v3(0, 0, 0); + bezierStartHeight: number = 18; + bezierMidHeight: number = 140; + bezierArc: number = 1; /** 是否自动销毁(到达目标后) */ autoDestroy: boolean = true; @@ -74,6 +77,9 @@ export class SMoveDataComp extends ecs.Comp { this.targetPos.set(0, 0, 0); this.currentPos.set(0, 0, 0); this.controlPoint.set(0, 0, 0); + this.bezierStartHeight = 18; + this.bezierMidHeight = 140; + this.bezierArc = 1; this.speed = 500; this.progress = 0; this.scale = 1; @@ -109,7 +115,8 @@ export class SMoveDataComp extends ecs.Comp { */ private calculateMoveParameters() { const distance = Vec3.distance(this.startPos, this.targetPos); - this.totalTime = distance / this.speed; + const safeSpeed = Math.max(1, this.speed); + this.totalTime = Math.max(0.05, distance / safeSpeed); // 为贝塞尔移动生成控制点 if (this.runType === RType.bezier) { @@ -127,12 +134,25 @@ export class SMoveDataComp extends ecs.Comp { // 计算垂直方向 const direction = new Vec3(); Vec3.subtract(direction, this.targetPos, this.startPos); + if (direction.length() < 0.0001) { + this.controlPoint.set(midPoint.x, midPoint.y + this.bezierMidHeight, midPoint.z); + return; + } const perpendicular = v3(-direction.y, direction.x, 0); perpendicular.normalize(); - // 根据scale决定控制点方向 - const offset = 100 * this.scale; + const distance = Vec3.distance(this.startPos, this.targetPos); + const baseOffset = Math.max(120, Math.min(220, distance * 0.35)); + const offset = baseOffset * Math.max(0.2, this.bezierArc); + if (perpendicular.y < 0) { + perpendicular.x *= -1; + perpendicular.y *= -1; + } Vec3.scaleAndAdd(this.controlPoint, midPoint, perpendicular, offset); + const minPeakY = midPoint.y + Math.max(0, this.bezierMidHeight); + if (this.controlPoint.y < minPeakY) { + this.controlPoint.y = minPeakY; + } } /** diff --git a/assets/script/game/skill/SMoveSystem.ts b/assets/script/game/skill/SMoveSystem.ts index 8851ffb8..eef8a165 100644 --- a/assets/script/game/skill/SMoveSystem.ts +++ b/assets/script/game/skill/SMoveSystem.ts @@ -104,19 +104,17 @@ export class SMoveSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate break; case RType.bezier: const bezierStartPos = v3( - moveComp.startPos.x + moveComp.atk_x, - moveComp.startPos.y + moveComp.atk_y, + moveComp.startPos.x, + moveComp.startPos.y + moveComp.bezierStartHeight, moveComp.startPos.z ); const bezierTargetPos = v3( - moveComp.targetPos.x + moveComp.atk_x, - moveComp.targetPos.y + moveComp.atk_y, + moveComp.targetPos.x, + moveComp.targetPos.y + moveComp.bezierStartHeight, moveComp.targetPos.z ); - const horizonY = bezierStartPos.y; - const finalX = this.resolveBezierFinalXByHorizon(bezierStartPos, bezierTargetPos, horizonY); moveComp.startPos.set(bezierStartPos); - moveComp.targetPos.set(finalX, horizonY, bezierTargetPos.z); + moveComp.targetPos.set(bezierTargetPos); node.setPosition(bezierStartPos); break; default: @@ -134,15 +132,6 @@ export class SMoveSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate } } - private resolveBezierFinalXByHorizon(startPos: Vec3, targetPos: Vec3, horizonY: number): number { - const deltaY = targetPos.y - startPos.y; - if (Math.abs(deltaY) < 0.0001) { - return targetPos.x; - } - const t = (horizonY - startPos.y) / deltaY; - return startPos.x + (targetPos.x - startPos.x) * t; - } - update(entity: ecs.Entity): void { if(!smc.mission.play ) return; if(smc.mission.pause) return diff --git a/assets/script/game/skill/Skill.ts b/assets/script/game/skill/Skill.ts index 5c8d2282..cc421ce4 100644 --- a/assets/script/game/skill/Skill.ts +++ b/assets/script/game/skill/Skill.ts @@ -180,6 +180,9 @@ export class Skill extends ecs.Entity { sMoveCom.scale = caster.node.scale.x < 0 ? -1 : 1; sMoveCom.runType = config.RType; sMoveCom.endType = config.EType; + sMoveCom.bezierStartHeight = config.bezier_start_y ?? 18; + sMoveCom.bezierMidHeight = config.bezier_mid_y ?? 140; + sMoveCom.bezierArc = config.bezier_arc ?? 1; // 从SkillView获取移动参数,位置初始化由SMoveSystem统一处理 sMoveCom.atk_x = SView.atk_x; sMoveCom.atk_y = SView.atk_y;