| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169 |
- 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<Node> = [];
- @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,
- }
|