64 lines
1.5 KiB
TypeScript
64 lines
1.5 KiB
TypeScript
import { _decorator, Component, Node, Prefab, instantiate, Vec3 } from "cc";
|
|
const { ccclass, property } = _decorator;
|
|
|
|
@ccclass("TrajectoryPreview")
|
|
export class TrajectoryPreview extends Component {
|
|
@property(Prefab)
|
|
pointPrefab: Prefab = null!;
|
|
|
|
@property
|
|
maxPoints: number = 20;
|
|
|
|
@property
|
|
timeStep: number = 0.1;
|
|
|
|
@property
|
|
gravity: Vec3 = new Vec3(0, -9.8, 0);
|
|
|
|
private points: Node[] = [];
|
|
|
|
onLoad() {
|
|
for (let i = 0; i < this.maxPoints; i++) {
|
|
const p = instantiate(this.pointPrefab);
|
|
p.active = false;
|
|
this.node.addChild(p); // 确保挂在场景下的空节点
|
|
this.points.push(p);
|
|
}
|
|
}
|
|
|
|
showTrajectory(
|
|
startPos: Vec3,
|
|
forward: Vec3,
|
|
power: number,
|
|
sideForce: number
|
|
) {
|
|
const velocity = forward.multiplyScalar(power);
|
|
velocity.x += sideForce;
|
|
|
|
const ballRadius = 0.01; // ⚽ 球半径
|
|
const groundY = 0; // 🟩 地面高度
|
|
|
|
for (let i = 0; i < this.maxPoints; i++) {
|
|
const t = i * this.timeStep;
|
|
|
|
const pos = new Vec3(
|
|
startPos.x + velocity.x * t,
|
|
startPos.y + velocity.y * t + 0.5 * this.gravity.y * t * t,
|
|
startPos.z + velocity.z * t
|
|
);
|
|
|
|
// ⭐ 限制最低不低于地面
|
|
if (pos.y < groundY + ballRadius * 0.5) {
|
|
pos.y = groundY + ballRadius * 0.5;
|
|
}
|
|
|
|
this.points[i].setWorldPosition(pos);
|
|
this.points[i].active = true;
|
|
}
|
|
}
|
|
|
|
hideTrajectory() {
|
|
this.points.forEach((p) => (p.active = false));
|
|
}
|
|
}
|