summaryrefslogtreecommitdiff
path: root/src/game.ts
diff options
context:
space:
mode:
Diffstat (limited to 'src/game.ts')
-rw-r--r--src/game.ts175
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