UNPKG

@woosh/meep-engine

Version:

Pure JavaScript game engine. Fully featured and production ready.

218 lines (158 loc) • 7.23 kB
import { EngineHarness } from "../../src/engine/EngineHarness.js"; import RenderSystem from "../../src/engine/ecs/systems/RenderSystem.js"; import { Camera } from "../../src/engine/graphics/ecs/camera/Camera.js"; import TopDownCameraController from "../../src/engine/graphics/ecs/camera/topdown/TopDownCameraController.js"; import Vector3 from "../../src/core/geom/Vector3.js"; import { TopDownCameraLander } from "../../src/engine/graphics/ecs/camera/topdown/TopDownCameraLander.js"; import Terrain from "../../src/engine/ecs/terrain/ecs/Terrain.js"; import { TerrainFlags } from "../../src/engine/ecs/terrain/ecs/TerrainFlags.js"; import Water from "../../src/engine/graphics/ecs/water/Water.js"; import GridObstacle from "../../src/engine/grid/obstacle/GridObstacle.js"; import Entity from "../../src/engine/ecs/Entity.js"; import GridPosition from "../../src/engine/grid/position/GridPosition.js"; import { Transform } from "../../src/engine/ecs/transform/Transform.js"; import { GridData } from "../../src/generation/grid/GridData.js"; import { computeStringHash } from "../../src/core/primitives/strings/computeStringHash.js"; import { ThemeEngine } from "../../src/generation/theme/ThemeEngine.js"; import { AreaTheme } from "../../src/generation/theme/AreaTheme.js"; import TaskGroup from "../../src/core/process/task/TaskGroup.js"; import { generateTerrainPreview } from "../../../../generator/generator/generateTerrainPreview.js"; import { SampleTheme0 } from "./themes/SampleTheme0.js"; import { SampleGenerator0 } from "./SampleGenerator0.js"; import { configureMirGrid } from "./grid/configureMirGrid.js"; import { EngineConfiguration } from "../../src/engine/EngineConfiguration.js"; import TerrainSystem from "../../src/engine/ecs/terrain/ecs/TerrainSystem.js"; import WaterSystem from "../../src/engine/graphics/ecs/water/WaterSystem.js"; import { MeshSystem } from "../../src/engine/graphics/ecs/mesh/MeshSystem.js"; import TopDownCameraControllerSystem from "../../src/engine/graphics/ecs/camera/topdown/TopDownCameraControllerSystem.js"; import { TopDownCameraLanderSystem } from "../../src/engine/graphics/ecs/camera/topdown/TopDownCameraLanderSystem.js"; import LightSystem from "../../src/engine/graphics/ecs/light/LightSystem.js"; import { TaskLoadingScreen } from "../../src/view/task/TaskLoadingScreen.js"; import { actionTask } from "../../src/core/process/task/util/actionTask.js"; function makeEngineConfig(engine) { const config = new EngineConfiguration(); const graphics = engine.graphics; config.addSystem(new RenderSystem(graphics)); config.addSystem(new TerrainSystem(graphics, engine.assetManager)); config.addSystem(new WaterSystem(graphics)); config.addSystem(new MeshSystem(engine)); config.addSystem(new TopDownCameraControllerSystem()); config.addSystem(new TopDownCameraLanderSystem()); config.addSystem(new LightSystem(engine)) return config; } /** * * @param {EngineHarness} harness * @return {Promise<void>} */ async function init(harness) { const engine = harness.engine; await makeEngineConfig(engine).apply(engine); await harness.initialize(); main(engine); } function prepare_gen_task({ SIZE_X = 64, SIZE_Y = 64, ecd }) { const camera = EngineHarness.buildCamera({ engine, target: new Vector3(15, 0, 16), // pitch: -PI_HALF, pitch: 1.1, yaw: 3.14, distance: 13, ecd, distanceMin: 5, distanceMax: 30 }); camera.add(new TopDownCameraLander()); // build lights EngineHarness.buildLights({ engine }) // build terrain const terrain = new Terrain(); terrain.resolution = 4; terrain.size.set(SIZE_X, SIZE_Y); terrain.samplerHeight.resize(SIZE_X, SIZE_Y); terrain.splat.resize(SIZE_X * 4, SIZE_Y * 4, 0); terrain.layers.resolution.set(512, 512); terrain.clearFlag(TerrainFlags.Built); terrain.build(engine.assetManager); const water = new Water(); water.color.setRGB(0.2, 0.0, 0.5); water.shoreColor.setRGB(0.3, 0.3, 1); water.shoreDepthTransition.set(0.16, 0.5); water.waveFrequency.set(1.3); water.waveAmplitude.set(0.15); water.waveSpeed.set(1.2); water.scattering.set(1.2); water.level.set(-0.3); const obstacle = new GridObstacle(); obstacle.resize(terrain.size.x, terrain.size.y); const terrainBuilder = new Entity(); terrainBuilder .add(terrain) .add(water) .add(obstacle) .add(new GridPosition()) .add(new Transform()) .build(ecd); const gridData = new GridData(); configureMirGrid(gridData); gridData.resize(terrain.size.x, terrain.size.y); gridData.computeScale(1); const generator = SampleGenerator0; const tGenerationTask = generator.generate(ecd, gridData, computeStringHash('alexx855')); const themeEngine = new ThemeEngine(); themeEngine.assetManager = engine.assetManager; const theme0 = new AreaTheme(); const width = gridData.width; const height = gridData.height; theme0.mask.resize(width, height); theme0.mask.mask.fill(0, 0, width, height, [1]); theme0.theme = SampleTheme0; themeEngine.add(theme0); themeEngine.random.setCurrentSeed(1); const tTheme = themeEngine.apply(gridData, ecd); tTheme.addDependency(tGenerationTask); const tBuildLevel = new TaskGroup([tGenerationTask, tTheme]); const tAddGameplayElements = actionTask(() => { // prepare gameplay-specific things on top of the generated level //build minimap const terrainPreview = generateTerrainPreview(terrainBuilder.id, ecd); terrain.preview.copy(terrainPreview); }); tAddGameplayElements.addDependency(tBuildLevel); return new TaskGroup([tBuildLevel, tAddGameplayElements]); } /** * * @param {Engine} engine */ function main(engine) { const ecd = engine.entityManager.dataset; const tBuildLevel = prepare_gen_task({ ecd }); TaskLoadingScreen.load(engine, tBuildLevel); engine.executor.runGroup(tBuildLevel); tBuildLevel.promise().then(() => { console.log('Generation took ', tBuildLevel.getExecutedCpuTime(), 'ms'); const camera = ecd.getAnyComponent(Camera); EngineHarness.buildOrbitalCameraController({ cameraEntity: camera.entity, engine }); // tweak camera for prototyping const ctrl = ecd.getComponent(camera.entity, TopDownCameraController); if (ctrl !== undefined) { ctrl.distanceMax = 200; } }); // Resume audio context engine.devices.pointer.on.down.addOne(engine.sound.resumeContext, engine.sound); engine.devices.pointer.on.wheel.addOne(engine.sound.resumeContext, engine.sound); } const engineHarness = new EngineHarness(); init(engineHarness);