解决一些小问题
This commit is contained in:
@@ -1,236 +0,0 @@
|
||||
import { _decorator, Animation, CCBoolean, Collider2D, Contact2DType, Tween, UITransform, v3, Vec3 } 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 { BezierMove } from "../BezierMove/BezierMove";
|
||||
import { DTType, EType, SkillSet, SType } from "../common/config/SkillSet";
|
||||
import { BoxSet, FacSet } from "../common/config/BoxSet";
|
||||
import { HeroViewComp } from "../hero/HeroViewComp";
|
||||
import { GameEvent } from "../common/config/GameEvent";
|
||||
import { smc } from "../common/SingletonModuleComp";
|
||||
import { Attrs } from "../common/config/HeroAttrs";
|
||||
const { ccclass, property } = _decorator;
|
||||
|
||||
/** 视图层对象 */
|
||||
@ccclass('AtkConCom')
|
||||
@ecs.register('AtkCon', false)
|
||||
export class AtkConCom extends CCComp {
|
||||
@property
|
||||
public anmEnd: boolean = false;
|
||||
@property
|
||||
public cbox: boolean = false;
|
||||
// 核心标识和配置
|
||||
s_uuid:number = 0;
|
||||
// 运行时状态(必须缓存的)
|
||||
is_destroy:boolean = false;
|
||||
startPos: Vec3 = v3(); // 起始位置
|
||||
targetPos: Vec3 = v3(); // 目标位置
|
||||
group:number = 0; //阵营
|
||||
fac:number=0; //阵营
|
||||
run_time:number = 0;
|
||||
// 战斗相关运行时数据
|
||||
Attrs:any=null
|
||||
hit_count:number = 0;
|
||||
// 组件引用
|
||||
anim:Animation=null;
|
||||
tweenInstance:Tween<any> = null;
|
||||
private moveDirection: Vec3 | null = null; // 添加一个属性来存储移动方向
|
||||
// 缓存的配置对象(避免重复查找)
|
||||
public Config: any = null;
|
||||
private isInitialized: boolean = false;
|
||||
private initializeConfig() {
|
||||
if (this.isInitialized) return;
|
||||
// 缓存技能配置,避免重复查找
|
||||
this.Config = SkillSet[this.s_uuid];
|
||||
if (!this.Config) {
|
||||
// console.error("[SkillCom] 技能配置不存在:", this.s_uuid);
|
||||
return;
|
||||
}
|
||||
this.isInitialized = true;
|
||||
// console.log("[SkillCom] 技能配置初始化完成:", this.s_uuid, this.Config.name);
|
||||
}
|
||||
start() {
|
||||
this.initializeConfig();
|
||||
// var entity = this.ent as ecs.Entity; // ecs.Entity 可转为当前模块的具体实体对象
|
||||
// this.on(ModuleEvent.Cmd, this.onHandler, this);
|
||||
|
||||
this.anim=this.node.getComponent(Animation)
|
||||
this.on(GameEvent.MissionEnd, this.doDestroy, this);
|
||||
this.node.active = true;
|
||||
let collider = this.getComponent(Collider2D);
|
||||
if(collider) {
|
||||
collider.group = this.group;
|
||||
collider.on(Contact2DType.BEGIN_CONTACT, this.onBeginContact, this);
|
||||
}
|
||||
}
|
||||
do_anim(){
|
||||
if(this.node.getComponent(Animation)){
|
||||
let anim = this.node.getComponent(Animation);
|
||||
//console.log("[SkillCom]:has anim",anim)
|
||||
anim.on(Animation.EventType.FINISHED, this.onAnimationFinished, this);
|
||||
}
|
||||
|
||||
}
|
||||
do_parabolic(){
|
||||
let bm=this.node.getComponent(BezierMove)
|
||||
this.node.angle +=10
|
||||
// bm.speed=700
|
||||
if(this.group==BoxSet.MONSTER) {bm.controlPointSide=-1 }
|
||||
bm.rotationSmoothness=0.6
|
||||
bm.moveTo(this.targetPos)
|
||||
}
|
||||
do_line(){
|
||||
let bm=this.node.getComponent(BezierMove)
|
||||
let s_x=this.startPos.x
|
||||
let s_y=this.startPos.y
|
||||
let t_x=this.targetPos.x
|
||||
let t_y=this.targetPos.y
|
||||
// 设定目标x
|
||||
this.targetPos.x = 400;
|
||||
if(this.group == BoxSet.MONSTER) {
|
||||
bm.controlPointSide = -1;
|
||||
this.targetPos.x = -400;
|
||||
}
|
||||
// 计算斜率
|
||||
const k = (t_y - s_y) / (t_x - s_x);
|
||||
// 按直线公式计算新的y
|
||||
this.targetPos.y = k * (this.targetPos.x - s_x) + s_y;
|
||||
bm.controlPointOffset=0
|
||||
bm.rotationSmoothness=0.6
|
||||
bm.moveTo(this.targetPos);
|
||||
}
|
||||
do_fixedEnd(){
|
||||
this.node.setPosition(this.targetPos.x > 360?300:this.targetPos.x,this.node.position.y,0)
|
||||
this.do_anim()
|
||||
}
|
||||
do_fixedStart(){
|
||||
this.node.setPosition(this.startPos.x,this.node.position.y,0)
|
||||
this.do_anim()
|
||||
}
|
||||
|
||||
onAnimationFinished(){
|
||||
// console.log("[SkillCom]:onAnimationFinished",this.s_uuid)
|
||||
if (!this.Config) return;
|
||||
|
||||
if(this.Config.EType==EType.timeEnd) return
|
||||
if(this.Config.SType!=SType.damage){
|
||||
|
||||
}
|
||||
this.is_destroy=true
|
||||
}
|
||||
onBeginContact (seCol: Collider2D, oCol: Collider2D) {
|
||||
// console.log(this.scale+"碰撞开始 ",seCol,oCol);
|
||||
if(seCol.node.position.x-oCol.node.position.x > 100 ) return
|
||||
let target = oCol.getComponent(HeroViewComp)
|
||||
if(oCol.group!=this.group){
|
||||
if(target == null) return;
|
||||
if (!this.Config) return;
|
||||
// console.log("[SkillCom]:onBeginContact oCol||seCol",oCol.node.position,seCol.node.position)
|
||||
this.single_damage(target,this.Config.DTType==DTType.range?true:false)
|
||||
// this.ent.destroy()
|
||||
}
|
||||
}
|
||||
//单体伤害
|
||||
single_damage(target:HeroViewComp,is_range:boolean=false){
|
||||
// //console.log("[SkillCom]:onBeginContact hit_count:",this.hit_count,SkillSet[this.s_uuid].hit)
|
||||
// if(this.hit_count > 0&&!is_range) this.ap=this.ap*(50+this.puncture_damage)/100 // 穿刺后 伤害减半,过滤范围伤害
|
||||
if(target == null) return;
|
||||
if (!this.Config) return;
|
||||
let damage=Math.floor(this.Attrs[Attrs.AP]*(SkillSet[this.s_uuid].ap/100))
|
||||
if(this.hit_count > 0 &&!is_range ){
|
||||
let Percentage=Math.pow((50+this.Attrs[Attrs.PUNCTURE_DMG])/100, this.hit_count)
|
||||
damage=damage*Percentage
|
||||
}
|
||||
target.do_atked(damage,this.Attrs,this.s_uuid) // ap 及暴击 属性已经在skill.ts 处理
|
||||
// console.log("[SkillCom]:single_damage t:tp:rtp",this.node.position,this.targetPos,target.node.position)
|
||||
this.hit_count++
|
||||
// console.log("[SkillCom]:碰撞次数:技能次数:穿刺次数",this.hit_count,this.Config.hit,this.puncture)
|
||||
if(this.hit_count>=(this.Config.hit+this.Attrs[Attrs.PUNCTURE])&&(this.Config.DTType!=DTType.range)&&(this.Config.EType!=EType.animationEnd)&&(this.Config.EType!=EType.timeEnd)) this.is_destroy=true // 技能命中次数
|
||||
}
|
||||
update(deltaTime: number) {
|
||||
// 确保配置已初始化(处理 update 可能先于 start 执行的情况)
|
||||
if (!this.isInitialized) {
|
||||
this.initializeConfig();
|
||||
if (!this.Config) return;
|
||||
}
|
||||
|
||||
if(smc.mission.pause) {
|
||||
if(this.anim) this.anim.pause()
|
||||
return;
|
||||
}
|
||||
if(this.anim) this.anim.resume()
|
||||
if (!this.node || !this.node.isValid) return;
|
||||
|
||||
if(this.Config.EType==EType.timeEnd){
|
||||
this.run_time+=deltaTime
|
||||
if(this.run_time>this.Config.in){
|
||||
// //console.log("[SkillCom]: timeEnd destroy",this.s_uuid,this.run_time)
|
||||
this.is_destroy=true
|
||||
}
|
||||
}
|
||||
|
||||
this.toDestroy();
|
||||
}
|
||||
public atk(args:any){
|
||||
let dis=this.node.getComponent(UITransform).width/2
|
||||
let targetsInRange: HeroViewComp[] = []
|
||||
|
||||
// 收集范围内所有敌方目标
|
||||
ecs.query(ecs.allOf(HeroViewComp)).some(e => {
|
||||
const view = e.get(HeroViewComp);
|
||||
if(view.fac!=this.fac) {
|
||||
const distance = Math.abs(this.node.position.x - view.node.position.x);
|
||||
if(distance <= dis) {
|
||||
targetsInRange.push(view);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// 根据配置的hit_num决定攻击模式
|
||||
const hitNum = SkillSet[this.s_uuid].hit_num || 0;
|
||||
if(hitNum > 0) {
|
||||
// 限制目标数量:按距离排序,选择最近的N个目标
|
||||
if(targetsInRange.length > 0) {
|
||||
// 按距离排序(从近到远)
|
||||
targetsInRange.sort((a, b) => {
|
||||
const distanceA = Math.abs(this.node.position.x - a.node.position.x);
|
||||
const distanceB = Math.abs(this.node.position.x - b.node.position.x);
|
||||
return distanceA - distanceB;
|
||||
});
|
||||
|
||||
// 限制目标数量
|
||||
const maxTargets = Math.min(hitNum, targetsInRange.length);
|
||||
const selectedTargets = targetsInRange.slice(0, maxTargets);
|
||||
|
||||
selectedTargets.forEach(target => {
|
||||
this.single_damage(target, false);
|
||||
});
|
||||
}
|
||||
} else {
|
||||
// 范围伤害:对所有范围内目标造成伤害
|
||||
if(targetsInRange.length > 0) {
|
||||
targetsInRange.forEach(target => {
|
||||
this.single_damage(target, false);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
toDestroy() {
|
||||
if(this.is_destroy){
|
||||
if (this.ent) {
|
||||
this.ent.destroy();
|
||||
} else {
|
||||
// 如果ent不存在,直接销毁节点
|
||||
if (this.node && this.node.isValid) {
|
||||
this.node.destroy();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
doDestroy(){
|
||||
// //console.log("[SkillCom]:doDestroy")
|
||||
this.is_destroy=true
|
||||
}
|
||||
reset() {
|
||||
this.node.destroy();
|
||||
}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
{
|
||||
"ver": "4.0.24",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "411a8c58-dab3-45d4-92d9-9fe420a9faa0",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS";
|
||||
import { smc } from "../common/SingletonModuleComp";
|
||||
|
||||
/** 业务层对象 */
|
||||
@ecs.register('EndAnmCom')
|
||||
@@ -17,8 +18,7 @@ export class EndAnmComSystem extends ecs.ComblockSystem implements ecs.IEntityEn
|
||||
|
||||
entityEnter(e: ecs.Entity): void {
|
||||
// 注:自定义业务逻辑
|
||||
|
||||
|
||||
if(!smc.mission.play || smc.mission.pause) return;
|
||||
e.remove(EndAnmComComp);
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@ import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ec
|
||||
import { RType, EType, SkillSet } from "../common/config/SkillSet";
|
||||
import { BoxSet } from "../common/config/BoxSet";
|
||||
import { SkillView } from "./SkillView";
|
||||
import { smc } from "../common/SingletonModuleComp";
|
||||
|
||||
/**
|
||||
* ==================== 技能移动数据组件 ====================
|
||||
@@ -283,6 +284,7 @@ export class SMoveSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate
|
||||
}
|
||||
|
||||
entityEnter(entity: ecs.Entity): void {
|
||||
if(!smc.mission.play || smc.mission.pause) return;
|
||||
const moveComp = entity.get(SMoveDataComp);
|
||||
const skillView = entity.get(SkillView);
|
||||
|
||||
@@ -354,6 +356,7 @@ export class SMoveSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate
|
||||
}
|
||||
|
||||
update(entity: ecs.Entity): void {
|
||||
if(!smc.mission.play || smc.mission.pause) return;
|
||||
const moveComp = entity.get(SMoveDataComp);
|
||||
const skillView = entity.get(SkillView);
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ import { DamageQueueHelper } from "../hero/DamageQueueComp";
|
||||
const { ccclass, property } = _decorator;
|
||||
|
||||
/** 视图层对象 */
|
||||
@ccclass('SkillViewComp')
|
||||
@ccclass('SkillView')
|
||||
@ecs.register('SkillView', false)
|
||||
export class SkillView extends CCComp {
|
||||
/** 视图层逻辑代码分离演示 */
|
||||
@@ -38,6 +38,7 @@ export class SkillView extends CCComp {
|
||||
if(collider) {
|
||||
collider.group = this.group;
|
||||
collider.on(Contact2DType.BEGIN_CONTACT, this.onBeginContact, this);
|
||||
console.log(`[skillView] ${this.sData.caster.ent.get(HeroAttrsComp).hero_name}的 ${this.SConf.name} 碰撞组 ${this.group}`)
|
||||
}
|
||||
if(this.node.getComponent(Animation)){
|
||||
let anim = this.node.getComponent(Animation);
|
||||
@@ -47,7 +48,7 @@ export class SkillView extends CCComp {
|
||||
|
||||
}
|
||||
onBeginContact (seCol: Collider2D, oCol: Collider2D) {
|
||||
// console.log(this.scale+"碰撞开始 ",seCol,oCol);
|
||||
console.log(`[skillView] ${this.sData.caster.ent.get(HeroAttrsComp).hero_name}的 ${this.SConf.name} 碰撞了 ${oCol.getComponent(HeroViewComp).ent.get(HeroAttrsComp).hero_name}`);
|
||||
if(this.SConf.EType!=EType.collision) return
|
||||
let target = oCol.getComponent(HeroViewComp)
|
||||
let model=target.ent.get(HeroAttrsComp)
|
||||
|
||||
@@ -1,156 +0,0 @@
|
||||
import { _decorator, CCBoolean, CCFloat, CCInteger, instantiate, Node, Prefab, v3, Vec3 } 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 { HeroViewComp } from "../hero/HeroViewComp";
|
||||
import { RType, SkillSet } from "../common/config/SkillSet";
|
||||
import { AtkConCom } from "./AtkConCom";
|
||||
import { BoxSet } from "../common/config/BoxSet";
|
||||
|
||||
const { ccclass, property } = _decorator;
|
||||
|
||||
/** 视图层对象 */
|
||||
@ccclass('SkillViewCom')
|
||||
@ecs.register('SkillView', false)
|
||||
export class SkillViewCom extends CCComp {
|
||||
/** 视图层逻辑代码分离演示 */
|
||||
@property({ type: Prefab })
|
||||
atkPrefab: Prefab = null!
|
||||
@property
|
||||
hasReady: boolean = false
|
||||
@property
|
||||
withHero: boolean = true
|
||||
@property
|
||||
ReadyLoop: boolean = false // 预备是否循环
|
||||
@property({ type: CCFloat })
|
||||
SkillTime: number = 0 // 技能控制存续时间时间
|
||||
@property({ type: CCFloat })
|
||||
ReadyTime: number = 0 // 技能前摇时间
|
||||
@property({ type: CCInteger })
|
||||
runType: number = 0 //技能运行类型 0-线性 1-贝塞尔 2-开始位置固定 3-目标位置固定
|
||||
@property({ type: CCInteger })
|
||||
ready_y: number = 0
|
||||
@property({ type: CCInteger })
|
||||
atk_x: number = 0
|
||||
@property({ type: CCInteger })
|
||||
atk_y: number = 0
|
||||
@property({ type: CCInteger })
|
||||
s_count:number=1;
|
||||
@property({ type: CCFloat })
|
||||
s_interval:number=0.2;
|
||||
|
||||
endTime: number = 0;
|
||||
readyFinish: boolean = false;
|
||||
caster:HeroViewComp=null!;
|
||||
s_uuid:number=0;
|
||||
s_cd:number=0;
|
||||
scale: number = 0;
|
||||
cName:string="";
|
||||
target:HeroViewComp=null;
|
||||
parent:Node=null;
|
||||
target_postions:any[]=null
|
||||
group:number=0
|
||||
fac:number=0
|
||||
// 战斗相关运行时数据
|
||||
Attrs:any=null
|
||||
startPos:any=null
|
||||
targetPos:any=null
|
||||
start() {
|
||||
// var entity = this.ent as ecs.Entity; // ecs.Entity 可转为当前模块的具体实体对象
|
||||
this.node.getChildByName("ready").active = this.hasReady
|
||||
this.node.setPosition(this.caster.node.position.x,this.caster.node.position.y+this.ready_y)
|
||||
}
|
||||
protected update(dt: number): void {
|
||||
this.doTimer(dt)
|
||||
this.move(dt)
|
||||
this.doEnd(dt)
|
||||
this.do_cd(dt)
|
||||
if(this.readyFinish) this.doAtk(dt)
|
||||
}
|
||||
doEnd(dt: number) {
|
||||
this.endTime += dt
|
||||
if(this.endTime >= this.SkillTime) {
|
||||
this.ent.destroy()
|
||||
}
|
||||
}
|
||||
|
||||
doTimer(dt: number){
|
||||
if(this.ReadyTime > 0) this.ReadyTime -= dt
|
||||
if(this.ReadyTime <=0) this.readyFinish=true
|
||||
}
|
||||
doAtk(dt:number): void {
|
||||
if(this.s_cd <= 0&&this.s_count > 0) {
|
||||
this.doSkill()
|
||||
this.s_count--
|
||||
this.s_cd = this.s_interval
|
||||
}
|
||||
}
|
||||
do_cd(dt:number){
|
||||
if(this.s_cd > 0) this.s_cd -= dt
|
||||
}
|
||||
doSkill(){
|
||||
if(this.atkPrefab!=null){
|
||||
let atkNode:Node = instantiate(this.atkPrefab)
|
||||
atkNode.parent = this.node.parent
|
||||
atkNode.setPosition(v3(this.node.position.x + this.atk_x*atkNode.scale.x, this.node.position.y + this.atk_y))
|
||||
if(this.node.scale.x < 0){
|
||||
atkNode.setScale(v3(atkNode.scale.x*-1,atkNode.scale.y,atkNode.scale.z))
|
||||
}
|
||||
let atkCom=atkNode.getComponent(AtkConCom)
|
||||
// 计算延长后的目标点坐标
|
||||
const originalStart = v3(this.node.position.x + this.atk_x, this.node.position.y + this.atk_y);
|
||||
const originalTarget = v3(this.targetPos[0].x, this.targetPos[0].y + BoxSet.ATK_Y);
|
||||
const direction = new Vec3();
|
||||
Vec3.subtract(direction, originalTarget, originalStart);
|
||||
const distance = direction.length();
|
||||
direction.normalize();
|
||||
const extendedTarget = new Vec3();
|
||||
Vec3.scaleAndAdd(extendedTarget, originalTarget, direction, 720);
|
||||
Object.assign(atkCom, {
|
||||
// 核心标识
|
||||
s_uuid: this.s_uuid,
|
||||
// 位置和施法者信息
|
||||
startPos: originalStart,
|
||||
targetPos: extendedTarget,
|
||||
group: this.group,
|
||||
fac: this.fac,
|
||||
// 技能数值
|
||||
Attrs:this.Attrs
|
||||
|
||||
});
|
||||
switch(this.runType){
|
||||
case RType.linear:
|
||||
this.do_linear(atkNode)
|
||||
break
|
||||
case RType.bezier:
|
||||
this.do_bezier(atkNode)
|
||||
break
|
||||
case RType.fixed:
|
||||
this.do_fixed(atkNode)
|
||||
break
|
||||
case RType.fixedEnd:
|
||||
this.do_fixedEnd(atkNode)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
do_linear(atkNode:any): void {
|
||||
atkNode.getComponent(AtkConCom).do_line()
|
||||
}
|
||||
do_bezier(atkNode:any): void {
|
||||
atkNode.getComponent(AtkConCom).do_parabolic()
|
||||
}
|
||||
do_fixed(atkNode:any): void {
|
||||
atkNode.getComponent(AtkConCom).do_fixedStart()
|
||||
}
|
||||
do_fixedEnd(atkNode:any): void {
|
||||
atkNode.getComponent(AtkConCom).do_fixedEnd()
|
||||
}
|
||||
move(dt: number): void {
|
||||
// console.log(`${this.cName}_[SkillViewCom] move`)
|
||||
if(this.caster != null&&this.caster.node!=null&&this.withHero) this.node.setPosition(this.caster.node.position.x,this.caster.node.position.y+this.ready_y)
|
||||
// console.log(`${this.cName}_[skillview]move`,this.caster.node.position,this.node.position)
|
||||
}
|
||||
reset() {
|
||||
this.node.destroy();
|
||||
}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
{
|
||||
"ver": "4.0.24",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "fa24efd6-db87-4a3a-957f-cde0cc3a4054",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
Reference in New Issue
Block a user