/// /// /// 'use strict'; var __extends = (this && this.__extends) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; var Vector3 = THREE.Vector3; var Material = THREE.Material; var Geometry = THREE.Geometry; //wtf fix.. Physijs.scripts.worker = "physi_js/physijs_worker.js"; Physijs.scripts.ammo = "ammo.js"; var PointerLock = (function () { function PointerLock(game, blocker, instructions) { var _this = this; this.game = game; this.blocker = blocker; this.instructions = instructions; this.hasLock = false; this.onChange = function (event) { var element = document.body; var doc = document; if (doc.pointerLockElement === element || doc.mozPointerLockElement === element || doc.webkitPointerLockElement === element) { //gained _this.hasLock = true; _this.blocker.style.display = "none"; if (_this.game.state == GameState.INITIALIZED || _this.game.state == GameState.PAUSED) { _this.game.start(); } console.log("gained"); } else { //lost _this.hasLock = false; _this.blocker.style.display = '-webkit-box'; _this.blocker.style.display = '-moz-box'; _this.blocker.style.display = 'box'; _this.instructions.style.display = ""; if (_this.game.state == GameState.STARTED) { _this.game.pause(); } console.log("lost"); } }; this.onError = function (event) { _this.instructions.style.display = ""; }; this.onClick = function (event) { var element = document.body; element.requestPointerLock = element.requestPointerLock || element.mozRequestPointerLock || element.webkitRequestPointerLock; _this.instructions.style.display = "none"; element.requestPointerLock(); }; } PointerLock.prototype.gain = function () { var havePointerLock = 'pointerLockElement' in document || 'mozPointerLockElement' 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); }; return PointerLock; }()); var Keyboard = (function () { function Keyboard() { var _this = this; this.status = {}; this.onKeyDown = function (event) { var key = Keyboard.keyName(event.keyCode); if (!_this.status[key]) _this.status[key] = { down: false, pressed: false, up: false, updatedPreviously: false }; }; this.onKeyUp = function (event) { var key = Keyboard.keyName(event.keyCode); if (_this.status[key]) _this.status[key].pressed = false; }; } Keyboard.prototype.update = function () { for (var key in this.status) { // insure that every keypress has "down" status exactly once if (!this.status[key].updatedPreviously) { this.status[key].down = true; this.status[key].pressed = true; this.status[key].updatedPreviously = true; } else { this.status[key].down = false; } // key has been flagged as "up" since last update if (this.status[key].up) { delete this.status[key]; continue; // move on to next key } if (!this.status[key].pressed) this.status[key].up = true; } }; Keyboard.prototype.down = function (key) { return (this.status[key] && this.status[key].down); }; Keyboard.prototype.pressed = function (key) { return (this.status[key] && this.status[key].pressed); }; Keyboard.prototype.up = function (key) { return (this.status[key] && this.status[key].up); }; Keyboard.prototype.register = function () { document.addEventListener("keydown", this.onKeyDown, false); document.addEventListener("keyup", this.onKeyUp, false); }; Keyboard.prototype.unregister = function () { document.removeEventListener("keydown", this.onKeyDown, false); document.removeEventListener("keyup", this.onKeyUp, false); }; Keyboard.keyName = function (keyCode) { return (Keyboard.k[keyCode] != null) ? Keyboard.k[keyCode] : String.fromCharCode(keyCode); }; /* Credit to: https://github.com/stemkoski */ Keyboard.k = { 8: "backspace", 9: "tab", 13: "enter", 16: "shift", 17: "ctrl", 18: "alt", 27: "esc", 32: "space", 33: "pageup", 34: "pagedown", 35: "end", 36: "home", 37: "left", 38: "up", 39: "right", 40: "down", 45: "insert", 46: "delete", 186: ";", 187: "=", 188: ",", 189: "-", 190: ".", 191: "/", 219: "[", 220: "\\", 221: "]", 222: "'" }; return Keyboard; }()); /** * */ var Mouse = (function () { function Mouse(player) { var _this = this; this.player = player; this.xMovement = 0; this.yMovement = 0; this.buttons = {}; this.onMouseMove = function (event) { _this.x = event.screenX; _this.xMovement = event.movementX; _this.y = event.screenY; _this.yMovement = event.movementY; _this.player.rotate(event.movementX); _this.player.look(event.movementY); }; this.onMouseDown = function (event) { _this.buttons[event.button] = true; _this.player.click(event.button); }; this.onMouseUp = function (event) { _this.buttons[event.button] = false; }; } Mouse.prototype.pressed = function (button) { return this.buttons[button]; }; Mouse.prototype.register = function () { document.addEventListener("mousemove", this.onMouseMove, false); document.addEventListener("mousedown", this.onMouseDown, false); document.addEventListener("mouseup", this.onMouseUp, false); }; Mouse.prototype.unregister = function () { document.removeEventListener("mousemove", this.onMouseMove, false); document.removeEventListener("mousedown", this.onMouseDown, false); document.removeEventListener("mouseup", this.onMouseUp, false); }; return Mouse; }()); /** * */ var Morph = (function (_super) { __extends(Morph, _super); function Morph(level, material, mass) { _super.call(this, Morph.generateGeometry(level), material, mass); this.level = level; } Morph.generateGeometry = function (level) { var numFaces = Morph.levels[level]; switch (numFaces) { case 4: return new THREE.TetrahedronGeometry(); case 6: return new THREE.BoxGeometry(1, 1, 1, 1, 1, 1); case 12: return new THREE.DodecahedronGeometry(1, 0); case 20: return new THREE.IcosahedronGeometry(1, 0); default: return new THREE.TetrahedronGeometry(); } }; Morph.prototype.updateGeometry = function () { this.geometry = Morph.generateGeometry(this.level); }; Morph.prototype.shrink = function () { if (this.level > 0) { this.level--; this.updateGeometry(); } }; Morph.prototype.grow = function () { if (this.level < 3) { this.level++; this.updateGeometry(); } }; Morph.levels = [4, 6, 12, 20]; return Morph; }(Physijs.SphereMesh)); /** * */ var Projectile = (function (_super) { __extends(Projectile, _super); function Projectile(pos, dir, level) { _super.call(this, level, Physijs.createMaterial(new THREE.MeshBasicMaterial({ color: 0x303030 }), 0.5, 0.3), 0.01); this.pos = pos; this.dir = dir; this.time = 0; this.position.copy(pos.clone().add(dir.clone().setLength(2))); } Projectile.prototype.shoot = function () { this.setLinearVelocity(this.dir); }; Projectile.prototype.tick = function (delta) { this.time += delta; }; return Projectile; }(Morph)); /** * */ var Enemy = (function (_super) { __extends(Enemy, _super); function Enemy() { _super.call(this, 0, Physijs.createMaterial(new THREE.MeshBasicMaterial({ color: 0xb02000 }), .8, .6), 2); this.speed = 10; } Enemy.prototype.approach = function (player) { var toPlayer = player.position.clone().sub(this.position).normalize(); this.setLinearVelocity(toPlayer.setLength(this.speed)); }; return Enemy; }(Morph)); var Player = (function (_super) { __extends(Player, _super); function Player() { _super.call(this, 1, Physijs.createMaterial(new THREE.MeshBasicMaterial({ color: 0x00a0b0 }), 1, 0.1), 0.5); this.forward = new Vector3(0, 0, -1); this.upward = new Vector3(0, 1, 0); this.camera = new Vector3(0, 10, 10); this.heading = 0; this.pitch = 0; this.speed = 25; this.projectiles = []; } Player.prototype.jump = function () { this.applyCentralImpulse(new Vector3(0, 8, 0)); }; Player.prototype.rotate = function (xMovement) { this.heading -= xMovement * 0.002; }; Player.prototype.look = function (yMovement) { this.pitch -= yMovement * 0.002; }; Player.prototype.click = function (button) { if (button == THREE.MOUSE.LEFT) { this.projectiles.push(new Projectile(this.position, this.getDirection().multiplyScalar(35), this.level)); } }; Player.prototype.getRight = function () { return this.getDirection().cross(this.upward).normalize(); }; Player.prototype.getDirection = function () { return this.forward.clone().applyAxisAngle(this.upward, this.heading); }; Player.prototype.getCamera = function () { return this.camera.clone().applyAxisAngle(this.upward, this.heading).applyAxisAngle(this.getRight(), this.pitch); }; return Player; }(Morph)); var World = (function (_super) { __extends(World, _super); function World(player) { _super.call(this); this.player = player; this.mobs = []; this.projectiles = []; this.setGravity(new THREE.Vector3(0, -40, 0)); this.add(player); player.position.set(0, 2, 0); player.castShadow = true; player.setDamping(0.05, 0.05); for (var i = 0; i < 10; i++) { var enemy = new Enemy(); var x = Math.floor(Math.random() * 20 + 3); var z = Math.floor(Math.random() * 20 + 3); enemy.position.set(x, 2, z); this.add(enemy); this.mobs.push(enemy); } var light = new THREE.DirectionalLight(0xFFFFFF); light.position.set(20, 40, -15); light.target.position.copy(player.position); light.castShadow = true; light.shadow.camera.left = -60; light.shadow.camera.top = -60; light.shadow.camera.right = 60; light.shadow.camera.bottom = 60; light.shadow.camera.near = 20; light.shadow.camera.far = 200; light.shadow.bias = -.0001; light.shadow.mapSize.width = light.shadow.mapSize.height = 2048; this.add(light); var groundGeometry = new THREE.BoxGeometry(1000, 1, 1000); var groundMaterial = Physijs.createMaterial(new THREE.MeshBasicMaterial({ color: 0xdadada }), 1, 1); var ground = new Physijs.BoxMesh(groundGeometry, groundMaterial, 0); ground.receiveShadow = true; this.add(ground); } World.prototype.tick = function (delta) { var _this = this; //push projectiles queued from player into the world. while (this.player.projectiles.length > 0) { var projectile = this.player.projectiles.pop(); this.projectiles.push(projectile); this.add(projectile); projectile.shoot(); } //enemy movement this.mobs.forEach(function (mob) { mob.approach(_this.player); }); //tick projectiles and remove them if time out //todo fix projectile removal, now ammojs spams obj s undefined /* this.projectiles.filter((projectile) => { projectile.tick(delta); let keep = projectile.time < 10 * 1000; if (!keep) { this.remove(projectile); } return keep; }); */ //physijs this.simulate(delta, 1); }; return World; }(Physijs.Scene)); var GameState; (function (GameState) { GameState[GameState["INITIALIZED"] = 0] = "INITIALIZED"; GameState[GameState["STARTED"] = 1] = "STARTED"; GameState[GameState["PAUSED"] = 2] = "PAUSED"; GameState[GameState["STOPPED"] = 3] = "STOPPED"; })(GameState || (GameState = {})); var Game = (function () { function Game() { var _this = this; this.ticks = 0; this.delta = 0; this.lastFrame = 0; this.timestep = 1000 / 60; this.maxFPS = 60; this.onWindowResize = function () { _this.camera.aspect = window.innerWidth / window.innerHeight; _this.camera.updateProjectionMatrix(); _this.renderer.setSize(window.innerWidth, window.innerHeight); }; this.renderer = new THREE.WebGLRenderer({ antialias: true }); this.renderer.setClearColor(0xffffff); this.renderer.setPixelRatio(window.devicePixelRatio); this.renderer.setSize(window.innerWidth, window.innerHeight); this.renderer.shadowMap.enabled = true; this.renderer.shadowMap.type = THREE.PCFSoftShadowMap; document.body.appendChild(this.renderer.domElement); window.addEventListener("resize", this.onWindowResize, false); this.camera = new THREE.PerspectiveCamera(55, window.innerWidth / window.innerHeight, 1, 1000); } Game.prototype.init = function () { //init player and world this.player = new Player(); this.world = new World(this.player); //init camera this.camera.position.addVectors(this.player.position, this.player.camera); this.camera.lookAt(this.player.position); //init keyboard and mouse this.keyboard = new Keyboard(); this.mouse = new Mouse(this.player); this.state = GameState.INITIALIZED; }; /** * Just render the scene. */ Game.prototype.render = function () { this.renderer.render(this.world, this.camera); }; /** * Update logic based on @param delta. * @param delta */ Game.prototype.tick = function (delta) { this.ticks++; this.keyboard.update(); //camera this.camera.position.addVectors(this.player.position, this.player.getCamera()); this.camera.lookAt(this.player.position); //player movement var forward = this.player.getDirection(); forward.setLength(this.player.speed); var right = forward.clone().cross(this.player.upward); right.setLength(this.player.speed); if (this.keyboard.pressed("W")) { this.player.applyCentralForce(forward); } if (this.keyboard.pressed("S")) { this.player.applyCentralForce(forward.negate()); } if (this.keyboard.pressed("D")) { this.player.applyCentralForce(right); } if (this.keyboard.pressed("A")) { this.player.applyCentralForce(right.negate()); } //clamp speed, TODO into a method var velocity = this.player.getLinearVelocity().clampLength(-20, 20); this.player.setLinearVelocity(velocity); //morph! if (this.keyboard.down("Q")) { this.player.shrink(); } else if (this.keyboard.down("E")) { this.player.grow(); } //jump! if (this.keyboard.down("space")) { console.log("jump"); this.player.jump(); } this.world.tick(delta); }; Game.prototype.run = function (timestamp) { var _this = this; if (!timestamp) { timestamp = performance.now(); } if (timestamp < this.lastFrame + (1000 / this.maxFPS)) { if (this.keepRunning) { requestAnimationFrame(function () { return _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(function (time) { return _this.run(time); }); } }; Game.prototype.start = function () { this.state = GameState.STARTED; this.keepRunning = true; this.lastFrame = performance.now(); this.keyboard.register(); this.mouse.register(); this.run(); }; Game.prototype.pause = function () { this.state = GameState.PAUSED; this.keyboard.unregister(); this.mouse.unregister(); this.keepRunning = false; }; Game.prototype.stop = function () { this.pause(); this.state = GameState.STOPPED; this.mouse.unregister(); this.keyboard.unregister(); window.removeEventListener("resize", this.onWindowResize, false); //todo }; return Game; }()); if (!Detector.webgl) { Detector.addGetWebGLMessage(); } window.onload = function () { var game = new Game(); game.init(); //make sure we have pointerlock here //from three.js example(PointerLock), thanks var block = document.getElementById("block"); var instructions = document.getElementById("instructions"); var plock = new PointerLock(game, block, instructions); plock.gain(); }; //# sourceMappingURL=game.js.map