Files
climb/assets/scripts/PlayerController.ts
2025-09-21 21:00:58 +08:00

123 lines
3.6 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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;
}
}
}