feat
This commit is contained in:
123
assets/scripts/PlayerController.ts
Normal file
123
assets/scripts/PlayerController.ts
Normal file
@@ -0,0 +1,123 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user