123 lines
3.6 KiB
TypeScript
123 lines
3.6 KiB
TypeScript
import { _decorator, Component, Node, Vec3, input, Input, EventTouch, Camera, view } from 'cc';
|
||
const { ccclass, property } = _decorator;
|
||
|
||
@ccclass('PlayerController')
|
||
export class PlayerController extends Component {
|
||
|
||
@property(Node)
|
||
player: Node | null = null; // 玩家节点
|
||
|
||
@property(Camera)
|
||
camera: Camera | null = null; // 主摄像机
|
||
|
||
@property({ range: [1, 20] })
|
||
moveSpeed: number = 5; // 移动速度
|
||
|
||
private isMoving: boolean = false;
|
||
private targetPosition: Vec3 = new Vec3();
|
||
private originalPosition: Vec3 = new Vec3();
|
||
|
||
onLoad() {
|
||
// 注册触摸事件
|
||
input.on(Input.EventType.TOUCH_START, this.onTouchStart, this);
|
||
}
|
||
|
||
onDestroy() {
|
||
// 移除触摸事件
|
||
input.off(Input.EventType.TOUCH_START, this.onTouchStart, this);
|
||
}
|
||
|
||
start() {
|
||
if (this.player) {
|
||
this.originalPosition.set(this.player.position);
|
||
}
|
||
}
|
||
|
||
private onTouchStart(event: EventTouch) {
|
||
if (!this.player || !this.camera) return;
|
||
|
||
// 获取触摸点的UI坐标
|
||
const touchLocation = event.getUILocation();
|
||
|
||
// 将UI坐标转换为世界坐标
|
||
const worldPos = this.screenToWorldPoint(touchLocation);
|
||
|
||
console.log(`触摸UI坐标: (${touchLocation.x}, ${touchLocation.y})`);
|
||
console.log(`转换后世界坐标: (${worldPos.x.toFixed(2)}, ${worldPos.y.toFixed(2)})`);
|
||
|
||
this.moveToPosition(worldPos);
|
||
}
|
||
|
||
private screenToWorldPoint(screenPos: { x: number, y: number }): Vec3 {
|
||
if (!this.camera) {
|
||
console.error('Camera未设置,无法进行坐标转换');
|
||
return new Vec3(screenPos.x, screenPos.y, 0);
|
||
}
|
||
|
||
// 获取可见区域大小
|
||
const visibleSize = view.getVisibleSize();
|
||
|
||
// 计算屏幕中心点
|
||
const centerX = visibleSize.width * 0.5;
|
||
const centerY = visibleSize.height * 0.5;
|
||
|
||
// 将屏幕坐标转换为以屏幕中心为原点的坐标
|
||
const normalizedX = screenPos.x - centerX;
|
||
const normalizedY = screenPos.y - centerY;
|
||
|
||
// 考虑相机的位置偏移
|
||
const cameraPos = this.camera.node.position;
|
||
|
||
// 计算世界坐标
|
||
const worldX = normalizedX + cameraPos.x;
|
||
const worldY = normalizedY + cameraPos.y;
|
||
|
||
return new Vec3(worldX, worldY, 0);
|
||
}
|
||
|
||
|
||
private moveToPosition(worldPos: Vec3) {
|
||
if (!this.player) return;
|
||
|
||
// 设置目标位置(保持Z轴不变)
|
||
this.targetPosition.set(worldPos.x, worldPos.y, this.player.position.z);
|
||
this.isMoving = true;
|
||
|
||
console.log(`移动目标: (${worldPos.x.toFixed(2)}, ${worldPos.y.toFixed(2)})`);
|
||
}
|
||
|
||
update(deltaTime: number) {
|
||
if (!this.isMoving || !this.player) return;
|
||
|
||
const currentPos = this.player.position;
|
||
const distance = Vec3.distance(currentPos, this.targetPosition);
|
||
|
||
// 如果距离很小,直接到达目标位置
|
||
if (distance < 0.1) {
|
||
this.player.position = this.targetPosition.clone();
|
||
this.isMoving = false;
|
||
console.log('到达目标位置');
|
||
return;
|
||
}
|
||
|
||
// 计算移动方向
|
||
const direction = new Vec3();
|
||
Vec3.subtract(direction, this.targetPosition, currentPos);
|
||
direction.normalize();
|
||
|
||
// 计算这一帧应该移动的距离
|
||
const moveDistance = this.moveSpeed * deltaTime * 100; // 增加移动速度倍数
|
||
|
||
// 如果剩余距离小于这一帧要移动的距离,直接到达目标
|
||
if (distance <= moveDistance) {
|
||
this.player.position = this.targetPosition.clone();
|
||
this.isMoving = false;
|
||
console.log('到达目标位置');
|
||
} else {
|
||
// 正常移动
|
||
const newPosition = new Vec3();
|
||
Vec3.scaleAndAdd(newPosition, currentPos, direction, moveDistance);
|
||
this.player.position = newPosition;
|
||
}
|
||
}
|
||
} |