diff --git a/js/world.js b/js/world.js index 1d7acaf..0a7cb0c 100644 --- a/js/world.js +++ b/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); + } } } }