first commit
This commit is contained in:
82
assets/scripts/Preview.ts
Normal file
82
assets/scripts/Preview.ts
Normal file
@@ -0,0 +1,82 @@
|
||||
// assets/scripts/Preview.ts
|
||||
import { _decorator, Component, Node, Prefab, instantiate, Vec3 } from "cc";
|
||||
import { BallPhysics } from "./BallPhysics";
|
||||
const { ccclass, property } = _decorator;
|
||||
|
||||
@ccclass("Preview")
|
||||
export class Preview extends Component {
|
||||
@property(Prefab) pointPrefab: Prefab = null!;
|
||||
@property(Node) goal: Node = null!;
|
||||
|
||||
@property({ tooltip: "轨迹点数量" }) maxPoints = 30;
|
||||
@property({ tooltip: "步长时间(秒)" }) timeStep = 0.05;
|
||||
|
||||
@property(BallPhysics) ballPhys: BallPhysics = null!;
|
||||
|
||||
private points: Node[] = [];
|
||||
|
||||
clear() {
|
||||
for (const p of this.points) p.destroy();
|
||||
this.points.length = 0;
|
||||
}
|
||||
|
||||
/** 显示预测轨迹 */
|
||||
showTrajectory(startPos: Vec3, dir: Vec3, speed: number, spin: Vec3) {
|
||||
this.clear();
|
||||
if (!this.pointPrefab || !this.ballPhys) return;
|
||||
|
||||
const goalZ = this.goal?.worldPosition?.z;
|
||||
|
||||
// 初始状态
|
||||
let pos = startPos.clone();
|
||||
let v = dir.clone().multiplyScalar(speed);
|
||||
let w = spin.clone(); // 自旋
|
||||
|
||||
// 迭代预测
|
||||
// let age = 0;
|
||||
for (let i = 0; i < this.maxPoints; i++) {
|
||||
// age += this.timeStep;
|
||||
// 保存点
|
||||
const p = instantiate(this.pointPrefab);
|
||||
p.setWorldPosition(pos);
|
||||
p.setParent(this.node);
|
||||
this.points.push(p);
|
||||
|
||||
// === 模拟 BallPhysics.update(dt) ===
|
||||
// const dt = this.timeStep;
|
||||
const dt = this.timeStep * 0.5;
|
||||
|
||||
// 空气阻力
|
||||
const speedNow = v.length();
|
||||
if (speedNow > 0.01) {
|
||||
const drag = v.clone().multiplyScalar(-this.ballPhys.dragK * speedNow);
|
||||
v.add(drag.multiplyScalar(dt));
|
||||
}
|
||||
|
||||
// 马格努斯效应:F = k * (ω × v)
|
||||
if (w.lengthSqr() > 0.0001 && v.lengthSqr() > 0.0001) {
|
||||
// const tFactor = 1.0 / (1.0 + age * 2.0); // age 是飞行时间,越久衰减越快
|
||||
// const magnus = w
|
||||
// .clone()
|
||||
// .cross(v)
|
||||
// .multiplyScalar(this.ballPhys.magnusK * tFactor);
|
||||
// v.add(magnus.multiplyScalar(dt));
|
||||
const magnus = w.clone().cross(v).multiplyScalar(this.ballPhys.magnusK);
|
||||
v.add(magnus.multiplyScalar(dt));
|
||||
}
|
||||
|
||||
// 重力
|
||||
v.y += -9.8 * dt;
|
||||
|
||||
// 移动
|
||||
pos = pos.add(v.clone().multiplyScalar(dt));
|
||||
|
||||
if (
|
||||
(startPos.z > goalZ && pos.z <= goalZ) ||
|
||||
(startPos.z < goalZ && pos.z >= goalZ)
|
||||
) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user