UNPKG

@woosh/meep-engine

Version:

Pure JavaScript game engine. Fully featured and production ready.

127 lines (93 loc) 3.52 kB
import TopDownCameraControllerSystem from "../../../graphics/ecs/camera/topdown/TopDownCameraControllerSystem.js"; import { Camera } from "../../../graphics/ecs/camera/Camera.js"; import { obtainTerrain } from "./obtainTerrain.js"; import { assert } from "../../../../core/assert.js"; import TerrainSystem from "../ecs/TerrainSystem.js"; import Task from "../../../../core/process/task/Task.js"; import { TaskSignal } from "../../../../core/process/task/TaskSignal.js"; import { max2 } from "../../../../core/math/max2.js"; import { clamp01 } from "../../../../core/math/clamp01.js"; /** * * @param {EntityManager} em * @param {EntityComponentDataset} ecd * @param {number} [timeout] in seconds * @returns {Task} */ export function loadVisibleTerrainTiles({ em, ecd, timeout = 10 }) { let totalTiles = 0; let loadedTiles = 0; let failedTiles = 0; let attempt = 0; let failureFlag = false; const timeout_milliseconds = timeout * 1000; let start_time = 0; function init() { start_time = Date.now(); const attemptId = attempt; //force update by camera controller, to ensure correct focus is set em.getSystem(TopDownCameraControllerSystem).update(0); ecd.traverseComponents(Camera, function (c) { c.updateMatrices(); }); const tiles = []; const terrain = obtainTerrain(ecd); assert.notEqual(terrain, null, 'terrain not found'); TerrainSystem.traverseVisibleTiles(ecd, terrain, function (tile) { tiles.push(tile); }); totalTiles = tiles.length; const tileManager = terrain.__tiles; function handleObtainedTile(t) { if (attemptId !== attempt) { return; } loadedTiles++; } function handleFailedTile(t) { if (attemptId !== attempt) { return; } attempt++; failedTiles++; if (attempt < 10) { init(); } else { failureFlag = true; } } if (totalTiles !== 0) { tiles.forEach(function (tile) { tileManager.obtain(tile.gridPosition.x, tile.gridPosition.y).then(handleObtainedTile, handleFailedTile); }); } } const task = new Task({ name: "Building visible terrain tiles", initializer: init, cycleFunction() { if (Date.now() > start_time + timeout_milliseconds) { // timed out return TaskSignal.EndFailure; } if (failureFlag) { return TaskSignal.EndFailure; } if (loadedTiles >= totalTiles) { return TaskSignal.EndSuccess; } else { return TaskSignal.Yield; } }, computeProgress() { const loaded_fraction = totalTiles === 0 ? 0 : loadedTiles / totalTiles; const timeout_fraction = (Date.now() - start_time) / timeout_milliseconds; return clamp01(max2(loaded_fraction, timeout_fraction)); } }); return task; }