import { _decorator, Component, Node, Enum, Vec2, Vec3, v3, EventHandler } from 'cc'; const { ccclass, property } = _decorator; export enum WalkTargetType { Line, Random } export enum WalkDeleyDataType { Const, Random } export enum WalkDeleyType { Step, Round } @ccclass("WalkDeleyData") export class WalkDeleyData { @property({ type: Enum(WalkDeleyDataType), tooltip: "延迟类型:\nConst:固定时间\nRandom:随机时间" }) type: WalkDeleyDataType = WalkDeleyDataType.Const; @property({ tooltip: "延迟时间(常量)", visible() { return this.type == WalkDeleyDataType.Const; } }) private deley_const: number = 0; @property({ tooltip: "延迟时间(随机值)", visible() { return this.type == WalkDeleyDataType.Random; } }) private deley_random: Vec2 = new Vec2(); public get deley(): number { if (this.type == WalkDeleyDataType.Const) { return this.deley_const; } else if (this.type == WalkDeleyDataType.Random) { return this.random(this.deley_random.x, this.deley_random.y); } return 0; } private random(min: number, max: number): number { return min + Math.random() * (max - min); } } @ccclass('TakeAWalk') export class TakeAWalk extends Component { @property({ type: [Node], tooltip: "散步目标点" }) points: Array = []; @property({ tooltip: "速度系数(每帧)" }) speed = 1; @property({ type: Enum(WalkTargetType), tooltip: "散步目标选择方式:\nLine:根据目标点集合,逐个前往\nRandom:在目标点集合中随机选择前往" }) walkTargetType: WalkTargetType = WalkTargetType.Random; @property({ type: Enum(WalkDeleyType), tooltip: "散步延迟方式:\nStep:每到一个点开始延迟(随机目标,固定使用这个方式)\nRound:所有目标点都经过后开始延迟", visible() { return this.walkTargetType == WalkTargetType.Line; } }) deleyType: WalkDeleyType = WalkDeleyType.Step; @property({ tooltip: "线性行走完成后是否循环", visible() { return this.walkTargetType == WalkTargetType.Line; } }) loop: boolean = true; @property({ type: EventHandler, tooltip: "非循环模式,完成后的回调", visible() { return this.walkTargetType == WalkTargetType.Line && !this.loop; } }) complete: EventHandler; @property({ type: WalkDeleyData, tooltip: "散步延迟数据" }) deley: WalkDeleyData = new WalkDeleyData(); @property({ tooltip: "初始化时是否设置散步节点到第一个目标点位置" }) resetPosOnLoad = false; @property({ tooltip: "是否初始化后开始移动" }) walkOnLoad = false; private curPointIndex = -1; private walkTotleFarme = 0; private beenStop = false; /**当前目标点 */ public curTargetPoint: Vec3; /**当前状态 */ public state: WalkState = WalkState.Stop; start() { if (this.resetPosOnLoad) { this.curPointIndex = 0; this.node.setPosition(this.points[this.curPointIndex].position); } if (this.walkTargetType == WalkTargetType.Random) { this.deleyType = WalkDeleyType.Step; } this.walkOnLoad && this.walk(); } public walk(): void { this.beenStop = false; this.next(0); } public stop(): void { this.beenStop = true; this.state = WalkState.Stop; } private next(deley: number = -1): void { if (this.walkTargetType == WalkTargetType.Random) { this.curPointIndex = this.random_int(0, this.points.length - 1); } else { this.curPointIndex++; if (this.curPointIndex >= this.points.length) { if (this.loop) { this.curPointIndex = 0; } else { this.curPointIndex = -1; this.stop(); this.complete && this.complete.emit(null); return; } } } let d = 0; if (this.deleyType == WalkDeleyType.Step || (this.deleyType == WalkDeleyType.Round && this.curPointIndex == 0)) { d = this.deley.deley; } deley >= 0 && (d = deley); this.curTargetPoint = this.points[this.curPointIndex].position; let distance = Vec3.distance(this.node.position, this.curTargetPoint); this.walkTotleFarme = distance / this.speed; this.scheduleOnce(() => { this.state = WalkState.Walk; }, d); } update() { if (this.state == WalkState.Walk && !this.beenStop) { let angle = Math.atan2(this.curTargetPoint.y - this.node.position.y, this.curTargetPoint.x - this.node.position.x); let x = Math.cos(angle) * this.speed; let y = Math.sin(angle) * this.speed; this.node.setPosition(this.node.position.add(v3(x, y, 0))); this.walkTotleFarme--; if (this.walkTotleFarme <= 0) { this.node.setPosition(this.curTargetPoint); this.next(); this.state = WalkState.Stop; } } } private random_int(min: number, max: number): number { return min + Math.round(Math.random() * (max - min)) } } export enum WalkState { Walk, Stop, }