first commit

This commit is contained in:
zzc
1970-01-01 08:45:37 +08:00
commit e9c9afb3b9
53 changed files with 5254 additions and 0 deletions

View File

@@ -0,0 +1,45 @@
// assets/scripts/GoalkeeperAI.ts
import { _decorator, Component, Node, RigidBody, Vec3, math } from "cc";
const { ccclass, property } = _decorator;
@ccclass("GoalkeeperAI")
export class GoalkeeperAI extends Component {
@property(Node) ball!: Node;
@property({ tooltip: "球门线Z世界坐标" }) goalLineZ = 10;
@property({ tooltip: "守门员水平活动范围X" }) rangeX = 3.5;
@property({ tooltip: "移动速度m/s" }) speed = 6;
@property({ tooltip: "反应延迟(秒)" }) reactDelay = 0.15;
private targetX = 0;
private tAcc = 0;
private tmp = new Vec3();
update(dt: number) {
if (!this.ball) return;
// 简化预测:用当前速度线性外推到球门线的交点
const rb = this.ball.getComponent(RigidBody);
if (!rb) return;
rb.getLinearVelocity(this.tmp);
const v = this.tmp.clone();
const bp = this.ball.worldPosition.clone();
if (Math.abs(v.z) < 0.1) return; // 几乎不朝球门方向飞
const timeToLine = (this.goalLineZ - bp.z) / v.z; // z 轴朝向球门
if (timeToLine < 0) return; // 已过线或背离
this.tAcc += dt;
if (this.tAcc >= this.reactDelay) {
const predictX = bp.x + v.x * timeToLine;
this.targetX = math.clamp(predictX, -this.rangeX, this.rangeX);
this.tAcc = 0; // 下次再延迟
}
// 移动守门员
const p = this.node.worldPosition;
const dx = this.targetX - p.x;
const step = math.clamp(dx, -this.speed * dt, this.speed * dt);
this.node.setWorldPosition(p.x + step, p.y, p.z);
}
}