import { TILE, SEA_GY } from '../core/constants.js'; import { state } from '../core/state.js'; import { grid, blocks, k, isSolid } from './world-storage.js'; // Физика жидкости const waterUpdateQueue = new Set(); let waterUpdateTimer = 0; const WATER_UPDATE_INTERVAL = 0.05; // Обновляем воду каждые 0.05 секунды function updateWaterPhysics(dt) { waterUpdateTimer += dt; if (waterUpdateTimer < WATER_UPDATE_INTERVAL) return; waterUpdateTimer = 0; // Ограничиваем количество водных блоков для обработки (оптимизация) const MAX_WATER_BLOCKS_PER_UPDATE = 50; let processedCount = 0; // Собираем только видимые водные блоки в очередь (оптимизация) waterUpdateQueue.clear(); const W = state.W; const H = state.H; const minGX = Math.floor(state.camX / TILE) - 10; const maxGX = Math.floor((state.camX + W) / TILE) + 10; const minGY = Math.floor(state.camY / TILE) - 10; const maxGY = Math.floor((state.camY + H) / TILE) + 10; for (const b of blocks) { if (processedCount >= MAX_WATER_BLOCKS_PER_UPDATE) break; if (!b.dead && b.t === 'water' && b.gx >= minGX && b.gx <= maxGX && b.gy >= minGY && b.gy <= maxGY) { waterUpdateQueue.add(k(b.gx, b.gy)); processedCount++; } } // Обновляем воду с ограничением глубины распространения const processed = new Set(); const toAdd = []; const MAX_WATER_DEPTH = 20; // Максимальная глубина распространения воды for (const key of waterUpdateQueue) { if (processed.has(key)) continue; const b = grid.get(key); if (!b || b.dead) continue; processed.add(key); const gx = b.gx; const gy = b.gy; // Проверяем глубину - не распространяем воду слишком глубоко if (gy > SEA_GY + MAX_WATER_DEPTH) continue; // Проверяем, можно ли воде упасть вниз const belowKey = k(gx, gy + 1); const below = grid.get(belowKey); // Внизу пусто - вода создаёт новый блок внизу (но не удаляется сверху) if (!below || below.dead) { // Ограничиваем создание новых водных блоков if (toAdd.length < 20) { // Максимум 20 новых блоков за обновление toAdd.push({ gx, gy: gy + 1, t: 'water' }); processed.add(belowKey); } continue; } // Если внизу не вода и не твёрдый блок - вода может течь вниз if (!isSolid(gx, gy + 1) && below && below.t !== 'water') { if (toAdd.length < 20) { toAdd.push({ gx, gy: gy + 1, t: 'water' }); processed.add(belowKey); } continue; } // Если внизу твёрдый блок или вода - вода растекается горизонтально // Проверяем левую сторону const leftKey = k(gx - 1, gy); const left = grid.get(leftKey); if (!left || left.dead) { if (toAdd.length < 20) { toAdd.push({ gx: gx - 1, gy, t: 'water' }); processed.add(leftKey); } continue; } // Проверяем правую сторону const rightKey = k(gx + 1, gy); const right = grid.get(rightKey); if (!right || right.dead) { if (toAdd.length < 20) { toAdd.push({ gx: gx + 1, gy, t: 'water' }); processed.add(rightKey); } continue; } } // Применяем изменения (только добавляем новые блоки) for (const newData of toAdd) { const key = k(newData.gx, newData.gy); if (!grid.has(key)) { const b = { gx: newData.gx, gy: newData.gy, t: newData.t, dead: false, active: false, fuse: 0 }; grid.set(key, b); blocks.push(b); } } // Очищаем мёртвые блоки из массива for (let i = blocks.length - 1; i >= 0; i--) { if (blocks[i].dead) { blocks.splice(i, 1); } } } export { updateWaterPhysics };