perf: 限制相机移动范围
This commit is contained in:
@@ -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;
|
const { ccclass, property } = _decorator;
|
||||||
|
|
||||||
@ccclass('CameraFollow')
|
@ccclass('CameraFollow')
|
||||||
@@ -16,6 +16,12 @@ export class CameraFollow extends Component {
|
|||||||
@property({ range: [0, 1] })
|
@property({ range: [0, 1] })
|
||||||
smoothness: number = 0.1; // 平滑度,0为瞬间跟随,1为最慢跟随
|
smoothness: number = 0.1; // 平滑度,0为瞬间跟随,1为最慢跟随
|
||||||
|
|
||||||
|
@property
|
||||||
|
mapWidth: number = 1080; // 地图宽度
|
||||||
|
|
||||||
|
@property
|
||||||
|
mapHeight: number = 2560; // 地图高度
|
||||||
|
|
||||||
private camera: Camera | null = null;
|
private camera: Camera | null = null;
|
||||||
|
|
||||||
onLoad() {
|
onLoad() {
|
||||||
@@ -42,6 +48,9 @@ export class CameraFollow extends Component {
|
|||||||
const targetPosition = this.target.position.clone();
|
const targetPosition = this.target.position.clone();
|
||||||
targetPosition.add(this.offset);
|
targetPosition.add(this.offset);
|
||||||
|
|
||||||
|
// 应用地图边界限制
|
||||||
|
const clampedPosition = this.clampCameraPosition(targetPosition);
|
||||||
|
|
||||||
// 使用插值实现平滑跟随
|
// 使用插值实现平滑跟随
|
||||||
const currentPosition = this.node.position;
|
const currentPosition = this.node.position;
|
||||||
const newPosition = new Vec3();
|
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));
|
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;
|
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) {
|
setTarget(target: Node) {
|
||||||
this.target = target;
|
this.target = target;
|
||||||
@@ -74,6 +112,7 @@ export class CameraFollow extends Component {
|
|||||||
|
|
||||||
const targetPosition = this.target.position.clone();
|
const targetPosition = this.target.position.clone();
|
||||||
targetPosition.add(this.offset);
|
targetPosition.add(this.offset);
|
||||||
this.node.position = targetPosition;
|
const clampedPosition = this.clampCameraPosition(targetPosition);
|
||||||
|
this.node.position = clampedPosition;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -13,6 +13,12 @@ export class PlayerController extends Component {
|
|||||||
@property({ range: [1, 20] })
|
@property({ range: [1, 20] })
|
||||||
moveSpeed: number = 5; // 移动速度
|
moveSpeed: number = 5; // 移动速度
|
||||||
|
|
||||||
|
@property
|
||||||
|
mapWidth: number = 1080; // 地图宽度
|
||||||
|
|
||||||
|
@property
|
||||||
|
mapHeight: number = 2560; // 地图高度
|
||||||
|
|
||||||
private isMoving: boolean = false;
|
private isMoving: boolean = false;
|
||||||
private targetPosition: Vec3 = new Vec3();
|
private targetPosition: Vec3 = new Vec3();
|
||||||
private originalPosition: Vec3 = new Vec3();
|
private originalPosition: Vec3 = new Vec3();
|
||||||
@@ -79,11 +85,28 @@ export class PlayerController extends Component {
|
|||||||
private moveToPosition(worldPos: Vec3) {
|
private moveToPosition(worldPos: Vec3) {
|
||||||
if (!this.player) return;
|
if (!this.player) return;
|
||||||
|
|
||||||
|
// 限制目标位置在地图边界内
|
||||||
|
const clampedPos = this.clampPlayerPosition(worldPos);
|
||||||
|
|
||||||
// 设置目标位置(保持Z轴不变)
|
// 设置目标位置(保持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;
|
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) {
|
update(deltaTime: number) {
|
||||||
@@ -117,7 +140,10 @@ export class PlayerController extends Component {
|
|||||||
// 正常移动
|
// 正常移动
|
||||||
const newPosition = new Vec3();
|
const newPosition = new Vec3();
|
||||||
Vec3.scaleAndAdd(newPosition, currentPos, direction, moveDistance);
|
Vec3.scaleAndAdd(newPosition, currentPos, direction, moveDistance);
|
||||||
this.player.position = newPosition;
|
|
||||||
|
// 确保新位置在地图边界内
|
||||||
|
const clampedNewPosition = this.clampPlayerPosition(newPosition);
|
||||||
|
this.player.position = clampedNewPosition;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user