@cc-component/cc-fly 0.0.0-stage → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.cc-ex-component.md +12 -0
- package/assets/fly/Interface.ts +32 -0
- package/assets/fly/Interface.ts.meta +9 -0
- package/assets/fly/base/BuffUI.ts +68 -0
- package/assets/fly/base/BuffUI.ts.meta +9 -0
- package/assets/fly/base/FlyArrowLauncher.ts +166 -0
- package/assets/fly/base/FlyArrowLauncher.ts.meta +9 -0
- package/assets/fly/base/FlyBaseBullet.ts +9 -0
- package/assets/fly/base/FlyBaseBullet.ts.meta +9 -0
- package/assets/fly/base/FlyBaseHit.ts +10 -0
- package/assets/fly/base/FlyBaseHit.ts.meta +9 -0
- package/assets/fly/base/FlyBaseHp.ts +96 -0
- package/assets/fly/base/FlyBaseHp.ts.meta +9 -0
- package/assets/fly/base/FlyBasePlayer.ts +359 -0
- package/assets/fly/base/FlyBasePlayer.ts.meta +9 -0
- package/assets/fly/base/FlyDamageLabel.ts +198 -0
- package/assets/fly/base/FlyDamageLabel.ts.meta +9 -0
- package/assets/fly/base/FlyDamageLabelManager.ts +111 -0
- package/assets/fly/base/FlyDamageLabelManager.ts.meta +9 -0
- package/assets/fly/base/FlyModule.ts +145 -0
- package/assets/fly/base/FlyModule.ts.meta +9 -0
- package/assets/fly/base/FlyNodePoolUtil.ts +56 -0
- package/assets/fly/base/FlyNodePoolUtil.ts.meta +9 -0
- package/assets/fly/base/FlyPlayerBuffSystem.ts +673 -0
- package/assets/fly/base/FlyPlayerBuffSystem.ts.meta +9 -0
- package/assets/fly/base/FlyPooledParticleEffect.ts +58 -0
- package/assets/fly/base/FlyPooledParticleEffect.ts.meta +9 -0
- package/assets/fly/base/FlySkiiManager.ts +19 -0
- package/assets/fly/base/FlySkiiManager.ts.meta +9 -0
- package/assets/fly/base.meta +9 -0
- package/assets/fly.meta +9 -0
- package/assets/pathfinding.meta +9 -0
- package/assets.meta +9 -0
- package/index.ts +19 -0
- package/index.ts.meta +9 -0
- package/package.json +18 -5
- package/package.json.meta +11 -0
- package/README.md +0 -3
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import { randomRangeInt, tween, misc } from 'cc';
|
|
2
|
+
import { Vec3 } from 'cc';
|
|
3
|
+
import { _decorator, Component, Node, v3 } from 'cc';
|
|
4
|
+
import { FlyBasePlayer } from './FlyBasePlayer';
|
|
5
|
+
import { FlySkiiManager } from './FlySkiiManager';
|
|
6
|
+
import { PlayerBuffType } from './FlyPlayerBuffSystem';
|
|
7
|
+
|
|
8
|
+
const { ccclass, property } = _decorator;
|
|
9
|
+
|
|
10
|
+
@ccclass('FlyModule')
|
|
11
|
+
export class FlyModule {
|
|
12
|
+
private static instance: FlyModule;
|
|
13
|
+
private constructor() {
|
|
14
|
+
|
|
15
|
+
}
|
|
16
|
+
static get Ins() {
|
|
17
|
+
if (!this.instance) {
|
|
18
|
+
this.instance = new FlyModule();
|
|
19
|
+
}
|
|
20
|
+
return this.instance;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* 开始抛物线缓动
|
|
24
|
+
* @param item 运动节点
|
|
25
|
+
* @param target_postion 目标位置
|
|
26
|
+
* @param update 更新 运动中回调
|
|
27
|
+
* @param offset_ratio 最高点 的偏移量
|
|
28
|
+
* @param time 动画时间
|
|
29
|
+
* @param speed 速度,>0 时优先使用速度计算时间
|
|
30
|
+
* @param is_random 是否随机上下方向
|
|
31
|
+
* @param start_position 起始位置--比如 父节点的位置和 抛物线的起点位置 不同,,用父节点的起始位置就传入
|
|
32
|
+
*/
|
|
33
|
+
static RunParabola(item: Node, target_postion: Vec3, update: (ratio: number) => void, param?: { offset_ratio?: number, is_random: boolean, time?: number, speed?: number, scale_offset_with_distance?: boolean, offset_reference_distance?: number, start_position?: Vec3, is_end_clone?: boolean }) {
|
|
34
|
+
FlyModule.Ins.RunParabolaTween(item, target_postion, update, param)
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
RunParabolaTween(item: Node, target_postion: Vec3, update: (ratio: number) => void, param?: { offset_ratio?: number, is_random: boolean, time?: number, speed?: number, scale_offset_with_distance?: boolean, offset_reference_distance?: number, start_position?: Vec3, is_end_clone?: boolean }) {
|
|
38
|
+
const distance = Vec3.distance(target_postion, item.worldPosition)
|
|
39
|
+
const duration = param?.speed && param.speed > 0 ? (distance / param.speed) : (param?.time ?? 1)
|
|
40
|
+
|
|
41
|
+
const start = item.worldPosition.clone();
|
|
42
|
+
const end = target_postion
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
let fx = end.x >= (param?.start_position ? param?.start_position.x : start.x) ? 1 : -1;//朝向始终 是上抛物线,
|
|
46
|
+
if (param?.is_random) { fx = [-1, 1][randomRangeInt(0, 2)] }
|
|
47
|
+
|
|
48
|
+
const direction = end.clone().subtract(start).normalize();
|
|
49
|
+
let offset = direction.clone().multiplyScalar(distance * 0.5);
|
|
50
|
+
offset = start.add(offset)
|
|
51
|
+
//垂直方向的位置
|
|
52
|
+
const perpendicular = new Vec3(-direction.y, direction.x, 0);
|
|
53
|
+
const offsetRatio = param?.offset_ratio ?? 0.5;
|
|
54
|
+
const referenceDistance = Math.max(param?.offset_reference_distance ?? 500, 0.001);
|
|
55
|
+
const offsetScaleDistance = param?.scale_offset_with_distance === false ? referenceDistance : distance;
|
|
56
|
+
const offsetMagnitude = offsetScaleDistance * offsetRatio;
|
|
57
|
+
offset = offset.add(perpendicular.multiplyScalar(offsetMagnitude * fx))
|
|
58
|
+
offset = v3(offset.x, offset.y);
|
|
59
|
+
|
|
60
|
+
this.RunTween(item, offset, target_postion, duration, update)
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
RunTween(target: Node, peakPoint, endPoint, duration, update) {
|
|
64
|
+
let points = [target.worldPosition.clone(), peakPoint, endPoint];
|
|
65
|
+
const data = { ratio: 0 }
|
|
66
|
+
tween(data).to(duration, { ratio: 1 }, // 这里以node的位置信息坐标缓动的目标
|
|
67
|
+
{
|
|
68
|
+
// ITweenOption 的接口实现:
|
|
69
|
+
onUpdate: (target_data: { ratio: 0 }, ratio: number) => {
|
|
70
|
+
const pos = this.GetPosition(target_data.ratio, points)
|
|
71
|
+
const pos1 = this.GetPosition(Math.max(ratio * 1.1, 0.001), points)
|
|
72
|
+
target.setWorldPosition(pos.x, pos.y, pos.z);
|
|
73
|
+
this.LookAt(target, pos1)
|
|
74
|
+
update && update(ratio, pos)
|
|
75
|
+
}
|
|
76
|
+
}).start();
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
GetPosition(ratio, points) {
|
|
80
|
+
const t = ratio
|
|
81
|
+
// 二次贝塞尔曲线公式
|
|
82
|
+
let x = (1 - t) * (1 - t) * points[0].x + 2 * (1 - t) * t * points[1].x + t * t * points[2].x;
|
|
83
|
+
let y = (1 - t) * (1 - t) * points[0].y + 2 * (1 - t) * t * points[1].y + t * t * points[2].y;
|
|
84
|
+
const pos = v3(x, y);
|
|
85
|
+
return pos
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
LookAt(target: Node, endPoint: Vec3) {
|
|
89
|
+
const direction = endPoint.clone().subtract(target.worldPosition).normalize(); // 计算A点指向B点的方向向量
|
|
90
|
+
const angle = Math.atan2(direction.x, direction.y); // 计算夹角(弧度)
|
|
91
|
+
let euler = v3(0, 0, -misc.radiansToDegrees(angle)); // 应用欧拉角到A点
|
|
92
|
+
target.eulerAngles = euler
|
|
93
|
+
return angle;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
getEuler(start: Vec3, end: Vec3) {
|
|
97
|
+
const direction = end.clone().subtract(start).normalize(); // 计算A点指向B点的方向向量
|
|
98
|
+
const angle = Math.atan2(direction.x, direction.y); // 计算夹角(弧度)
|
|
99
|
+
let euler = v3(0, 0, -misc.radiansToDegrees(angle)); // 应用欧拉角到A点
|
|
100
|
+
return -misc.radiansToDegrees(angle);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* 生成抛物线上的指定数量坐标点
|
|
105
|
+
* @param start 起始点
|
|
106
|
+
* @param peak 控制点(峰值点)
|
|
107
|
+
* @param end 结束点
|
|
108
|
+
* @param count 点的数量
|
|
109
|
+
* @returns 坐标点数组
|
|
110
|
+
*/
|
|
111
|
+
generateParabolaPoints(param: { start: Vec3, end: Vec3, offset_ratio: number, count: number }) {
|
|
112
|
+
//中心点
|
|
113
|
+
const distance = Vec3.distance(param.start, param.end)
|
|
114
|
+
const direction = param.end.clone().subtract(param.start).normalize();
|
|
115
|
+
let center = direction.clone().multiplyScalar(distance * 0.5);
|
|
116
|
+
center = param.start.clone().add(center)
|
|
117
|
+
//中心点垂直方向的位置
|
|
118
|
+
const perpendicular = new Vec3(-direction.y, direction.x, 0);
|
|
119
|
+
center = center.add(perpendicular.multiplyScalar(distance * (param?.offset_ratio ?? 0.5)))
|
|
120
|
+
const points = [param.start, center, param.end];
|
|
121
|
+
const result: { positions: Vec3, rotion: number }[] = []
|
|
122
|
+
for (let i = 0; i < param.count; i++) {
|
|
123
|
+
const ratio = i / (param.count - 1);
|
|
124
|
+
const pos = this.GetPosition(ratio, points);
|
|
125
|
+
const pos1 = this.GetPosition(Math.max(ratio * 1.1, 0.001), points)
|
|
126
|
+
const euler = this.getEuler(pos, pos1)
|
|
127
|
+
result.push({ positions: pos, rotion: euler });
|
|
128
|
+
}
|
|
129
|
+
return result;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
//#endregion
|
|
134
|
+
/**技能释放动画 */
|
|
135
|
+
// static OnSkillAnim<T extends FlyBasePlayer>(primaryTarget: T, candidateTargets: readonly T[], onHit: (target: T) => void): void {
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
// }
|
|
140
|
+
static OnSkillAnim<T extends FlyBasePlayer>(call: (buffType: PlayerBuffType | any, attacker: T, primaryTarget: T, candidateTargets: readonly T[], onHit: (target: T) => void) => void): void {
|
|
141
|
+
FlySkiiManager.getInstance().EmitSkillAnim = call;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
window.FlyModule = FlyModule;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { instantiate, Node, NodePool, Prefab } from 'cc';
|
|
2
|
+
|
|
3
|
+
export class FlyNodePoolUtil {
|
|
4
|
+
private static readonly pools = new Map<string, NodePool>();
|
|
5
|
+
private static readonly templates = new Map<string, { template: Node | Prefab; parent: Node | null }>();
|
|
6
|
+
private static readonly nodePoolKeys = new WeakMap<Node, string>();
|
|
7
|
+
private static readonly maxPoolSize = 20;
|
|
8
|
+
|
|
9
|
+
static register(key: string, template: Node | Prefab, parent: Node | null = template instanceof Node ? template.parent : null): void {
|
|
10
|
+
const registration = this.templates.get(key);
|
|
11
|
+
if (registration && registration.template !== template) {
|
|
12
|
+
throw new Error(`NodePool key "${key}" is already used by another template.`);
|
|
13
|
+
}
|
|
14
|
+
this.templates.set(key, { template, parent });
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
static get(key: string): Node {
|
|
18
|
+
const registration = this.templates.get(key);
|
|
19
|
+
if (!registration) {
|
|
20
|
+
throw new Error(`报错了:NodePool key "${key}" has not been registered.`);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
let pool = this.pools.get(key);
|
|
24
|
+
if (!pool) {
|
|
25
|
+
pool = new NodePool();
|
|
26
|
+
this.pools.set(key, pool);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const node = pool.get() ?? (registration.template instanceof Node
|
|
30
|
+
? instantiate(registration.template)
|
|
31
|
+
: instantiate(registration.template));
|
|
32
|
+
this.nodePoolKeys.set(node, key);
|
|
33
|
+
node.setParent(registration.parent);
|
|
34
|
+
node.active = true;
|
|
35
|
+
return node;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
static put(node: Node): void {
|
|
39
|
+
if (!node?.isValid) return;
|
|
40
|
+
|
|
41
|
+
const key = this.nodePoolKeys.get(node);
|
|
42
|
+
const pool = key ? this.pools.get(key) : undefined;
|
|
43
|
+
if (!pool || pool.size() >= this.maxPoolSize) {
|
|
44
|
+
this.nodePoolKeys.delete(node);
|
|
45
|
+
node.destroy();
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
pool.put(node);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
static clear(key: string): void {
|
|
52
|
+
this.pools.get(key)?.clear();
|
|
53
|
+
this.pools.delete(key);
|
|
54
|
+
this.templates.delete(key);
|
|
55
|
+
}
|
|
56
|
+
}
|