squidGame/tgx-games-client/assets/module_arean/scripts/common/CameraOrbit.ts

118 lines
4.1 KiB
TypeScript
Raw Normal View History

2025-02-10 11:08:10 +08:00
// CameraOrbit.ts
2025-02-21 10:45:46 +08:00
import { _decorator, Component, Node, Vec3, EventTouch, input, Input, tween, Tween } from 'cc';
2025-02-10 11:08:10 +08:00
const { ccclass, property } = _decorator;
@ccclass('CameraOrbit')
export class CameraOrbit extends Component {
2025-02-21 10:45:46 +08:00
private lastTouchX: number = 0;
private readonly rotationSpeed: number = 0.6; // 旋转速度系数,可以根据需要调整
private autoRotateTween: Tween<Node> | null = null;
private isTouching: boolean = false;
private currentAngle: number = 0;
private centerPoint: Vec3 = new Vec3();
private radius: number = 0; // 移除 @property改为自动计算
private initialHeight: number = 0;
2025-02-10 11:08:10 +08:00
start() {
2025-02-21 10:45:46 +08:00
if (!this.node) return; // 添加节点检查
// 保存中心点Y轴位置设置为负值使摄像机向下倾斜
this.centerPoint.set(0, -5, 0);
this.initialHeight = this.node.position.y;
// 计算半径(根据初始位置到中心点的水平距离)
const initialPos = this.node.position;
this.radius = Math.sqrt(
initialPos.x * initialPos.x +
initialPos.z * initialPos.z
);
// 计算初始角度
this.currentAngle = Math.atan2(initialPos.x, initialPos.z) * 180 / Math.PI;
this.updateCameraPosition();
this.startAutoRotate();
}
private startAutoRotate() {
// 创建一个对象来存储和更新角度
const tweenTarget = { angle: this.currentAngle };
this.autoRotateTween = tween(tweenTarget)
2025-02-10 11:08:10 +08:00
.repeatForever(
tween()
2025-02-21 10:45:46 +08:00
.to(360, {
angle: 360
}, {
onUpdate: () => {
this.currentAngle = tweenTarget.angle;
this.updateCameraPosition();
}
})
2025-02-10 11:08:10 +08:00
)
.start();
}
2025-02-21 10:45:46 +08:00
private updateCameraPosition() {
if (!this.node) return; // 添加节点检查
const angleInRadians = this.currentAngle * Math.PI / 180;
const x = Math.sin(angleInRadians) * this.radius;
const z = Math.cos(angleInRadians) * this.radius;
this.node.setPosition(new Vec3(x, this.initialHeight, z));
this.node.lookAt(this.centerPoint);
// 移除180度偏移让摄像机朝向中心
this.node.setRotationFromEuler(0, this.currentAngle, 0);
}
onEnable() {
// 注册触摸事件
input.on(Input.EventType.TOUCH_START, this.onTouchStart, this);
input.on(Input.EventType.TOUCH_MOVE, this.onTouchMove, this);
input.on(Input.EventType.TOUCH_END, this.onTouchEnd, this);
input.on(Input.EventType.TOUCH_CANCEL, this.onTouchEnd, this);
}
onDisable() {
// 移除触摸事件监听
input.off(Input.EventType.TOUCH_START, this.onTouchStart, this);
input.off(Input.EventType.TOUCH_MOVE, this.onTouchMove, this);
input.off(Input.EventType.TOUCH_END, this.onTouchEnd, this);
input.off(Input.EventType.TOUCH_CANCEL, this.onTouchEnd, this);
}
private onTouchStart(event: EventTouch) {
this.isTouching = true;
this.lastTouchX = event.getLocationX();
// 暂停自动旋转
if (this.autoRotateTween) {
this.autoRotateTween.stop();
}
}
private onTouchMove(event: EventTouch) {
if (!this.isTouching) return;
// 计算触摸移动距离
const currentTouchX = event.getLocationX();
const deltaX = currentTouchX - this.lastTouchX;
// 更新角度
this.currentAngle -= deltaX * this.rotationSpeed;
// 确保角度在0-360范围内
this.currentAngle = (this.currentAngle + 360) % 360;
// 更新相机位置和朝向
this.updateCameraPosition();
// 更新上一次触摸位置
this.lastTouchX = currentTouchX;
}
private onTouchEnd() {
this.isTouching = false;
// 恢复自动旋转
this.startAutoRotate();
}
2025-02-10 11:08:10 +08:00
}