我智商爆棚
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

111 lines
3.8 KiB

4 weeks ago
import Common5 from "../../Platform/th/Common5";
const { ccclass, property } = cc._decorator;
export enum Axis {
PositiveX, // 正 X 轴
PositiveY, // 正 Y 轴
NegativeX, // 负 X 轴
NegativeY, // 负 Y 轴
}
@ccclass
export default class FMRunCircle extends cc.Component {
@property({ type: cc.Node, tooltip: '围绕旋转的目标' })
public target: cc.Node = null;
@property({ tooltip: '顺时针旋转' })
public clockwise: boolean = true;
@property({ tooltip: '旋转一圈花费的时间' })
public timePerRound: number = 10;
@property({ tooltip: '是否始终面向目标节点' })
public faceToTarget: boolean = false;
@property({
type: cc.Enum(Axis),
tooltip: '面向目标节点的轴:\n- PositiveX:正 X 轴\n- PositiveY:正 Y 轴\n- NegativeX:负 X 轴\n- NegativeY:负 Y 轴',
visible() { return this.faceToTarget }
})
public faceAxis: Axis = Axis.NegativeY;
@property({ tooltip: '自动开始旋转' })
public autoStart: boolean = false;
public angle: number = 0; // 角度
public radius: number = 0; // 半径
private isRotating: boolean = false; // 标志位,是否正在旋转
start() {
if (this.autoStart) this.run();
}
/**
*
* @param target
* @param clockwise
* @param timePerRound
* @param faceToTarget
* @param faceAxis
*/
public run(target?: cc.Node, clockwise?: boolean, timePerRound?: number, faceToTarget?: boolean, faceAxis?: Axis) {
if (target) this.target = target;
if (clockwise) this.clockwise = clockwise;
if (timePerRound) this.timePerRound = timePerRound;
if (faceToTarget) this.faceToTarget = faceToTarget;
if (faceAxis) this.faceAxis = faceAxis;
if (!this.target) {
cc.log('No target!');
return;
}
// 计算初始角度和半径
this.angle = this.getAngle(this.target.getPosition(), this.node.getPosition());
this.radius = Common5.makeDistance(this.target.getPosition(), this.node.getPosition());
// 开始
this.isRotating = true;
}
/**
*
* @param p1 1
* @param p2 2
*/
private getAngle(p1: cc.Vec2, p2: cc.Vec2): number {
return Math.atan(p2.y - p1.y / p2.x - p1.x);
}
update(dt: number) {
if (!this.isRotating || !this.target) return;
// 将角度转换为弧度
let radian = Math.PI / 180 * this.angle;
// 更新节点的位置
this.node.x = this.target.x + this.radius * Math.cos(radian);
this.node.y = this.target.y + this.radius * Math.sin(radian);
// 更新节点的角度
if (this.faceToTarget) {
switch (this.faceAxis) {
case Axis.PositiveX:
this.node.angle = this.angle + 180;
break;
case Axis.PositiveY:
this.node.angle = this.angle + 90;
break;
case Axis.NegativeX:
this.node.angle = this.angle;
break;
case Axis.NegativeY:
this.node.angle = this.angle - 90;
break;
}
}
// 计算下一帧的角度
let anglePerFrame = dt * (360 / this.timePerRound);
if (this.clockwise) this.angle -= anglePerFrame;
else this.angle += anglePerFrame;
// 重置角度,避免数值过大
if (this.angle >= 360) this.angle %= 360;
else if (this.angle <= -360) this.angle %= -360;
}
public stop() {
this.isRotating = false;
}
}