You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
283 lines
11 KiB
283 lines
11 KiB
import { _decorator, Component, Node, v3, Vec3 } from 'cc';
|
|
import { Skill } from './Skill';
|
|
import { GBundle } from '../../../game/ConfigRes';
|
|
import { WeaponType } from '../../../manager/WeaponDataManager';
|
|
import { GEvent } from 'db://assets/mx/module/event/GEvent';
|
|
const { ccclass, property } = _decorator;
|
|
|
|
@ccclass('iceWeaponSchedule')
|
|
export class iceWeaponSchedule extends Component {
|
|
@property({ type: Node, tooltip: "技能效果层上" })
|
|
skillLayerTop: Node = null;
|
|
|
|
//武器初始个数 冰棒
|
|
private bgWeaponCount: number = 0
|
|
private binggunNodeArray: Node[] = [] //所有的冰棒武器
|
|
|
|
// 缓存主角的发射点,避免 update 内反复 getChildByName/clone
|
|
private _weaponLaunchNode: Node | null = null;
|
|
private _tmpIceConePos: Vec3 = v3(0, 0, 0);
|
|
|
|
//冰棍转转转
|
|
specialSkillInfo = [];
|
|
|
|
rotateSpeed: number = 1;
|
|
rotateVolume: number = 1;
|
|
isCreateBinggun: boolean = false;
|
|
|
|
specialTimeFix = 1
|
|
specialTimeAdd = 0
|
|
binggunAllAtk: number = 0;
|
|
isBinggunCrit: boolean = false;
|
|
addRateAtk: number = 1;
|
|
|
|
getBgWeaponCount() {
|
|
return this.bgWeaponCount
|
|
}
|
|
setBgWeaponCount(count: number) {
|
|
this.bgWeaponCount = count
|
|
}
|
|
|
|
setGameData(rotateVolume, rotateSpeed, specialSkillInfo, binggunAllAtk, isBinggunCrit, specialTimeFix) {
|
|
this.rotateVolume = rotateVolume
|
|
this.rotateSpeed = rotateSpeed
|
|
this.specialSkillInfo = specialSkillInfo
|
|
this.binggunAllAtk = binggunAllAtk
|
|
this.isBinggunCrit = isBinggunCrit
|
|
this.specialTimeFix = specialTimeFix
|
|
this.addRateAtk = 1
|
|
}
|
|
getBinggunNodeArray() {
|
|
return this.binggunNodeArray
|
|
}
|
|
setBinggunNodeArray(arr: Node[]) {
|
|
this.binggunNodeArray = arr
|
|
}
|
|
|
|
setIsCreateBinggun(isCreate: boolean) {
|
|
this.isCreateBinggun = isCreate
|
|
}
|
|
|
|
|
|
start() {
|
|
this.rotateSpeed = 1;
|
|
this.rotateVolume = 1;
|
|
this.isCreateBinggun = false;
|
|
this.specialSkillInfo = [];
|
|
this.specialTimeFix = 1
|
|
this.specialTimeAdd = 0
|
|
this.binggunAllAtk = 0
|
|
this.isBinggunCrit = false
|
|
this.addRateAtk = 1
|
|
this.bgWeaponCount = 0
|
|
this.binggunNodeArray = []
|
|
GEvent.Ins.on(GEvent.GameRestart, this.gameRestart, this);
|
|
}
|
|
|
|
gameRestart() {
|
|
this.rotateSpeed = 1;
|
|
this.rotateVolume = 1;
|
|
this.isCreateBinggun = false;
|
|
this.specialSkillInfo = [];
|
|
this.specialTimeFix = 1
|
|
this.specialTimeAdd = 0
|
|
this.binggunAllAtk = 0
|
|
this.bgWeaponCount = 0
|
|
this.binggunNodeArray = []
|
|
this.isBinggunCrit = false
|
|
this.addRateAtk = 1
|
|
}
|
|
createBinggunNodeArray(weaponProperty, weaponId, weaponState) {
|
|
let radius = 100
|
|
let weaponCount = weaponProperty.weaponCount
|
|
|
|
|
|
this.rotateVolume = weaponProperty.volume
|
|
|
|
this.rotateSpeed = weaponProperty.rotateSpeed //转圈速率秒
|
|
if (this.rotateSpeed <= 0) {
|
|
this.rotateSpeed = 0.5
|
|
}
|
|
//console.log('冰棒+++武器旋转速率+++++++==',this.rotateSpeed)
|
|
this.specialSkillInfo = weaponProperty.specialSkillInfo //['13,2,3']
|
|
if (this.specialSkillInfo.length > 0) {
|
|
let arr = this.specialSkillInfo[0].split(',')
|
|
this.specialTimeFix = Number(arr[1])
|
|
|
|
}
|
|
this.binggunAllAtk = weaponProperty.allAtk
|
|
this.isBinggunCrit = weaponProperty.isCrit
|
|
this.addRateAtk = weaponProperty.addRateAtk
|
|
if (this.bgWeaponCount != weaponCount) {
|
|
|
|
if (this.specialSkillInfo.length > 0) {
|
|
let arr = this.specialSkillInfo[0].split(',')
|
|
this.specialTimeFix = Number(arr[1])
|
|
|
|
}
|
|
|
|
this.isCreateBinggun = true
|
|
//位置计算,围绕着主角旋转的
|
|
//每个节点的角度
|
|
let _angle = 360 / weaponCount
|
|
|
|
for (let k = this.bgWeaponCount; k < weaponCount; k++) {
|
|
|
|
this.scheduleOnce(async () => {
|
|
//计算旋转角度和偏移的位置
|
|
|
|
let angle = k * _angle;
|
|
let radian = angle * Math.PI / 180;
|
|
let addPos = v3(
|
|
Math.cos(radian) * radius,
|
|
Math.sin(radian) * radius,
|
|
0
|
|
);
|
|
|
|
//gg.audio.playEffect({ name: '牙签受击',path:'sound/武器音效/'});
|
|
let weaponNode = await this.instantiateSingleWeapon(weaponId, weaponProperty.volume, addPos)
|
|
if (!weaponNode) return;
|
|
let skillComp = weaponNode.getComponent(Skill);
|
|
// weaponNode['specialTimeAdd'] = 0
|
|
this.binggunNodeArray.push(weaponNode)
|
|
|
|
//weaponNode.angle = angle;
|
|
skillComp.setData(weaponState.config, v3(0, 0, 0));
|
|
skillComp.setInstanceId(100000 + k)
|
|
|
|
if (k == weaponCount - 1) {
|
|
for (let kk = 0; kk < this.binggunNodeArray.length; kk++) {
|
|
let angle = kk * _angle;
|
|
let radian = angle * Math.PI / 180;
|
|
let addPos = v3(
|
|
Math.cos(radian) * radius,
|
|
Math.sin(radian) * radius,
|
|
0
|
|
);
|
|
const wp = gg.game.CurentBattle.PlayerController.playerNode
|
|
.getChildByName('weaponLaunchNode')
|
|
.worldPosition.clone()
|
|
.add(addPos);
|
|
this.binggunNodeArray[kk].setWorldPosition(wp);
|
|
this.binggunNodeArray[kk].angle = angle;
|
|
if (kk == this.binggunNodeArray.length - 1) {
|
|
this.isCreateBinggun = false
|
|
}
|
|
}
|
|
|
|
}
|
|
}, 0.05)
|
|
}
|
|
|
|
|
|
this.bgWeaponCount = weaponCount
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
/**
|
|
* 实例化单个武器
|
|
* @param weaponId 武器ID
|
|
* @param volume 武器缩放比例
|
|
* @param addPos 武器位置偏移
|
|
* @param index 第几个位置
|
|
*/
|
|
async instantiateSingleWeapon(weaponId: number, volume: number, addPos?: Vec3, index?: number) {
|
|
|
|
let weaponNode = await gg.res.getNodeAsync(`prefab/武器/`, `weapon${weaponId}`, GBundle.BattleGameWeapon)
|
|
if (!weaponNode) return null;
|
|
weaponNode.setParent(this.node, true);
|
|
weaponNode.scale = v3(volume, volume, 1)
|
|
const add = addPos ?? v3(0, 0, 0);
|
|
weaponNode.worldPosition = gg.game.CurentBattle.PlayerController.playerNode
|
|
.getChildByName('weaponLaunchNode')
|
|
.worldPosition.clone()
|
|
.add(add);
|
|
|
|
return weaponNode
|
|
}
|
|
|
|
update(dt: number) {
|
|
if (!gg.game.CurentBattle.canUpdateFrame()) {
|
|
return
|
|
}
|
|
const scaledDt = dt * gg.game.CurentBattle.TimeScale;
|
|
if (this.binggunNodeArray.length && this.isCreateBinggun == false) {
|
|
|
|
let radius = 100; // 旋转半径
|
|
|
|
// 计算每秒旋转角度:360度 / 旋转一周时间
|
|
let rotateAnglePerSecond = 360 / this.rotateSpeed;
|
|
// 根据实际帧间隔计算每次需要旋转的角度
|
|
let rotateAnglePerFrame = rotateAnglePerSecond * scaledDt;
|
|
|
|
// 遍历所有冰棒节点,实现流畅旋转
|
|
if (!this._weaponLaunchNode || !this._weaponLaunchNode.isValid) {
|
|
this._weaponLaunchNode = gg.game.CurentBattle.PlayerController.playerNode.getChildByName('weaponLaunchNode');
|
|
}
|
|
const basePos = this._weaponLaunchNode!.worldPosition;
|
|
const baseX = basePos.x;
|
|
const baseY = basePos.y - 50;
|
|
const baseZ = basePos.z;
|
|
|
|
for (let index = 0; index < this.binggunNodeArray.length; index++) {
|
|
const weaponNode = this.binggunNodeArray[index];
|
|
if (weaponNode && weaponNode.isValid) {
|
|
weaponNode.setScale(this.rotateVolume, this.rotateVolume, 1);
|
|
weaponNode.angle -= rotateAnglePerFrame;
|
|
|
|
if (weaponNode.angle <= 0) weaponNode.angle += 360;
|
|
|
|
// 计算新的位置偏移量(保持围绕主角旋转)
|
|
const radian = weaponNode.angle * Math.PI / 180;
|
|
const addX = Math.cos(radian) * radius;
|
|
const addY = Math.sin(radian) * radius;
|
|
weaponNode.setWorldPosition(baseX + addX, baseY + addY, baseZ);
|
|
}
|
|
}
|
|
//有特殊技能,每把刀specialTimeFix秒释放冰锥,释放的时候刀的角度在前方,后方不释放冰锥
|
|
if (this.specialSkillInfo.length > 0) {
|
|
let fixNum = 4
|
|
this.specialTimeAdd += scaledDt
|
|
if (this.specialTimeAdd >= this.specialTimeFix) {
|
|
this.specialTimeAdd = 0
|
|
const arr = this.specialSkillInfo[0].split(',');
|
|
const atk = this.binggunAllAtk * Number(arr[2]);
|
|
const scale = this.rotateVolume;
|
|
const baseZ = basePos.z;
|
|
const spacing = (40 + 5) * scale;
|
|
// 需求保持固定向上:前方行中心点始终在玩家上方
|
|
const forwardDist = 220 * scale;
|
|
const centerX = basePos.x;
|
|
const centerY = basePos.y + forwardDist;
|
|
const validWeapons = this.binggunNodeArray.filter(n => !!n && n.isValid);
|
|
const emitCount = Math.min(fixNum, validWeapons.length);
|
|
const half = (emitCount - 1) * 0.5;
|
|
|
|
for (let i = 0; i < emitCount; i++) {
|
|
const weaponNode = validWeapons[i];
|
|
const lateral = (i - half) * spacing;
|
|
const x = centerX + lateral;
|
|
const y = centerY;
|
|
this._tmpIceConePos.set(x, y, baseZ);
|
|
const skill = weaponNode.getComponent(Skill);
|
|
if (!skill) continue;
|
|
skill.playIceCone('冰棒刀冰锥', this._tmpIceConePos, scale, 80 * scale, atk, this.isBinggunCrit, this.addRateAtk, this.skillLayerTop)
|
|
}
|
|
}
|
|
|
|
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
onDestroy() {
|
|
GEvent.Ins.off(GEvent.GameRestart, this.gameRestart, this);
|
|
this.unscheduleAllCallbacks()
|
|
}
|
|
}
|
|
|
|
|
|
|