From 35cfabb66ba0f221091bfff04bf8a03923792c0b Mon Sep 17 00:00:00 2001 From: richarjiang Date: Sun, 21 Sep 2025 21:11:02 +0800 Subject: [PATCH] =?UTF-8?q?perf:=20=E9=99=90=E5=88=B6=E7=9B=B8=E6=9C=BA?= =?UTF-8?q?=E7=A7=BB=E5=8A=A8=E8=8C=83=E5=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- assets/scripts/CameraFollow.ts | 45 ++++++++++++++++++++++++++++-- assets/scripts/PlayerController.ts | 32 +++++++++++++++++++-- 2 files changed, 71 insertions(+), 6 deletions(-) diff --git a/assets/scripts/CameraFollow.ts b/assets/scripts/CameraFollow.ts index fd66858..b1e47a9 100644 --- a/assets/scripts/CameraFollow.ts +++ b/assets/scripts/CameraFollow.ts @@ -1,4 +1,4 @@ -import { _decorator, Component, Node, Vec3, Camera } from 'cc'; +import { _decorator, Component, Node, Vec3, Camera, view } from 'cc'; const { ccclass, property } = _decorator; @ccclass('CameraFollow') @@ -16,6 +16,12 @@ export class CameraFollow extends Component { @property({ range: [0, 1] }) smoothness: number = 0.1; // 平滑度,0为瞬间跟随,1为最慢跟随 + @property + mapWidth: number = 1080; // 地图宽度 + + @property + mapHeight: number = 2560; // 地图高度 + private camera: Camera | null = null; onLoad() { @@ -42,6 +48,9 @@ export class CameraFollow extends Component { const targetPosition = this.target.position.clone(); targetPosition.add(this.offset); + // 应用地图边界限制 + const clampedPosition = this.clampCameraPosition(targetPosition); + // 使用插值实现平滑跟随 const currentPosition = this.node.position; const newPosition = new Vec3(); @@ -49,10 +58,39 @@ export class CameraFollow extends Component { // 根据平滑度设置插值速度 const lerpFactor = Math.min(1.0, this.followSpeed * deltaTime * (1 - this.smoothness + 0.1)); - Vec3.lerp(newPosition, currentPosition, targetPosition, lerpFactor); + Vec3.lerp(newPosition, currentPosition, clampedPosition, lerpFactor); this.node.position = newPosition; } + // 限制相机位置在地图边界内 + private clampCameraPosition(position: Vec3): Vec3 { + if (!this.camera) return position; + + // 获取屏幕可见区域大小 + const visibleSize = view.getVisibleSize(); + + // 计算相机能看到的世界区域的一半 + const halfCameraWidth = visibleSize.width * 0.5; + const halfCameraHeight = visibleSize.height * 0.5; + + // 计算地图边界(地图锚点为0.5,0.5,所以范围是-mapWidth/2到+mapWidth/2) + const mapHalfWidth = this.mapWidth * 0.5; + const mapHalfHeight = this.mapHeight * 0.5; + + // 计算相机位置的边界(确保相机边缘不超出地图边界) + const minX = -mapHalfWidth + halfCameraWidth; + const maxX = mapHalfWidth - halfCameraWidth; + const minY = -mapHalfHeight + halfCameraHeight; + const maxY = mapHalfHeight - halfCameraHeight; + + // 限制相机位置 + const clampedPosition = position.clone(); + clampedPosition.x = Math.max(minX, Math.min(maxX, position.x)); + clampedPosition.y = Math.max(minY, Math.min(maxY, position.y)); + + return clampedPosition; + } + // 设置跟随目标 setTarget(target: Node) { this.target = target; @@ -74,6 +112,7 @@ export class CameraFollow extends Component { const targetPosition = this.target.position.clone(); targetPosition.add(this.offset); - this.node.position = targetPosition; + const clampedPosition = this.clampCameraPosition(targetPosition); + this.node.position = clampedPosition; } } \ No newline at end of file diff --git a/assets/scripts/PlayerController.ts b/assets/scripts/PlayerController.ts index 6b2fa76..582be79 100644 --- a/assets/scripts/PlayerController.ts +++ b/assets/scripts/PlayerController.ts @@ -13,6 +13,12 @@ export class PlayerController extends Component { @property({ range: [1, 20] }) moveSpeed: number = 5; // 移动速度 + @property + mapWidth: number = 1080; // 地图宽度 + + @property + mapHeight: number = 2560; // 地图高度 + private isMoving: boolean = false; private targetPosition: Vec3 = new Vec3(); private originalPosition: Vec3 = new Vec3(); @@ -79,11 +85,28 @@ export class PlayerController extends Component { private moveToPosition(worldPos: Vec3) { if (!this.player) return; + // 限制目标位置在地图边界内 + const clampedPos = this.clampPlayerPosition(worldPos); + // 设置目标位置(保持Z轴不变) - this.targetPosition.set(worldPos.x, worldPos.y, this.player.position.z); + this.targetPosition.set(clampedPos.x, clampedPos.y, this.player.position.z); this.isMoving = true; - console.log(`移动目标: (${worldPos.x.toFixed(2)}, ${worldPos.y.toFixed(2)})`); + console.log(`移动目标: (${clampedPos.x.toFixed(2)}, ${clampedPos.y.toFixed(2)})`); + } + + // 限制玩家位置在地图边界内 + private clampPlayerPosition(position: Vec3): Vec3 { + // 计算地图边界(地图锚点为0.5,0.5,所以范围是-mapWidth/2到+mapWidth/2) + const mapHalfWidth = this.mapWidth * 0.5; + const mapHalfHeight = this.mapHeight * 0.5; + + // 限制玩家位置 + const clampedPosition = position.clone(); + clampedPosition.x = Math.max(-mapHalfWidth, Math.min(mapHalfWidth, position.x)); + clampedPosition.y = Math.max(-mapHalfHeight, Math.min(mapHalfHeight, position.y)); + + return clampedPosition; } update(deltaTime: number) { @@ -117,7 +140,10 @@ export class PlayerController extends Component { // 正常移动 const newPosition = new Vec3(); Vec3.scaleAndAdd(newPosition, currentPos, direction, moveDistance); - this.player.position = newPosition; + + // 确保新位置在地图边界内 + const clampedNewPosition = this.clampPlayerPosition(newPosition); + this.player.position = clampedNewPosition; } } } \ No newline at end of file