refactor: Optimize camera movement with chunk-aware smooth tracking

This commit is contained in:
Kacper Kostka (aider) 2025-04-05 18:15:32 +02:00
parent afba547fce
commit 0a13dfc0a3

View File

@ -173,15 +173,48 @@ class Player extends Entity {
} }
centerCamera() { centerCamera() {
// Calculate the target world offset to center on player // Get current camera center in world coordinates
const targetOffsetX = this.x - (canvas.width / PIXEL_SIZE / 2); const cameraWidth = canvas.width / PIXEL_SIZE;
const targetOffsetY = this.y - (canvas.height / PIXEL_SIZE / 2); const cameraHeight = canvas.height / PIXEL_SIZE;
const cameraCenterX = worldOffsetX + cameraWidth / 2;
const cameraCenterY = worldOffsetY + cameraHeight / 2;
// Smoothly move the camera to the target position (reduced smoothing factor) // Calculate distance from player to camera center
worldOffsetX += (targetOffsetX - worldOffsetX) * 0.05; const distanceX = Math.abs(this.x - cameraCenterX);
worldOffsetY += (targetOffsetY - worldOffsetY) * 0.05; const distanceY = Math.abs(this.y - cameraCenterY);
// Mark that the world has moved for rendering // Define thresholds for camera movement (percentage of screen size)
worldMoved = true; const thresholdX = cameraWidth * 0.3; // Move when player is 30% away from center
const thresholdY = cameraHeight * 0.3;
// Only move camera when player gets close to the edge of current view
let needsUpdate = false;
if (distanceX > thresholdX) {
// Calculate target position with chunk-based snapping
const chunkSize = CHUNK_SIZE;
const playerChunkX = Math.floor(this.x / chunkSize);
const targetX = this.x - (canvas.width / PIXEL_SIZE / 2);
// Smooth transition to the target position
worldOffsetX += (targetX - worldOffsetX) * 0.1;
needsUpdate = true;
}
if (distanceY > thresholdY) {
// Calculate target position with chunk-based snapping
const chunkSize = CHUNK_SIZE;
const playerChunkY = Math.floor(this.y / chunkSize);
const targetY = this.y - (canvas.height / PIXEL_SIZE / 2);
// Smooth transition to the target position
worldOffsetY += (targetY - worldOffsetY) * 0.1;
needsUpdate = true;
}
// Only mark world as moved if we actually updated the camera
if (needsUpdate) {
worldMoved = true;
}
} }
} }