Files
ball/assets/scripts/GoalkeeperAI.ts
1970-01-01 08:45:37 +08:00

46 lines
1.5 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// 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);
}
}