diff --git a/app/Bootstrap/HttpServer.js b/app/Bootstrap/HttpServer.js index 1c30e77..e8f3f2d 100755 --- a/app/Bootstrap/HttpServer.js +++ b/app/Bootstrap/HttpServer.js @@ -69,6 +69,10 @@ function (http, nodeStatic, Api, fs) { fileServer.serveFile('./node_modules/screenfull/dist/screenfull.js', 200, {}, req, res); break; + case req.url == '/chart.js': + fileServer.serveFile('./node_modules/chart.js/Chart.js', 200, {}, req, res); + break; + case req.url == '/api': self.api.handleCall(fullBody); var status = self.api.isError ? 400 : 200; diff --git a/app/Game/Client/Control/PlayerController.js b/app/Game/Client/Control/PlayerController.js index 2e67d96..8332ab3 100755 --- a/app/Game/Client/Control/PlayerController.js +++ b/app/Game/Client/Control/PlayerController.js @@ -3,9 +3,10 @@ define([ "Lib/Utilities/NotificationCenter", "Game/Client/Control/Inputs/KeyboardAndMouse", "Game/Client/Control/Inputs/Gamepad", + "Game/Client/PointerLockManager" ], -function (Parent, Nc, KeyboardAndMouse, Gamepad) { +function (Parent, Nc, KeyboardAndMouse, Gamepad, PointerLockManager) { "use strict"; @@ -20,16 +21,19 @@ function (Parent, Nc, KeyboardAndMouse, Gamepad) { PlayerController.prototype = Object.create(Parent.prototype); PlayerController.prototype.update = function() { + Parent.prototype.update.call(this); this.gamepad.update(); }; PlayerController.prototype.moveLeft = function () { + if (!PointerLockManager.isLocked()) return; Parent.prototype.moveLeft.call(this); Nc.trigger(Nc.ns.client.to.server.gameCommand.send, 'moveLeft'); } PlayerController.prototype.moveRight = function () { + if (!PointerLockManager.isLocked()) return; Parent.prototype.moveRight.call(this); Nc.trigger(Nc.ns.client.to.server.gameCommand.send, 'moveRight'); } @@ -40,54 +44,66 @@ function (Parent, Nc, KeyboardAndMouse, Gamepad) { } PlayerController.prototype.jump = function () { + if (!PointerLockManager.isLocked()) return; Parent.prototype.jump.call(this); Nc.trigger(Nc.ns.client.to.server.gameCommand.send, 'jump'); } PlayerController.prototype.jumpStop = function () { + if (!PointerLockManager.isLocked()) return; Parent.prototype.jumpStop.call(this); Nc.trigger(Nc.ns.client.to.server.gameCommand.send, 'jumpStop'); } PlayerController.prototype.setXY = function(x, y) { + if (!PointerLockManager.isLocked()) return; var options = {x:x, y:y}; Parent.prototype.lookAt.call(this, options); Nc.trigger(Nc.ns.client.to.server.gameCommand.send, 'lookAt', options); }; PlayerController.prototype.handActionLeft = function() { + if (!PointerLockManager.isLocked()) return; this.handActionRequest(-0.5, 0.5); }; PlayerController.prototype.handActionRight = function() { + if (!PointerLockManager.isLocked()) return; this.handActionRequest(0.5, 0.5); }; PlayerController.prototype.suicide = function() { + if (!PointerLockManager.isLocked()) return; Nc.trigger(Nc.ns.client.to.server.gameCommand.send, "suicide"); }; PlayerController.prototype.handActionRequest = function(options) { + if (!PointerLockManager.isLocked()) return; Nc.trigger(Nc.ns.client.to.server.gameCommand.send, "handActionRequest", options); }; PlayerController.prototype.showInfo = function() { + if (!PointerLockManager.isLocked()) return; Nc.trigger(Nc.ns.client.game.gameStats.toggle, true); }; PlayerController.prototype.hideInfo = function() { + if (!PointerLockManager.isLocked()) return; Nc.trigger(Nc.ns.client.game.gameStats.toggle, false); }; PlayerController.prototype.zoomIn = function() { + if (!PointerLockManager.isLocked()) return; Nc.trigger(Nc.ns.client.game.zoomIn, true); }; PlayerController.prototype.zoomOut = function() { + if (!PointerLockManager.isLocked()) return; Nc.trigger(Nc.ns.client.game.zoomOut, false); }; PlayerController.prototype.zoomReset = function() { + if (!PointerLockManager.isLocked()) return; Nc.trigger(Nc.ns.client.game.zoomReset, false); }; diff --git a/app/Game/Client/GameController.js b/app/Game/Client/GameController.js index 982f184..9dd24ea 100755 --- a/app/Game/Client/GameController.js +++ b/app/Game/Client/GameController.js @@ -12,10 +12,11 @@ define([ "Game/Client/View/DomController", "Lib/Utilities/Protocol/Helper", "Game/Client/Me", - "Game/Client/AudioPlayer" + "Game/Client/AudioPlayer", + "Game/Client/PointerLockManager" ], -function (Parent, Box2D, PhysicsEngine, ViewManager, PlayerController, Nc, requestAnimFrame, Settings, GameObject, Doll, DomController, ProtocolHelper, Me, AudioPlayer) { +function (Parent, Box2D, PhysicsEngine, ViewManager, PlayerController, Nc, requestAnimFrame, Settings, GameObject, Doll, DomController, ProtocolHelper, Me, AudioPlayer, PointerLockManager) { "use strict"; @@ -242,6 +243,10 @@ function (Parent, Box2D, PhysicsEngine, ViewManager, PlayerController, Nc, reque Parent.prototype.loadLevel.call(this, path); } + GameController.prototype.onLevelLoaded = function () { + PointerLockManager.update(null, {start:true}); + } + GameController.prototype.toggleGameStats = function(show) { var playersArray = []; diff --git a/app/Game/Client/Loader/Level.js b/app/Game/Client/Loader/Level.js index 42da85e..540f04a 100755 --- a/app/Game/Client/Loader/Level.js +++ b/app/Game/Client/Loader/Level.js @@ -106,8 +106,9 @@ function (Parent, Settings, Nc, PIXI, AbstractLayer) { }; Level.prototype.setupLayer = function(options, behind, referenceId) { + Parent.prototype.setupLayer.call(this, options, behind, referenceId); - var parallaxSpeed = 0.0; + var parallaxSpeed = 0.0; // default parallax if (options.properties && options.properties.parallaxSpeed) { parallaxSpeed = parseFloat(options.properties.parallaxSpeed); } diff --git a/app/Game/Client/Loader/TiledLevel.js b/app/Game/Client/Loader/TiledLevel.js index 0f7cd1d..d45fdfa 100644 --- a/app/Game/Client/Loader/TiledLevel.js +++ b/app/Game/Client/Loader/TiledLevel.js @@ -70,6 +70,8 @@ function (Parent, Settings, Nc) { TiledLevel.prototype.setupLayer = function(options, behind, referenceId) { + var self = this; + Parent.prototype.setupLayer.call(this, options, behind, referenceId); // So far only one image per layer is possible because of Tiled editor @@ -80,8 +82,8 @@ function (Parent, Settings, Nc) { var callback = function(mesh) { Nc.trigger(Nc.ns.client.view.mesh.add, options.layerId, mesh); Nc.trigger(Nc.ns.client.view.mesh.update, options.layerId, mesh, { - x: Settings.STAGE_WIDTH / 2, - y: Settings.STAGE_HEIGHT / 2, + x: 0,//self.levelData.width * Settings.TILE_SIZE / 2, + y: 0,//self.levelData.height * Settings.TILE_SIZE / 2, pivot: { x: mesh.texture.width / 2, y: mesh.texture.height / 2 diff --git a/app/Game/Client/Networker.js b/app/Game/Client/Networker.js index 985ae2b..193a96b 100755 --- a/app/Game/Client/Networker.js +++ b/app/Game/Client/Networker.js @@ -90,6 +90,8 @@ function (ProtocolHelper, GameController, User, Nc, Settings, DomController) { } } + this.gameController.onLevelLoaded(); + this.sendGameCommand("clientReady"); }; diff --git a/app/Game/Client/PointerLockManager.js b/app/Game/Client/PointerLockManager.js new file mode 100644 index 0000000..8959fad --- /dev/null +++ b/app/Game/Client/PointerLockManager.js @@ -0,0 +1,53 @@ +define([ + "Lib/Utilities/QuerySelector", + "Lib/Utilities/NotificationCenter" +], + +function (Qs, Nc) { + + "use strict"; + + function PointerLockManager() { + this.canvas = Qs.$("#canvas"); + + this.listeners = []; + + if (!document) { + throw new Error("Using PointerLockManager, but window.document is not defined."); + } + + document.addEventListener('pointerlockchange', this.update.bind(this), false); + document.addEventListener('mozpointerlockchange', this.update.bind(this), false); + document.addEventListener('webkitpointerlockchange', this.update.bind(this), false); + + this.ncTokens = [ + Nc.on(Nc.ns.client.pointerLock.request, this.request, this) + ]; + } + + PointerLockManager.prototype.request = function() { + + var canvas = this.canvas; + + canvas.requestPointerLock = canvas.requestPointerLock || + canvas.mozRequestPointerLock || + canvas.webkitRequestPointerLock; + + // Ask the browser to lock the pointer + canvas.requestPointerLock(); + } + + // called by the browser event and others + PointerLockManager.prototype.update = function(e, options) { + options = options ? options : {}; + Nc.trigger(Nc.ns.client.pointerLock.change, this.isLocked(), options); + }; + + PointerLockManager.prototype.isLocked = function() { + return document.pointerLockElement === this.canvas || + document.mozPointerLockElement === this.canvas || + document.webkitPointerLockElement === this.canvas; + }; + + return new PointerLockManager(); +}); \ No newline at end of file diff --git a/app/Game/Client/View/Abstract/View.js b/app/Game/Client/View/Abstract/View.js index 10fc885..378aa8e 100755 --- a/app/Game/Client/View/Abstract/View.js +++ b/app/Game/Client/View/Abstract/View.js @@ -16,7 +16,7 @@ function (Abstract, DomController, Settings, Exception, Nc) { this.debugMode = false; this.ncTokens = [ - Nc.on(Nc.ns.client.view.fullscreen.change, this.onFullscreenChange, this), + Nc.on(Nc.ns.client.view.display.change, this.onDisplaySizeChange, this), Nc.on(Nc.ns.client.view.debugMode.toggle, this.onToggleDebugMode, this), Nc.on(Nc.ns.client.game.zoomIn, this.onZoomIn, this), @@ -70,8 +70,9 @@ function (Abstract, DomController, Settings, Exception, Nc) { return pos; }; */ - AbstractView.prototype.onFullscreenChange = function(isFullScreen) { + AbstractView.prototype.onDisplaySizeChange = function(isFullScreen) { +/* if (!isFullScreen) { Settings.STAGE_WIDTH = 600; Settings.STAGE_HEIGHT = 400; @@ -81,6 +82,10 @@ function (Abstract, DomController, Settings, Exception, Nc) { Settings.STAGE_WIDTH = window.innerWidth; Settings.STAGE_HEIGHT = window.innerHeight; } + */ + + Settings.STAGE_WIDTH = window.innerWidth; + Settings.STAGE_HEIGHT = window.innerHeight; }; AbstractView.prototype.onToggleDebugMode = function(debugMode) { diff --git a/app/Game/Client/View/DomController.js b/app/Game/Client/View/DomController.js index ee1f8b4..e1450e5 100755 --- a/app/Game/Client/View/DomController.js +++ b/app/Game/Client/View/DomController.js @@ -2,10 +2,12 @@ define([ 'Game/Config/Settings', 'Lib/Utilities/NotificationCenter', "Lib/Vendor/Stats", - "Lib/Vendor/Screenfull" + "Lib/Vendor/Screenfull", + "Game/Client/View/GraphManager", + "Game/Client/PointerLockManager" ], -function (Settings, Nc, Stats, Screenfull) { +function (Settings, Nc, Stats, Screenfull, GraphManager, PointerLockManager) { "use strict"; @@ -15,6 +17,9 @@ function (Settings, Nc, Stats, Screenfull) { this.stats = null; this.ping = null; + var contextFps = document.getElementById('graph-fps').getContext("2d"); + this.gm = new GraphManager(contextFps); + Nc.on(Nc.ns.client.view.events.ready, this.initDevTools, this); } @@ -57,6 +62,7 @@ function (Settings, Nc, Stats, Screenfull) { button.innerHTML = "Fullscreen"; button.onclick = function() { if(Screenfull.enabled) { + PointerLockManager.request(); Screenfull.request(self.canvas); } } @@ -64,13 +70,12 @@ function (Settings, Nc, Stats, Screenfull) { this.devToolsContainer.appendChild(li); window.onresize = function() { - if(Screenfull.enabled) { - Nc.trigger(Nc.ns.client.view.fullscreen.change, Screenfull.isFullscreen); - } + Nc.trigger(Nc.ns.client.view.display.change); } }; DomController.prototype.statsBegin = function() { + this.gm.fpsStep(); if(this.stats) { this.stats.begin(); } @@ -80,6 +85,7 @@ function (Settings, Nc, Stats, Screenfull) { if(this.stats) { this.stats.end(); } + }; DomController.prototype.setPing = function(ping) { @@ -101,7 +107,7 @@ function (Settings, Nc, Stats, Screenfull) { } DomController.prototype.initCanvas = function (canvas) { - Nc.trigger(Nc.ns.client.view.fullscreen.change, Screenfull.isFullscreen); + Nc.trigger(Nc.ns.client.view.display.change, Screenfull.isFullscreen); } DomController.prototype.getDebugCanvas = function () { diff --git a/app/Game/Client/View/GraphManager.js b/app/Game/Client/View/GraphManager.js new file mode 100644 index 0000000..057921a --- /dev/null +++ b/app/Game/Client/View/GraphManager.js @@ -0,0 +1,80 @@ +define([ + "Lib/Vendor/Chart" +], + +function (Chart) { + + "use strict"; + + function GraphManager(ctxFps) { + + var numberOfGraphBarsFPS = 25; + + var empty = new Array(numberOfGraphBarsFPS); + for (var i = empty.length - 1; i >= 0; i--) empty[i] = -1; + + var data = { + labels: empty, + datasets: [ + { + label: "My First dataset", + fillColor: "rgba(220,220,220,1)", + strokeColor: "rgba(220,220,220,1)", + highlightFill: "rgba(220,220,220,1)", + data: empty + }, + ]}; + + var options = { + showScale: false, + scaleShowLabels: false, + showTooltips: false, + animation: false, + scaleBeginAtZero : true, + scaleShowGridLines : false, + scaleShowHorizontalLines: true, + scaleShowVerticalLines: true, + barShowStroke : false, + barStrokeWidth : 0, + barValueSpacing : 0, + barDatasetSpacing : 0, + responsive: false, + scaleBackdropPaddingY : 10, + scaleOverride: true, + scaleStartValue: 0, + scaleStepWidth: 1, + scaleSteps: 60 + } + + this.fpsGraph = new Chart(ctxFps).Bar(data, options); + this.frameCounter = 0; + + var self = this; + + setInterval(function(){ + self.fpsGraph.addData( [self.frameCounter], "" ); + var color; + var alpha = 0.8; + + if (self.frameCounter >= 50) { + color = "rgba(136, 209, 018, " + alpha + ")"; + } else if (self.frameCounter > 25) { + color = "rgba(204, 114, 018, " + alpha + ")"; + } else { + color = "rgba(224, 018, 018, " + 1 + ")"; + } + + self.fpsGraph.datasets[0].bars[self.fpsGraph.datasets[0].bars.length-1].fillColor = color; + self.fpsGraph.removeData(); + self.fpsGraph.update(); + self.frameCounter = 0; + }, 1000); + } + + GraphManager.prototype.fpsStep = function() { + this.frameCounter++; + } + + return GraphManager; + +}); \ No newline at end of file diff --git a/app/Game/Client/View/Pixi/Layer.js b/app/Game/Client/View/Pixi/Layer.js index f9c9d45..5daa51d 100644 --- a/app/Game/Client/View/Pixi/Layer.js +++ b/app/Game/Client/View/Pixi/Layer.js @@ -3,9 +3,10 @@ define([ "Lib/Vendor/Pixi", "Game/Client/View/Pixi/ColorRangeReplaceFilter", "Game/Config/Settings", + "Lib/Utilities/ColorConverter" ], -function (Parent, PIXI, ColorRangeReplaceFilter, Settings) { +function (Parent, PIXI, ColorRangeReplaceFilter, Settings, ColorConverter) { "use strict"; @@ -22,6 +23,39 @@ function (Parent, PIXI, ColorRangeReplaceFilter, Settings) { this.container.x = 0; this.container.y = 0; this.static = false; + + if (Settings.SHOW_LAYER_INFO) { + + var self = this; + var g = new PIXI.Graphics(); + var converter = new ColorConverter(); + var c = converter.getColorByName(name); + var fontSize = 12; + var textOptions = { + font: "normal " + fontSize + "px 'Joystix'", + fill: "#" + c.toString(16), + }; + + var t = new PIXI.Text(name, textOptions); + + var y = 0; + switch (name) { + case "ghost": y++; + case "item": y++; + case "tile": y++; + case "spawn": y=y; + } + + t.position = new PIXI.Point(0, fontSize * y); + + g.lineStyle (1, c, 1); + g.drawRect (0, 0, 100 + y, 100 + y); + + setTimeout(function(){ + self.container.addChild(t); + self.container.addChild(g); + }, 500); + } } Layer.prototype = Object.create(Parent.prototype); @@ -166,6 +200,7 @@ function (Parent, PIXI, ColorRangeReplaceFilter, Settings) { Layer.prototype.render = function(centerPosition, zoom) { this.setPosition(centerPosition); + this.setZoom(zoom); // Zoom @@ -174,8 +209,37 @@ function (Parent, PIXI, ColorRangeReplaceFilter, Settings) { this.container.scale.x = this.zoom.current; this.container.scale.y = this.container.scale.x; + + /* + + // we would need another zoom state, + // to separate fixed zooming (by window size) + // and user zoom by +/-/0 keys + + // this snippet would zoom the layers by its parallax + // so further away layers would not zoom as much. + + var zoomParallax = this.parallaxSpeed == 0 + ? 1 + : this.parallaxSpeed < 0 + ? (1 + this.parallaxSpeed) + : this.parallaxSpeed + 1000; + + var newZoomTarget = 1 + Math.log(this.zoom.target+2) * (zoomParallax) + console.log(newZoomTarget) + + this.container.scale.x = newZoomTarget; + this.container.scale.y = newZoomTarget; + + // Later, this would need to be added as well: + this.container.x *= newZoomTarget; + this.container.y *= newZoomTarget; + */ + + // Position - if (!this.static) { + + /* var posXStep = (this.position.target.x - this.position.current.x) * Settings.CAMERA_GLIDE / 100; this.position.current.x += posXStep; this.container.x = this.position.current.x + (this.position.current.x * this.parallaxSpeed); @@ -183,7 +247,41 @@ function (Parent, PIXI, ColorRangeReplaceFilter, Settings) { var posYStep = (this.position.target.y - this.position.current.y) * Settings.CAMERA_GLIDE / 100; this.position.current.y += posYStep; this.container.y = this.position.current.y + (this.position.current.y * this.parallaxSpeed); - } + */ + + if (!this.static) { + var levelSize = { + x: 600, + y: 400 + } + + var posXStep = (this.position.target.x - this.position.current.x) * Settings.CAMERA_GLIDE / 100; + this.position.current.x += posXStep; + + var posYStep = (this.position.target.y - this.position.current.y) * Settings.CAMERA_GLIDE / 100; + this.position.current.y += posYStep; + + this.container.x = this.position.current.x + levelSize.x / 2 - (-this.parallaxSpeed) * (this.position.current.x + levelSize.x / 2); + this.container.y = this.position.current.y + levelSize.y / 2 - (-this.parallaxSpeed) * (this.position.current.y + levelSize.y / 2); + + if (this.name == "spawn" + || this.name == "tile" + || this.name == "item" + || this.name == "ghost" + || this.name == "swiper") { + this.container.x = this.position.current.x; + this.container.y = this.position.current.y; + } + + this.container.x *= this.zoom.current; + this.container.y *= this.zoom.current; + + this.container.x += Settings.STAGE_WIDTH / 2; + this.container.y += Settings.STAGE_HEIGHT / 2; + } + + + }; return Layer; diff --git a/app/Game/Client/View/Pixi/Layers/Swiper.js b/app/Game/Client/View/Pixi/Layers/Swiper.js index 4421fea..28344ff 100644 --- a/app/Game/Client/View/Pixi/Layers/Swiper.js +++ b/app/Game/Client/View/Pixi/Layers/Swiper.js @@ -27,8 +27,8 @@ function (Parent, PIXI, Nc, Settings) { Swiper.prototype.swipe = function(x, y) { var offset = { - x: Settings.STAGE_WIDTH / 2, - y: Settings.STAGE_HEIGHT / 2 + x: Settings.STAGE_WIDTH / 2 / this.zoom.current, + y: Settings.STAGE_HEIGHT / 2 / this.zoom.current, } this.sprite.moveTo(offset.x + this.last.x, offset.y + this.last.y); diff --git a/app/Game/Client/View/Pixi/View.js b/app/Game/Client/View/Pixi/View.js index 935f50d..310026a 100755 --- a/app/Game/Client/View/Pixi/View.js +++ b/app/Game/Client/View/Pixi/View.js @@ -8,10 +8,11 @@ define([ "Game/Client/View/Pixi/GameStats", "Game/Client/View/LayerManager", "Game/Client/View/Pixi/Layers/Ghost", - "Game/Client/View/Pixi/Layers/Swiper" + "Game/Client/View/Pixi/Layers/Swiper", + "Game/Client/PointerLockManager" ], -function (Parent, DomController, PIXI, Settings, Nc, Exception, GameStats, LayerManager, Ghost, Swiper) { +function (Parent, DomController, PIXI, Settings, Nc, Exception, GameStats, LayerManager, Ghost, Swiper, PointerLockManager) { "use strict"; @@ -23,12 +24,16 @@ function (Parent, DomController, PIXI, Settings, Nc, Exception, GameStats, Layer this.stage = null; this.container = null; this.infoContainer = null; - this.infoFilters = []; this.loader = null; this.currentZoom = Settings.ZOOM_DEFAULT; + this.clickToEnable = null; this.init(); + this.ncTokens = this.ncTokens.concat([ + Nc.on(Nc.ns.client.pointerLock.change, this.onPointerLockChange, this) + ]); + PIXI.scaleModes.DEFAULT = PIXI.scaleModes.NEAREST; } @@ -66,7 +71,9 @@ function (Parent, DomController, PIXI, Settings, Nc, Exception, GameStats, Layer this.initCanvas(this.renderer.view); - // Tab Overlay (not using layer manager) + this.initPointerLockView(); + + // Tab Overlay (not using layer manager, cause of filters) this.gameStats = new GameStats(this.container); this.stage.addChild(this.gameStats.getInfoContainer()); @@ -75,6 +82,8 @@ function (Parent, DomController, PIXI, Settings, Nc, Exception, GameStats, Layer this.swiperLayer = new Swiper(); this.layerManager.insert(this.swiperLayer, false); + + this.render(); } PixiView.prototype.render = function () { @@ -85,32 +94,74 @@ function (Parent, DomController, PIXI, Settings, Nc, Exception, GameStats, Layer this.renderer.render(this.stage); } + PixiView.prototype.initPointerLockView = function() { + + var blurFilter = new PIXI.BlurFilter(); + blurFilter.blurX = 42 * this.currentZoom; + blurFilter.blurY = 42 * this.currentZoom; + + var pixelFilter = new PIXI.PixelateFilter(); + pixelFilter.pixelSize = 10 * this.currentZoom ; + + var grayFilter = new PIXI.GrayFilter(); + grayFilter.gray = 0.99; + this.pointerLockFilters = [pixelFilter, grayFilter]; + + this.clickToEnable = new PIXI.Text("Click to start playing."); + this.clickToEnable.visible = false; + this.stage.addChild(this.clickToEnable) + }; + + PixiView.prototype.onPointerLockChange = function(isLocked, options) { + if(isLocked) { + this.container.filters = null; + this.clickToEnable.visible = false; + this.onZoomReset(); + } else { + + if(!options || options.start !== true) { + this.clickToEnable.setText("Click to continue playing."); + } + + this.clickToEnable.setStyle({ + font: "normal " + (14 * this.currentZoom) + "px 'Joystix'", + fill: "#ffffff", + stroke: "rgba(0,0,0,0.8)", + strokeThickness: 6 * this.currentZoom + }); + + this.container.filters = this.pointerLockFilters; + this.pointerLockFilters.forEach(function(filter) { filter.dirty = true; }); + + this.clickToEnable.position = new PIXI.Point(Settings.STAGE_WIDTH / 2 - this.clickToEnable.width / 2, Settings.STAGE_HEIGHT / 2 - this.clickToEnable.height / 2) + this.clickToEnable.visible = true; + + this.onZoomReset(); + this.currentZoom *= 0.9; + } + }; + PixiView.prototype.calculateCenterPosition = function() { var target = this.me.getHeadPosition(); - var centerPosition = {x: target.x, y: target.y}; - centerPosition.x *= -Settings.RATIO * this.currentZoom; - centerPosition.y *= -Settings.RATIO * this.currentZoom; - centerPosition.x += Settings.STAGE_WIDTH / 2; - centerPosition.y += Settings.STAGE_HEIGHT / 2; + var centerPosition = {x: target.x, y: target.y}; + centerPosition.x *= Settings.RATIO * -1; + centerPosition.y *= Settings.RATIO * -1; var lookAt = this.me.getLookAt(); - centerPosition.x -= lookAt.x * Settings.STAGE_WIDTH / 4; - centerPosition.y += lookAt.y * Settings.STAGE_HEIGHT / 4; + centerPosition.x -= lookAt.x * 600 / 4; + centerPosition.y += lookAt.y * 400 / 4; return centerPosition; }; - PixiView.prototype.onFullscreenChange = function(isFullScreen) { - Parent.prototype.onFullscreenChange.call(this, isFullScreen); + PixiView.prototype.onDisplaySizeChange = function(isFullScreen) { + Parent.prototype.onDisplaySizeChange.call(this, isFullScreen); - if(isFullScreen) { - this.renderer.resize(window.innerWidth, window.innerHeight); - this.currentZoom = window.innerWidth / 600; - } else { - this.renderer.resize(600, 400); - this.currentZoom = 1; - } + this.renderer.resize(window.innerWidth, window.innerHeight); + this.currentZoom = window.innerWidth / 600; + + PointerLockManager.update(null, {}); // only to reposition clickToEnable text }; PixiView.prototype.initLoader = function() { @@ -150,20 +201,19 @@ function (Parent, DomController, PIXI, Settings, Nc, Exception, GameStats, Layer }; PixiView.prototype.onZoomIn = function() { - console.log("onZoomIn") if(this.currentZoom + Settings.ZOOM_FACTOR <= Settings.ZOOM_MAX) { this.currentZoom += Settings.ZOOM_FACTOR; } }; PixiView.prototype.onZoomOut = function() { - if(this.currentZoom - Settings.ZOOM_FACTOR > 0) { + //if(this.currentZoom - Settings.ZOOM_FACTOR > window.innerWidth / 600) { this.currentZoom -= Settings.ZOOM_FACTOR; - } - }; + //} + }; PixiView.prototype.onZoomReset = function() { - this.currentZoom = Settings.ZOOM_DEFAULT; + this.currentZoom = window.innerWidth / 600; }; PixiView.prototype.getTexturesFromFrame = function(textureNames) { diff --git a/app/Game/Config/Settings.js b/app/Game/Config/Settings.js index 0476ad0..747e8c2 100755 --- a/app/Game/Config/Settings.js +++ b/app/Game/Config/Settings.js @@ -31,6 +31,7 @@ define(function() { CAMERA_GLIDE: 12, // % of the way per frame VIEW_CONTROLLER: 0 ? 'Three' : 'Pixi', ARROW_GLIDE: 30, // % of the way per frame + SHOW_LAYER_INFO: false, // GAME PLAY WALK_SPEED: 4, diff --git a/app/Lib/Utilities/Client/Extensions.js b/app/Lib/Utilities/Client/Extensions.js index 1f4e7d0..07e65ab 100644 --- a/app/Lib/Utilities/Client/Extensions.js +++ b/app/Lib/Utilities/Client/Extensions.js @@ -1,9 +1,8 @@ define([ - "Lib/Utilities/Core/Extensions", - "Lib/Vendor/Pixi" + "Lib/Utilities/Core/Extensions" ], -function (Parent, PIXI) { +function (Parent) { "use strict"; }); \ No newline at end of file diff --git a/app/Lib/Utilities/ColorConverter.js b/app/Lib/Utilities/ColorConverter.js index 0c9d5d1..6332a74 100644 --- a/app/Lib/Utilities/ColorConverter.js +++ b/app/Lib/Utilities/ColorConverter.js @@ -31,11 +31,11 @@ function (CryptoJS) { 0x739137, 0x46824f, 0x19b0b4, - 0x0c1eb1, + 0x1c1eb1, 0xccb206, 0x433e20, 0x201a13, - 0x045396, + 0x145396, 0x313d08, 0xb7a345, 0xdc168a, diff --git a/app/Lib/Utilities/NotificationCenter.js b/app/Lib/Utilities/NotificationCenter.js index ebe688f..9b16fff 100755 --- a/app/Lib/Utilities/NotificationCenter.js +++ b/app/Lib/Utilities/NotificationCenter.js @@ -26,6 +26,10 @@ function (Exception) { var i = 0; this.ns = { client: { + pointerLock: { + request: null, + change: null + }, view: { layer: { createAndInsert: null @@ -53,7 +57,7 @@ function (Exception) { preloadBar: { update: null }, - fullscreen: { + display: { change: null }, debugMode: { diff --git a/app/Lib/Utilities/QuerySelector.js b/app/Lib/Utilities/QuerySelector.js new file mode 100644 index 0000000..96cabb1 --- /dev/null +++ b/app/Lib/Utilities/QuerySelector.js @@ -0,0 +1,23 @@ +define([ +], + +function () { + + "use strict"; + + function QuerySelector() { + if (!document) { + throw new Error("Using QuerySelector, but window.document is not defined."); + } + } + + QuerySelector.prototype.$ = function(selector) { + return document.querySelector(selector); + } + + QuerySelector.prototype.$$ = function(selector) { + return document.querySelectorAll(selector); + } + + return new QuerySelector(); +}); \ No newline at end of file diff --git a/app/Lib/Vendor/Chart.js b/app/Lib/Vendor/Chart.js new file mode 100644 index 0000000..1d8d155 --- /dev/null +++ b/app/Lib/Vendor/Chart.js @@ -0,0 +1,3 @@ +define(["chart"], function (Chart) { + return Chart; +}); \ No newline at end of file diff --git a/app/Menu/Menu.js b/app/Menu/Menu.js index 3dc8c54..e0c573a 100644 --- a/app/Menu/Menu.js +++ b/app/Menu/Menu.js @@ -1,9 +1,11 @@ define([ "Lib/Utilities/ColorConverter", - "Lib/Utilities/Exception" + "Lib/Utilities/Exception", + "Game/Client/PointerLockManager", + "Lib/Utilities/QuerySelector" ], -function (ColorConverter, Exception) { +function (ColorConverter, Exception, PointerLockManager, Qs) { "use strict"; @@ -20,28 +22,28 @@ function (ColorConverter, Exception) { if(localStorage["player"]) { var player = JSON.parse(localStorage["player"]); if(player.nickname) { - $("#nick").value = player.nickname; + Qs.$("#nick").value = player.nickname; } } if(localStorage["customname"]) { - $("#customname").value = localStorage["customname"]; + Qs.$("#customname").value = localStorage["customname"]; } - $("#refresh").onclick = refresh; + Qs.$("#refresh").onclick = refresh; refresh(); populateMaps(); this.channelDestructionTimeout = null; this.refreshInterval = setInterval(refresh, 5000); - $("#createbutton").onclick = function() { + Qs.$("#createbutton").onclick = function() { show('#createform'); return false; }; - $("#quickstartbutton").onclick = quickstart; + Qs.$("#quickstartbutton").onclick = quickstart; - var cancelButtons = $$(".cancel"); + var cancelButtons = Qs.$$(".cancel"); for (var i = 0; i < cancelButtons.length; i++) { cancelButtons[i].onclick = function() { show('#listform'); @@ -50,13 +52,13 @@ function (ColorConverter, Exception) { }; this.colorConverter = new ColorConverter(); - var c = $("#nick"); + var c = Qs.$("#nick"); c.onchange = c.onkeyup = c.onblur = c.onclick = this.updatePrimaryColor.bind(this); this.updatePrimaryColor({target:c}); }; Menu.prototype.updatePrimaryColor = function(e) { - $("#primarycolor").style.backgroundColor = "#" + this.colorConverter.getColorByName(e.target.value).toString(16); + Qs.$("#primarycolor").style.backgroundColor = "#" + this.colorConverter.getColorByName(e.target.value).toString(16); }; Menu.prototype.onRun = function(channelName, nickname) { @@ -65,7 +67,7 @@ function (ColorConverter, Exception) { window.onhashchange = function() { if(window.location.hash) { - if($("#game").style.display == "block") { + if(Qs.$("#game").style.display == "block") { window.location.reload(); } refresh(function(list) { @@ -88,14 +90,6 @@ function (ColorConverter, Exception) { window.onload = window.onhashchange; - function $(selector) { - return document.querySelector(selector); - } - - function $$(selector) { - return document.querySelectorAll(selector); - } - var lastRefreshResponse; function refresh(callback) { @@ -131,7 +125,7 @@ function (ColorConverter, Exception) { errorCallback(xhr.status, xhr.responseText); } else { console.error("Ajax error: " + xhr.status + " " + xhr.responseText) - $("#list").innerHTML = ""; + Qs.$("#list").innerHTML = ""; document.body.className = "offline"; } } @@ -161,7 +155,7 @@ function (ColorConverter, Exception) { html += "No channels found."; } - $("#list").innerHTML = html; + Qs.$("#list").innerHTML = html; } function populateMaps() { @@ -176,15 +170,15 @@ function (ColorConverter, Exception) { html += ""; }; - $("#maps").innerHTML = html; + Qs.$("#maps").innerHTML = html; }, function(status, responseText) { console.error("getMaps error:", status, responseText); }); } - $("form#listform").onsubmit = function(e) { + Qs.$("form#listform").onsubmit = function(e) { try { - var nickname = $("#nick").value; + var nickname = Qs.$("#nick").value; var channelName = getSelectedChannel(); join(nickname, channelName); } catch(e) { @@ -194,9 +188,9 @@ function (ColorConverter, Exception) { return false; } - $("form#createform").onsubmit = function(e) { + Qs.$("form#createform").onsubmit = function(e) { try { - var channelName = $("#customname").value; + var channelName = Qs.$("#customname").value; create(channelName, onCreateSuccess); } catch(e) { console.error(e) @@ -205,10 +199,10 @@ function (ColorConverter, Exception) { return false; } - $("form#customjoinform").onsubmit = function(e) { + Qs.$("form#customjoinform").onsubmit = function(e) { try { - var nickname = $("#nick").value; - var channelName = $("#customname").value; + var nickname = Qs.$("#nick").value; + var channelName = Qs.$("#customname").value; join(nickname, channelName); } catch(e) { console.error(e); @@ -223,29 +217,29 @@ function (ColorConverter, Exception) { } function showCustomJoinForm() { - $("#customname").value = unescape(window.location.hash.substr(1)); - $("#link").value = window.location.href; + Qs.$("#customname").value = unescape(window.location.hash.substr(1)); + Qs.$("#link").value = window.location.href; show("#customjoinform"); } function show(id) { - $("#createform").style.display = "none"; - $("#listform").style.display = "none"; - $("#customjoinform").style.display = "none"; - $("#game").style.display = "none"; + Qs.$("#createform").style.display = "none"; + Qs.$("#listform").style.display = "none"; + Qs.$("#customjoinform").style.display = "none"; + Qs.$("#game").style.display = "none"; if(id != "#customjoinform") { history.pushState("", document.title, window.location.pathname); } - $(id).style.display = "block"; + Qs.$(id).style.display = "block"; } function quickstart() { refresh(function(list){ var defaultChannelName = quickstartChannelName; history.pushState("", document.title, window.location.pathname + "#" + defaultChannelName); - var nickname = $("#nick").value; + var nickname = Qs.$("#nick").value; if(!nickname) { nickname = "Guest" + (Math.floor(Math.random() * 899) + 100) @@ -272,7 +266,7 @@ function (ColorConverter, Exception) { alert("Your channel has timed out."); window.location.href = "/"; } else { - $("#timeout").innerHTML = " within " + formatDate(diff) + " minutes"; + Qs.$("#timeout").innerHTML = " within " + formatDate(diff) + " minutes"; } }, 1000); } @@ -357,8 +351,8 @@ function (ColorConverter, Exception) { }); //window.location.href = "/game.html"; - $("#menu").style.display = "none"; - $("#game").style.display = "block"; + Qs.$("#menu").style.display = "none"; + Qs.$("#game").style.display = "block"; instance.onRun(channelName, nickname); // Dumm und dümmer if(instance.refreshInterval) { @@ -369,7 +363,7 @@ function (ColorConverter, Exception) { clearInterval(instance.channelDestructionTimeout); } - requestPointerLock(); + PointerLockManager.request(); } } @@ -383,7 +377,7 @@ function (ColorConverter, Exception) { levelUids: maps, maxUsers: 10, minUsers: 2, - scoreLimit: parseInt($("#scoreLimit").value, 10) + scoreLimit: parseInt(Qs.$("#scoreLimit").value, 10) } localStorage["customname"] = channelName; @@ -399,18 +393,9 @@ function (ColorConverter, Exception) { } } - function requestPointerLock() { - - var c = $("#canvas"); - c.requestPointerLock = c.requestPointerLock || - c.mozRequestPointerLock || - c.webkitRequestPointerLock; - - // Ask the browser to lock the pointer) - c.requestPointerLock(); - } - - $("#canvas").onclick = requestPointerLock; + Qs.$("#canvas").onclick = function(){ + PointerLockManager.request(); + }; return Menu; diff --git a/client.js b/client.js index 84452ab..e9aa73a 100755 --- a/client.js +++ b/client.js @@ -8,6 +8,7 @@ requirejs.config({ waitSeconds: 0, paths: { screenfull: "/screenfull", + chart: "/chart", socketio: "/socket.io/socket.io" }, }); diff --git a/static/css/screen.css b/static/css/screen.css index f4e4598..31844a8 100644 --- a/static/css/screen.css +++ b/static/css/screen.css @@ -31,7 +31,12 @@ body { list-style-type: none; margin: 0; padding: 0; - background: #333; + background: rgba(0, 0, 0, 0.5); + position: absolute; + z-index: 1; + width: 100%; + /*display: none;*/ + } #menuBar li { display: inline-block; @@ -127,12 +132,18 @@ a { height: 100%; } -canvas { - position: absolute; +#canvasContainer canvas { + position: absolute;/* top: 50%; left: 50%; margin-top: -200px; - margin-left: -300px; + margin-left: -300px;*/ +} + +#graph-fps { + background: rgba(0,0,0,0.3); + border: 1px solid rgba(0,0,0,0.5); + padding: 2px; } :-webkit-full-screen { diff --git a/static/html/index.html b/static/html/index.html index f1d3b36..e09f6ad 100644 --- a/static/html/index.html +++ b/static/html/index.html @@ -75,7 +75,7 @@
- +