perf: Optimize chunk rendering and generation by skipping off-screen chunks
This commit is contained in:
parent
c7735b8578
commit
4c96226d05
66
js/world.js
66
js/world.js
@ -454,15 +454,35 @@ function moveMetadata(fromX, fromY, toX, toY) {
|
||||
function getVisibleChunks() {
|
||||
const visibleChunks = [];
|
||||
|
||||
// Calculate visible chunk range
|
||||
// Calculate visible chunk range (chunks that might be visible on screen)
|
||||
const startChunkX = Math.floor(worldOffsetX / CHUNK_SIZE) - 1;
|
||||
const endChunkX = Math.ceil((worldOffsetX + canvas.width / PIXEL_SIZE) / CHUNK_SIZE) + 1;
|
||||
const startChunkY = Math.floor(worldOffsetY / CHUNK_SIZE) - 1;
|
||||
const endChunkY = Math.ceil((worldOffsetY + canvas.height / PIXEL_SIZE) / CHUNK_SIZE) + 1;
|
||||
|
||||
// Calculate the exact visible area in world coordinates
|
||||
const visibleStartX = worldOffsetX;
|
||||
const visibleEndX = worldOffsetX + canvas.width / PIXEL_SIZE;
|
||||
const visibleStartY = worldOffsetY;
|
||||
const visibleEndY = worldOffsetY + canvas.height / PIXEL_SIZE;
|
||||
|
||||
for (let chunkY = startChunkY; chunkY < endChunkY; chunkY++) {
|
||||
for (let chunkX = startChunkX; chunkX < endChunkX; chunkX++) {
|
||||
visibleChunks.push({ chunkX, chunkY });
|
||||
// Calculate chunk boundaries in world coordinates
|
||||
const chunkWorldStartX = chunkX * CHUNK_SIZE;
|
||||
const chunkWorldEndX = (chunkX + 1) * CHUNK_SIZE;
|
||||
const chunkWorldStartY = chunkY * CHUNK_SIZE;
|
||||
const chunkWorldEndY = (chunkY + 1) * CHUNK_SIZE;
|
||||
|
||||
// Check if this chunk is actually visible in the viewport
|
||||
const isVisible = !(
|
||||
chunkWorldEndX < visibleStartX ||
|
||||
chunkWorldStartX > visibleEndX ||
|
||||
chunkWorldEndY < visibleStartY ||
|
||||
chunkWorldStartY > visibleEndY
|
||||
);
|
||||
|
||||
visibleChunks.push({ chunkX, chunkY, isVisible });
|
||||
}
|
||||
}
|
||||
|
||||
@ -474,19 +494,53 @@ function generateChunksAroundPlayer() {
|
||||
const centerChunkY = Math.floor(worldOffsetY / CHUNK_SIZE);
|
||||
const radius = 3; // Generate chunks within 3 chunks of the player
|
||||
|
||||
// Always generate the stone layer at y = 1
|
||||
// Get visible chunks to prioritize their generation
|
||||
const visibleChunks = getVisibleChunks();
|
||||
const visibleChunkKeys = new Set(visibleChunks.map(chunk => getChunkKey(chunk.chunkX, chunk.chunkY)));
|
||||
|
||||
// Always generate the stone layer at y = 1 for visible chunks first
|
||||
for (let dx = -radius; dx <= radius; dx++) {
|
||||
const chunkX = centerChunkX + dx;
|
||||
const chunkY = 1; // The chunk at y = 1 (moved from y = -1)
|
||||
getOrCreateChunk(chunkX, chunkY);
|
||||
const key = getChunkKey(chunkX, chunkY);
|
||||
|
||||
// Prioritize visible chunks
|
||||
if (visibleChunkKeys.has(key)) {
|
||||
getOrCreateChunk(chunkX, chunkY);
|
||||
}
|
||||
}
|
||||
|
||||
// Generate chunks in a square around the player
|
||||
// Generate visible chunks first
|
||||
for (const { chunkX, chunkY, isVisible } of visibleChunks) {
|
||||
if (isVisible) {
|
||||
getOrCreateChunk(chunkX, chunkY);
|
||||
}
|
||||
}
|
||||
|
||||
// Then generate non-visible chunks within the radius (with lower priority)
|
||||
// Always generate the stone layer at y = 1 for remaining chunks
|
||||
for (let dx = -radius; dx <= radius; dx++) {
|
||||
const chunkX = centerChunkX + dx;
|
||||
const chunkY = 1;
|
||||
const key = getChunkKey(chunkX, chunkY);
|
||||
|
||||
// Skip if already generated
|
||||
if (!visibleChunkKeys.has(key)) {
|
||||
getOrCreateChunk(chunkX, chunkY);
|
||||
}
|
||||
}
|
||||
|
||||
// Generate remaining chunks in a square around the player
|
||||
for (let dy = -radius; dy <= radius; dy++) {
|
||||
for (let dx = -radius; dx <= radius; dx++) {
|
||||
const chunkX = centerChunkX + dx;
|
||||
const chunkY = centerChunkY + dy;
|
||||
getOrCreateChunk(chunkX, chunkY);
|
||||
const key = getChunkKey(chunkX, chunkY);
|
||||
|
||||
// Skip if already generated
|
||||
if (!visibleChunkKeys.has(key)) {
|
||||
getOrCreateChunk(chunkX, chunkY);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user