summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/block.ts181
-rw-r--r--src/cube.ts36
-rw-r--r--src/game.ts175
-rw-r--r--src/input.ts9
-rw-r--r--src/omni.ts158
-rw-r--r--src/pointerlock.ts75
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