Files
heros/assets/script/game/skills/SkillCom.ts

285 lines
10 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 { _decorator,Collider2D ,Contact2DType,v3,IPhysics2DContact,Vec3, tween, math, RigidBody2D} 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 { smc } from "../common/SingletonModuleComp";
import { oops } from "../../../../extensions/oops-plugin-framework/assets/core/Oops";
import { GameEvent } from "../common/config/GameEvent";
import { AnimType, endType, SkillSet } from "../common/config/SkillSet";
import { EndAnmCom } from './EndAnmCom';
import { BoxSet } from "../common/config/BoxSet";
import { HeroFac, HeroSet } from "../common/config/heroSet";
import { HeroViewComp } from "../hero/HeroViewComp";
import { BezierMove } from "../BezierMove/BezierMove";
const { ccclass, property } = _decorator;
/** 视图层对象 */
@ccclass('SkillCom')
@ecs.register('SkillCom')
export class SkillCom extends CCComp {
s_uuid:number = 0;
s_name:string = "";
hero:number = 0;
speed:number = 200;
scale:number = 1;
angle:number = 0;
atk_count:number = 0;
is_destroy:boolean = false;
enemys:any = [];
animType: number = 0; // 运动类型
endType: number = 0; // 结束类型
inTime: number = 0; // 持续时间
startPos: Vec3 = v3(); // 起始位置
targetPos: Vec3 = v3(); // 目标位置
duration: number = 0; // 技能持续时间
prefabName: string = ""; // 预制体名称
animName: string = "";
group:number = 0; //阵营
fac:number=0; //阵营
caster:any=null;
distance_x:number=0;
distance_y:number=0;
ap:number=0;
private moveDirection: Vec3 | null = null; // 添加一个属性来存储移动方向
protected onLoad(): void {
}
start() {
oops.message.on(GameEvent.MissionEnd, this.doDestroy, this);
this.node.active = true;
let collider = this.getComponent(Collider2D);
// console.log(this.group +"技能 collider ",collider);
collider.group = this.group;
if (collider) {
collider.on(Contact2DType.BEGIN_CONTACT, this.onBeginContact, this);
}
if(SkillSet[this.s_uuid].AnimType==AnimType.parabolic){
this.node.angle +=10
let bm=this.node.getComponent(BezierMove)
// bm.speed=700
if(this.group==BoxSet.MONSTER) bm.controlPointSide=-1
bm.moveTo(this.targetPos)
}
// let dir_x = this.targetPos.x > this.node.position.x ? 1 : -1
// this.node.scale = v3(dir_x,1,1)
// 根据目标位置设置节点朝向
// if ( this.targetPos) {
// // 计算朝向
// let direction = this.targetPos.x > this.node.position.x ? 1 : -1;
// // 设置节点缩放来改变朝向
// this.node.scale = v3(direction * Math.abs(this.scale), this.scale, 1);
// }
// let dir_y = ( this.targetPos.y+BoxSet.ATK_Y) > this.node.position.y ? 1 : -1
// if( this.targetPos.y+BoxSet.ATK_Y==this.node.position.y){
// dir_y=0
// }
// // 计算这一帧的移动距离
// this.distance_x = SkillSet[this.s_uuid].speed*dir_x;
// this.distance_y = this.distance_x*Math.abs(this.targetPos.y-this.node.position.y)/Math.abs(this.targetPos.x-this.node.position.x)*dir_y;
// this.startMovement();
// // 计算目标角度
// if (this.targetPos) {
// const currentPos = this.node.position;
// // 计算角度(弧度)
// const dx = this.targetPos.x - currentPos.x;
// const dy = (this.targetPos.y + BoxSet.ATK_Y) - currentPos.y;
// const angle = Math.atan2(dy, dx);
// // 将弧度转换为角度并设置节点旋转
// this.angle = angle * 180 / Math.PI;
// this.node.angle = this.angle; // 移除负号,修正角度方向
// }
// // 计算速度分量
// const radians = this.angle * Math.PI / 180; // 移除负号,使用正确的角度
// this.distance_x = this.speed * Math.cos(radians);
// this.distance_y = this.speed * Math.sin(radians);
// this.startMovement();
// console.log("skill start",this.node.parent)
}
onBeginContact (seCol: Collider2D, oCol: Collider2D) {
// console.log(this.scale+"碰撞开始 ",seCol,oCol);
let target = oCol.getComponent(HeroViewComp)
let caster = seCol.getComponent(HeroViewComp)
if(oCol.group!=this.group){
if(target == null) return;
let remainingDamage = this.ap;
target.do_atked(remainingDamage)
this.ent.destroy()
}
}
private startMovement() {
switch(SkillSet[this.s_uuid].AnimType) {
case AnimType.parabolic:
this.startBezierMove();
break;
case AnimType.fixed:
this.startFixedMove();
break;
case AnimType.fixedStart:
this.startFixedStartMove();
break;
case AnimType.fixedEnd:
this.startFixedEndMove();
break;
}
}
private startLinearMove(dt: number) {
if (!this.speed || this.is_destroy) return;
// 使用角度方向移动
const newX = this.node.position.x + this.distance_x * dt;
const newY = this.node.position.y + this.distance_y * dt;
this.node.setPosition(newX, newY, this.node.position.z);
// 检查是否超出边界
if (newX < -400 || newX > 400) {
this.is_destroy = true;
}
}
private startBezierMove() {
// let s_pos = v3(this.startPos.x,this.startPos.y)
// let c_pos = v3((this.targetPos.x+this.startPos.x)/2,this.startPos.y+150)
// let e_pos = v3(this.targetPos.x,this.targetPos.y)
// let time =Math.abs(Math.abs(this.targetPos.x-this.startPos.x)/this.speed)
// // console.log("开始贝塞尔运动=>time:"+time,"s_pos:"+s_pos,"c_pos:"+c_pos,"e_pos:"+e_pos)
// SkillCom.bezierTo(this.node,time,s_pos,c_pos,e_pos,{
// onComplete: (target?: object) => {
// this.is_destroy=true
// },
// }).start();
}
private startFixedMove() {
if (this.endType === endType.timeEnd) {
tween(this.node)
.delay(this.inTime)
.call(() => this.is_destroy = true)
.start();
} else if (this.endType === endType.animationEnd) {
if (!this.node.getComponent(EndAnmCom)) {
this.node.addComponent(EndAnmCom);
}
}
}
private startFixedStartMove() {
// console.log("开始固定起点运动")
this.node.position = this.startPos;
if (this.endType === endType.timeEnd) {
// console.log("开始固定起点运动=>time:"+this.inTime)
tween(this.node)
.delay(this.inTime)
.call(() => this.is_destroy = true)
.start();
} else if (this.endType === endType.animationEnd) {
if (!this.node.getComponent(EndAnmCom)) {
this.node.addComponent(EndAnmCom);
}
}
}
private startFixedEndMove() {
// console.log("开始固定终点运动")
this.node.position = this.targetPos;
if (this.endType === endType.timeEnd) {
// console.log("开始固定终点运动=>time:"+this.inTime)
tween(this.node)
.delay(this.inTime)
.call(() => this.is_destroy = true)
.start();
} else if (this.endType === endType.animationEnd) {
if (!this.node.getComponent(EndAnmCom)) {
this.node.addComponent(EndAnmCom);
}
}
}
public static bezierTo(target: any, duration: number, c1: Vec3, c2: Vec3, to: Vec3, opts: any) {
opts = opts || Object.create(null);
/*
* @desc 二阶贝塞尔
* @param {number} t 当前百分比
* @param {} p1 起点坐标
* @param {} cp 控制点
* @param {} p2 终点坐标
* @returns {any}
*/
let twoBezier = (t:number, p1: Vec3, cp: Vec3, p2: Vec3) => {
let x = (1 - t) * (1 - t) * p1.x + 2 * t * (1 - t) * cp.x + t * t * p2.x;
let y = (1 - t) * (1 - t) * p1.y + 2 * t * (1 - t) * cp.y + t * t * p2.y;
return v3(x, y, 0);
};
opts.onUpdate = (arg: Vec3, ratio: number) => {
target.position = twoBezier(ratio, c1, c2, to);
};
return tween(target).to(duration, {}, opts);
}
to_console(value:any,value2:any=null,value3:any=null){
console.log("["+this.s_name+this.s_uuid+"]:",value,value2,value3)
}
update(deltaTime: number) {
if(smc.mission.pause) return;
if (!this.node || !this.node.isValid) return;
if(this.animType == AnimType.linear) this.startLinearMove(deltaTime);
this.toDestroy();
}
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("doDestroy")
this.is_destroy=true
}
/** 视图对象通过 ecs.Entity.remove(ModuleViewComp) 删除组件是触发组件处理自定义释放逻辑 */
reset() {
this.is_destroy = false;
this.animType = 0;
this.endType = 0;
this.speed = 0;
this.inTime = 0;
this.startPos.set();
this.targetPos.set();
this.moveDirection = null; // 重置移动方向
// 先移除所有碰撞回调
const collider = this.getComponent(Collider2D);
if (collider) {
collider.off(Contact2DType.BEGIN_CONTACT);
}
this.scheduleOnce(() => {
this.node.destroy();
}, 0);
}
}