diff options
Diffstat (limited to 'src/game.ts')
| -rw-r--r-- | src/game.ts | 175 |
1 files changed, 175 insertions, 0 deletions
diff --git a/src/game.ts b/src/game.ts new file mode 100644 index 0000000..09aea10 --- /dev/null +++ b/src/game.ts @@ -0,0 +1,175 @@ +module Omni { + /** + * Base game class, will handle the game loop, rendering, + */ + export class Game implements Tickable { + private renderer:THREE.WebGLRenderer; + private camera:THREE.PerspectiveCamera; + + private blockLoader:BlockLoader; + private cube:Cube; + + private ticks:number = 0; + private delta:number = 0; + private lastFrame:number = 0; + private timestep:number = 1000 / 60; + private maxFPS:number = 60; + + private keepRunning:boolean; + + static CAMERA_FOV:number = 55; + static CAMERA_NEAR:number = 1; + static CAMERA_FAR:number = 1000; + + /** + * + */ + constructor() { + this.renderer = new THREE.WebGLRenderer({ + antialias: true + }); + this.renderer.setClearColor(0xbababa); + this.renderer.setSize(window.innerWidth, window.innerHeight); + document.body.appendChild(this.renderer.domElement); + + window.addEventListener("resize", this.onWindowResize, false); + window.addEventListener("visibilitychange", this.onVisibilityChange, false); + + this.camera = new THREE.PerspectiveCamera(Game.CAMERA_FOV, window.innerWidth / window.innerHeight, Game.CAMERA_NEAR, Game.CAMERA_FAR); + this.blockLoader = new BlockLoader(BlockLoader.BLOCKS); + } + + /** + * + */ + init():void { + console.debug("Game: init"); + this.blockLoader.load(); + } + + /** + * + */ + start = ():void => { + console.debug("Game: start"); + + //wait around till block_loader is done loading assets + if (!this.blockLoader.isLoaded()) { + setTimeout(this.start, 10); + return; + } + + //build the level here + this.cube.init(0); + + this.unpause(); + }; + + /** + * + */ + unpause():void { + console.debug("Game: unpause"); + + this.keepRunning = true; + this.run(); + } + + /** + * + * @param delta + */ + tick(delta:number):void { + this.ticks++; + this.cube.tick(delta); + } + + /** + * + */ + render():void { + this.renderer.render(this.cube, this.camera); + } + + /** + * + * @param timestamp + */ + run(timestamp?:number):void { + if (!timestamp) { + timestamp = performance.now(); + } + + if (timestamp < this.lastFrame + (1000 / this.maxFPS)) { + if (this.keepRunning) { + requestAnimationFrame(() => this.run()); + } + return; + } + this.delta += timestamp - this.lastFrame; + this.lastFrame = timestamp; + + var numUpdateSteps = 0; + while (this.delta >= this.timestep) { + this.tick(this.timestep); + this.delta -= this.timestep; + if (++numUpdateSteps >= 240) { + // panic here, reset delta + this.delta = 0; + break; + } + } + + this.render(); + if (this.keepRunning) { + requestAnimationFrame((time) => this.run(time)); + } + } + + /** + * When releasing pointer lock/on menu. Menu is HTML based. + */ + pause():void { + console.debug("Game: pause"); + this.keepRunning = false; + } + + /** + * When leaving the page. + */ + stop = ():void => { + this.pause(); + + console.debug("Game: stop"); + this.blockLoader.dispose(); + this.renderer.dispose(); + }; + + onWindowResize = () => { + this.camera.aspect = window.innerWidth / window.innerHeight; + this.camera.updateProjectionMatrix(); + + this.renderer.setSize(window.innerWidth, window.innerHeight); + }; + + onVisibilityChange = () => { + console.debug("visibility change"); + }; + + } +} + +let game:Omni.Game; +let locker:Omni.PointerLocker; + +window.onload = () => { + game = new Omni.Game(); + locker = new Omni.PointerLocker(game.start, game.stop); + game.init(); + locker.enable(); +}; + +window.onunload = () => { + locker.disable(); + game.stop(); +};
\ No newline at end of file |
