const { ccclass, property } = cc._decorator; @ccclass export default class CirculateTweenAnimation extends cc.Component { @property(cc.Node) circulateNode: cc.Node = null; @property(cc.Vec3) startPoint: cc.Vec3 = null; @property(cc.Vec3) endPoint: cc.Vec3 = null; @property() speed: number = 10; directionVector: cc.Vec3 = null; isCirculate: boolean = true; protected onEnable(): void { if (!this.circulateNode) { this.circulateNode = this.node; } this.directionVector = this.endPoint.sub(this.startPoint).normalize(); this.circulateNode.setPosition(this.startPoint); this.node.attr({ setSpeed: (speed: number) => { this.speed = speed; if (speed == 0) { this.isCirculate = false; } } }); } update(dt) { if (this.isCirculate) { let pos = this.circulateNode.position.add(this.directionVector.mul(this.speed).mul(dt)); this.circulateNode.setPosition(pos); if (this.determine(this.startPoint, this.endPoint, this.circulateNode.position)) { this.circulateNode.setPosition(this.startPoint); } } } determine(startPoint: cc.Vec3, endPoint: cc.Vec3, curPoint: cc.Vec3) { if (startPoint.y == endPoint.y) { let direction = (endPoint.x >= startPoint.x) ? 1 : 2; let isGreater = (curPoint.x >= endPoint.x) ? 1 : 2; return direction == isGreater; } else { let direction = (endPoint.y >= startPoint.y) ? 1 : 2; let isGreater = (curPoint.y >= endPoint.y) ? 1 : 2; return direction == isGreater; } } }