perf: 限制相机移动范围

This commit is contained in:
2025-09-21 21:11:02 +08:00
parent 85d1b54389
commit 35cfabb66b
2 changed files with 71 additions and 6 deletions

View File

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