// World management functions let worldOffsetX = 0; let worldOffsetY = 0; let worldOffsetXBeforeDrag = 0; let worldOffsetYBeforeDrag = 0; let chunks = new Map(); // Map to store chunks with key "x,y" let metadata = new Map(); // Map to store metadata for pixels let generatedChunks = new Set(); // Set to track which chunks have been generated function moveWorld(dx, dy) { worldOffsetX += dx; worldOffsetY += dy; updateCoordinatesDisplay(); // Generate terrain for chunks around the current view generateChunksAroundPlayer(); } function updateCoordinatesDisplay() { const chunkX = Math.floor(worldOffsetX / CHUNK_SIZE); const chunkY = Math.floor(worldOffsetY / CHUNK_SIZE); document.getElementById('coords').textContent = `Chunk: ${chunkX},${chunkY} | Offset: ${Math.floor(worldOffsetX)},${Math.floor(worldOffsetY)}`; } function getChunkKey(chunkX, chunkY) { return `${chunkX},${chunkY}`; } function getOrCreateChunk(chunkX, chunkY) { const key = getChunkKey(chunkX, chunkY); if (!chunks.has(key)) { // Create a new chunk with empty pixels const chunkData = new Array(CHUNK_SIZE * CHUNK_SIZE).fill(EMPTY); // Add floor at the bottom of the world (y = 0 and y = 1) if (chunkY === 0 || chunkY === 1) { // Fill the bottom row with walls for (let x = 0; x < CHUNK_SIZE; x++) { chunkData[(CHUNK_SIZE - 1) * CHUNK_SIZE + x] = WALL; } } chunks.set(key, chunkData); } return chunks.get(key); } function getChunkCoordinates(worldX, worldY) { const chunkX = Math.floor(worldX / CHUNK_SIZE); const chunkY = Math.floor(worldY / CHUNK_SIZE); const localX = ((worldX % CHUNK_SIZE) + CHUNK_SIZE) % CHUNK_SIZE; const localY = ((worldY % CHUNK_SIZE) + CHUNK_SIZE) % CHUNK_SIZE; return { chunkX, chunkY, localX, localY }; } function setPixel(worldX, worldY, type) { const { chunkX, chunkY, localX, localY } = getChunkCoordinates(worldX, worldY); const chunk = getOrCreateChunk(chunkX, chunkY); const index = localY * CHUNK_SIZE + localX; chunk[index] = type; } function getPixel(worldX, worldY) { // Special case: floor at the bottom of the world (first two chunks) const floorChunkY = Math.floor(worldY / CHUNK_SIZE); if (worldY % CHUNK_SIZE === CHUNK_SIZE - 1 && (floorChunkY === 0 || floorChunkY === 1)) { return WALL; } const { chunkX, chunkY, localX, localY } = getChunkCoordinates(worldX, worldY); const key = getChunkKey(chunkX, chunkY); if (!chunks.has(key)) { return EMPTY; } const chunk = chunks.get(key); const index = localY * CHUNK_SIZE + localX; return chunk[index]; } // Metadata functions to store additional information about pixels function setMetadata(worldX, worldY, data) { const key = `${worldX},${worldY}`; metadata.set(key, data); } function getMetadata(worldX, worldY) { const key = `${worldX},${worldY}`; return metadata.get(key); } function removeMetadata(worldX, worldY) { const key = `${worldX},${worldY}`; metadata.delete(key); } // Move metadata when a pixel moves function moveMetadata(fromX, fromY, toX, toY) { const data = getMetadata(fromX, fromY); if (data) { setMetadata(toX, toY, data); removeMetadata(fromX, fromY); } } function getVisibleChunks() { const visibleChunks = []; // Calculate visible chunk range 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; for (let chunkY = startChunkY; chunkY < endChunkY; chunkY++) { for (let chunkX = startChunkX; chunkX < endChunkX; chunkX++) { visibleChunks.push({ chunkX, chunkY }); } } return visibleChunks; }