UNPKG

the-world-engine

Version:

three.js based, unity like game engine for browser

257 lines (244 loc) 8.99 kB
import { CoroutineProcessor } from "./coroutine/CoroutineProcessor"; import { EngineGlobalObject } from "./EngineGlobalObject"; import { GameState, GameStateKind } from "./GameState"; import { Scene } from "./hierarchy_object/Scene"; import { Physics2DProcessor } from "./physics/2d/Physics2DProcessor"; import { CameraContainer } from "./render/CameraContainer"; import { Color } from "./render/Color"; import { GameScreen } from "./render/GameScreen"; import { OptimizedCSS3DRenderer } from "./render/OptimizedCSS3DRenderer"; import { TransformMatrixProcessor } from "./render/TransformMatrixProcessor"; import { WebGLGlobalObject } from "./render/WebGLGlobalObject"; import { SceneProcessor } from "./SceneProcessor"; import { Time } from "./time/Time"; export class Game { S; C; R; K; D; O; i; _; p; v; P; G; g; L; l; j; T=null; F; A; M; B; W; constructor(e, t = true) { const i = document.createElement("div"); i.style.width = "100%"; i.style.height = "100%"; i.style.position = "relative"; e.appendChild(i); e = i; this.S = new Scene; this.C = new GameScreen(e.clientWidth, e.clientHeight); this.j = e; { this.i = new CameraContainer((e => { if (this.D) { const t = this.S.unsafeGetThreeScene(); if (e instanceof Color) { const i = this.K; i.r = e.r; i.g = e.g; i.b = e.b; t.background = i; } else { t.background = e; } } else if (this.R) { const t = this.R.domElement; if (e === null) { t.style.backgroundColor = "rgba(0, 0, 0, 0)"; } else if (e.isTexture) { console.warn("THREE.Texture background is not supported in CSS3DRenderer"); t.style.backgroundColor = "rgba(0, 0, 0, 0)"; } else { t.style.backgroundColor = "rgba(" + e.r * 255 + "," + e.g * 255 + "," + e.b * 255 + "," + e.a + ")"; } } })); } this._ = new Time; this.p = new GameState(GameStateKind.WaitingForStart); this.v = new SceneProcessor; this.P = new CoroutineProcessor(this._); this.G = new TransformMatrixProcessor; this.g = new Physics2DProcessor; this.L = new EngineGlobalObject(this.S, this.i, this._, this.p, this.C, this.v, this.P, this.G, this.g, e); this.F = null; this.A = false; this.M = t; this.B = this.resizeFramebuffer.bind(this); if (t) window.addEventListener("resize", this.B); this.W = this.q.bind(this); } resizeFramebuffer() { const e = this.j.clientWidth; const t = this.j.clientHeight; if (e === this.C.width && t === this.C.height) return; this.C.resize(e, t); if (this.R) { this.R.setSize(e, t); this.R.domElement.style.width = "100%"; this.R.domElement.style.height = "100%"; } if (this.D) { this.D.setSize(e, t); this.O.style.width = "100%"; this.O.style.height = "100%"; } } run(e, t) { if (this.A) throw new Error("Game is disposed."); if (this.p.kind !== GameStateKind.WaitingForStart) throw new Error("Game is already running."); this.p.kind = GameStateKind.Initializing; this._.start(); const i = new e(this.L, t); const s = i.run(); this.T = i.getGameSettingObject(); this.L.applyGameSetting(this.T); if (this.T.render.webGLRendererLoader) { if (this.T.render.webGLRendererInitilizer === undefined) { console.warn("webGLRendererLoader is specified, but webGLRenderer is not specified. so engine will not render as webgl."); } else { this.K = new this.T.render.webGLRendererLoader.Color; const e = this.T.render.webGLRendererInitilizer(); let t; let i; let s; if (e instanceof Array) { t = e[0]; i = e[1]; s = false; } else { t = e; i = e.domElement; s = true; } const r = this.j; this.O = i; this.D = t; this.D.setSize(r.clientWidth, r.clientHeight); this.O.style.position = "absolute"; r.appendChild(this.O); this.l = new WebGLGlobalObject(t, s ? t : null); this.L.setWebGLGlobalObject(this.l); } } else { if (this.T.render.webGLRendererInitilizer) { console.warn("webGLRenderer is specified, but webGLRendererLoader is not specified. so engine will not render as webgl."); } } if (this.T.render.useCss3DRenderer) { const e = this.j; this.R = new OptimizedCSS3DRenderer; this.R.setSize(e.clientWidth, e.clientHeight); const t = this.R.domElement; t.style.width = "100%"; t.style.height = "100%"; t.style.position = "absolute"; t.style.pointerEvents = "none"; t.onscroll = e => { const t = e.target; t.scrollTop = 0; t.scrollLeft = 0; }; e.appendChild(t); } s.build(); if (!this.i.camera) throw new Error("Camera is not exist or not active in the scene."); this.p.kind = GameStateKind.Running; this.v.startProcessNonSyncedEvent(); this.g.update(this._.deltaTime); this.P.updateAfterProcess(); if (!this.i.camera) throw new Error("Camera is not exist or not active in the scene."); this.v.processRemoveObject(); const r = this.G.update(); if (this.R) { this.R.render(r, this.S.unsafeGetThreeScene(), this.i.camera.threeCamera); } const o = this.l?.effectComposer; if (o) { o.render(this._.deltaTime); } else if (this.D) { this.D.render(this.S.unsafeGetThreeScene(), this.i.camera.threeCamera); } this.G.flush(); this.P.endFrameAfterProcess(); this.F = requestAnimationFrame(this.W); } q() { this._.update(); this.v.startProcessNonSyncedEvent(); this.g.update(this._.deltaTime); this.P.tryCompact(); this.P.updateAfterProcess(); if (!this.i.camera) throw new Error("Camera is not exist or not active in the scene."); this.v.processRemoveObject(); const e = this.G.update(); if (this.R) { this.R.render(e, this.S.unsafeGetThreeScene(), this.i.camera.threeCamera); } const t = this.l?.effectComposer; if (t) { t.render(this._.deltaTime); } else if (this.D) { this.D.render(this.S.unsafeGetThreeScene(), this.i.camera.threeCamera); } this.G.flush(); this.P.endFrameAfterProcess(); this.F = requestAnimationFrame(this.W); } stop() { if (this.A) throw new Error("Game is disposed."); if (this.p.kind !== GameStateKind.Running) throw new Error("Game is not running."); this.p.kind = GameStateKind.Stopped; if (this.F) cancelAnimationFrame(this.F); this.F = null; } resume() { if (this.A) throw new Error("Game is disposed."); if (this.p.kind !== GameStateKind.Stopped) throw new Error("Game is not stopped."); this.p.kind = GameStateKind.Running; this.q(); } dispose() { if (this.A) return; if (this.p.kind === GameStateKind.Running) { this.p.kind = GameStateKind.Finalizing; if (this.F) cancelAnimationFrame(this.F); this.L.dispose(); const e = this.S.children; for (let t = 0; t < e.length; ++t) { e[t].gameObject.destroy(); } if (this.R) this.j.removeChild(this.R.domElement); if (this.O) this.j.removeChild(this.O); if (this.l) this.l.dispose(); } else { this.L.dispose(); } if (this.M) window.removeEventListener("resize", this.B); this.j.remove(); this.A = true; this.p.kind = GameStateKind.Finalized; } get inputHandler() { return this.L.input; } get currentGameState() { return this.p.kind; } }