diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/block.ts | 181 | ||||
| -rw-r--r-- | src/cube.ts | 36 | ||||
| -rw-r--r-- | src/game.ts | 175 | ||||
| -rw-r--r-- | src/input.ts | 9 | ||||
| -rw-r--r-- | src/omni.ts | 158 | ||||
| -rw-r--r-- | src/pointerlock.ts | 75 |
6 files changed, 394 insertions, 240 deletions
diff --git a/src/block.ts b/src/block.ts index bd80239..0d5b97e 100644 --- a/src/block.ts +++ b/src/block.ts @@ -1,5 +1,95 @@ module Omni { + export class Block { + private state:number; + + private mesh:Physijs.BoxMesh; + + static states:number[]; + static mesh_file:string = ""; + + //will take the correct state as params? + constructor(private geometry:THREE.Geometry, private materials:THREE.Material[]) { + this.mesh = new Physijs.BoxMesh(geometry, materials[0], 0); + } + + getState():number { + return this.state; + } + + setState(state:number):void { + this.state = state; + } + + setPosition(pos:THREE.Vector3):void { + this.mesh.position.copy(pos); + } + + getPosition():THREE.Vector3 { + return this.mesh.position.clone(); + } + + getObject():THREE.Object3D { + return this.mesh; + } + + } + + /** + * Plain block without any puzzles. + */ + export class PlainBlock extends Block { + static mesh_file = "plainBlock.json"; + static states:number[] = []; + + constructor(loader:BlockLoader) { + super(loader.getMesh(PlainBlock.mesh_file), loader.getMaterials(PlainBlock.mesh_file)); + } + } + + /** + * Button block with 2 states + */ + export class ButtonBlock extends Block { + //need to make good design choices here, with the handling of states.. + static mesh_file = "buttonBlock.json"; + static states:number[] = [0, 1]; + + constructor(loader:BlockLoader) { + super(loader.getMesh(ButtonBlock.mesh_file), loader.getMaterials(ButtonBlock.mesh_file)); + } + } + + /** + * Lever block with 4 positions/states + */ + export class LeverBlock extends Block { + static mesh_file = "leverBlock.json"; + static states:number[] = [0, 1, 2, 3]; + + constructor(loader:BlockLoader) { + super(loader.getMesh(LeverBlock.mesh_file), loader.getMaterials(LeverBlock.mesh_file)); + } + } + + /** + * + */ + export class AzimuthBlock extends Block { + static mesh_file = "azimuthBlock.json"; + static states:number[] = [0, 1, 2, 3]; + + } + + /** + * + */ + export class PullBlock extends Block { + static mesh_file = "pullBlock.json"; + static states:number[] = []; + + } + export class BlockLoader { private manager:THREE.LoadingManager = new THREE.LoadingManager(); private loader:THREE.JSONLoader = new THREE.JSONLoader(this.manager); @@ -10,12 +100,13 @@ module Omni { private loaded:boolean = false; static URL_PREFIX:string = "json/"; - static FILES:string[] = [ + static BLOCKS:string[] = [ PlainBlock.mesh_file, LeverBlock.mesh_file, - ButtonBlock.mesh_file, - AzimuthBlock.mesh_file, - PullBlock.mesh_file]; + //ButtonBlock.mesh_file, + //AzimuthBlock.mesh_file, + //PullBlock.mesh_file, + ]; /** * @param files what files to load() @@ -23,6 +114,7 @@ module Omni { constructor(private files:string[]) { this.manager.onLoad = () => { this.loaded = true; + console.debug("BlockLoader: loaded"); }; } @@ -30,7 +122,7 @@ module Omni { * Load all the geometries and materials from mesh_files */ load():void { - console.log("BlockLoader: loading..."); + console.debug("BlockLoader: loading..."); this.files.forEach((file) => { this.loadOne(file); }); @@ -58,7 +150,7 @@ module Omni { * Dispose of all the geometries and mats */ dispose():void { - console.log("BlockLoader: disposing..."); + console.debug("BlockLoader: disposing..."); if (this.loaded) { this.files.forEach((file) => { this.geometries[file].dispose(); @@ -90,81 +182,4 @@ module Omni { return this.materials[file]; } } - - export class Block { - private state:number; - - private mesh:Physijs.BoxMesh; - - static states:number[]; - static mesh_file:string = ""; - - //will take the correct state as params? - constructor() { - - } - - getState():number { - return this.state; - } - - setState(state:number):void { - this.state = state; - } - } - - /** - * Plain block without any puzzles. - */ - export class PlainBlock extends Block { - static mesh_file = "plainBlock.json"; - static states:number[] = []; - - constructor() { - super(); - } - } - - /** - * Button block with 2 states - */ - export class ButtonBlock extends Block { - //need to make good design choices here, with the handling of states.. - static mesh_file = "buttonBlock.json"; - static states:number[] = [0, 1]; - - constructor() { - super(); - } - } - - /** - * Lever block with 4 positions/states - */ - export class LeverBlock extends Block { - static mesh_file = "leverBlock.json"; - static states:number[] = [0, 1, 2, 3]; - - constructor() { - super(); - } - } - - /** - * - */ - export class AzimuthBlock extends Block { - static mesh_file = "azimuthBlock.json"; - static states:number[] = [0, 1, 2, 3]; - - } - - /** - * - */ - export class PullBlock extends Block { - static mesh_file = "pullBlock.json"; - static states:number[] = []; - - } }
\ No newline at end of file diff --git a/src/cube.ts b/src/cube.ts index bcb2988..f80f07e 100644 --- a/src/cube.ts +++ b/src/cube.ts @@ -1,15 +1,41 @@ module Omni { - export class Cube extends Physijs.Scene implements Tickable{ - private elements:Block[]; + export class Cube extends Physijs.Scene implements Tickable { + private blocks:Block[]; private puzzles:Puzzle[]; - constructor() { + static SIZE:number = 4; + + constructor(private loader:BlockLoader) { super(); - let block = new LeverBlock(); - } + init(level?:number):void { + //cube size, 4*4*4 + //generate corners first + let half = Cube.SIZE / 2; + let corners = [ + new THREE.Vector3(-1, -1, -1), + new THREE.Vector3(1, -1, -1), + new THREE.Vector3(-1, -1, 1), + new THREE.Vector3(1, -1, 1), + new THREE.Vector3(-1, 1, -1), + new THREE.Vector3(1, 1, -1), + new THREE.Vector3(-1, 1, 1), + new THREE.Vector3(1, 1, 1) + ]; + for (let corner of corners) { + let vertex = corner.clone().multiplyScalar(half); + let block = new PlainBlock(this.loader); + block.setPosition(vertex.add(corner.clone().multiplyScalar(0.5))); + this.add(block.getObject()); + this.blocks.push(block); + } + + //then edges + //then fill in the rest + + } tick(delta:number):void { this.simulate(delta); 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 diff --git a/src/input.ts b/src/input.ts new file mode 100644 index 0000000..07154a0 --- /dev/null +++ b/src/input.ts @@ -0,0 +1,9 @@ +module Omni { + export class Keyboard { + + } + + export class Mouse { + + } +}
\ No newline at end of file diff --git a/src/omni.ts b/src/omni.ts index 64a31a8..fcef3d9 100644 --- a/src/omni.ts +++ b/src/omni.ts @@ -1,156 +1,10 @@ /// <reference path="../ts/three.d.ts" /> /// <reference path="../ts/physijs.d.ts" /> -/// <reference path="cube.ts" /> + +/// <reference path="game.ts" /> +/// <reference path="interface.ts" /> +/// <reference path="input.ts" /> /// <reference path="block.ts" /> /// <reference path="puzzle.ts" /> -/// <reference path="pointerlock.ts" /> -/// <reference path="interface.ts" /> - -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 block_loader:BlockLoader; - private current_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(0xcacaca); - this.renderer.setSize(window.innerWidth, window.innerHeight); - document.body.appendChild(this.renderer.domElement); - window.addEventListener("resize", this.onWindowResize, false); - - this.camera = new THREE.PerspectiveCamera(Game.CAMERA_FOV, window.innerWidth / window.innerHeight, Game.CAMERA_NEAR, Game.CAMERA_FAR); - this.block_loader = new BlockLoader(BlockLoader.FILES); - } - - /** - * - */ - init():void { - - this.block_loader.load(); - } - - /** - * - */ - start():void { - - } - - /** - * - */ - unpause():void { - - } - - /** - * - * @param delta - */ - tick(delta:number):void { - this.ticks++; - this.current_cube.tick(delta); - } - - /** - * - */ - render():void { - this.renderer.render(this.current_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 { - - } - - /** - * When leaving the page. - */ - stop():void { - this.block_loader.dispose(); - } - - onWindowResize = () => { - this.camera.aspect = window.innerWidth / window.innerHeight; - this.camera.updateProjectionMatrix(); - - this.renderer.setSize(window.innerWidth, window.innerHeight); - }; - - } -} - -let game:Omni.Game; -window.onload = () => { - console.log("onload"); - game = new Omni.Game(); - game.init(); - game.start(); -}; - -window.onunload = () => { - console.log("onunload"); - game.pause(); - game.stop(); -}; +/// <reference path="cube.ts" /> +/// <reference path="pointerlock.ts" />
\ No newline at end of file diff --git a/src/pointerlock.ts b/src/pointerlock.ts index d75ccda..7bd4dab 100644 --- a/src/pointerlock.ts +++ b/src/pointerlock.ts @@ -1,5 +1,80 @@ module Omni { export class PointerLocker { + hasLock:boolean = false; + private blocker:HTMLElement = document.getElementById("block"); + private instructions:HTMLElement = document.getElementById("instructions"); + constructor(private onGain:() => void, private onLose:() => void) { + } + + enable():void { + let havePointerLock = 'pointerLockElement' in document || 'mozPointerLockElsement' in document || 'webkitPointerLockElement' in document; + if (!havePointerLock) { + return; + } + + document.addEventListener("pointerlockchange", this.onChange, false); + document.addEventListener("mozpointerlockchange", this.onChange, false); + document.addEventListener("webkitpointerlockchange", this.onChange, false); + + document.addEventListener("pointerlockerror", this.onError, false); + document.addEventListener("mozpointerlockerror", this.onError, false); + document.addEventListener("webkitpointerlockerror", this.onError, false); + + this.blocker.addEventListener("click", this.onClick, false); + } + + onChange = (event):void => { + let element = document.body; + let doc:any = document; + + if (doc.pointerLockElement === element || doc.mozPointerLockElement === element || doc.webkitPointerLockElement === element) { + //gained + this.hasLock = true; + this.hide(); + this.onGain(); + } else { + //lost + this.hasLock = false; + this.show(); + this.onLose(); + } + }; + + onError = (event):void => { + + }; + + onClick = (event):void => { + let element:any = document.body; + element.requestPointerLock = element.requestPointerLock || element.mozRequestPointerLock || element.webkitRequestPointerLock; + this.instructions.style.display = "none"; + + element.requestPointerLock(); + }; + + disable():void { + document.removeEventListener("pointerlockchange", this.onChange, false); + document.removeEventListener("mozpointerlockchange", this.onChange, false); + document.removeEventListener("webkitpointerlockchange", this.onChange, false); + + document.removeEventListener("pointerlockerror", this.onError, false); + document.removeEventListener("mozpointerlockerror", this.onError, false); + document.removeEventListener("webkitpointerlockerror", this.onError, false); + + this.blocker.removeEventListener("click", this.onClick, false); + } + + private hide():void { + this.blocker.style.display = "none"; + } + + private show():void { + this.blocker.style.display = '-webkit-box'; + this.blocker.style.display = '-moz-box'; + this.blocker.style.display = 'box'; + + this.instructions.style.display = ""; + } } }
\ No newline at end of file |
