Added PointerLockManagement, Fixed layer positioning, added fps chart. fixes #120, fixes #121, fixes #123

This commit is contained in:
logsol 2015-02-27 18:44:30 +01:00
parent 8d0989844c
commit 60eae208a2
23 changed files with 458 additions and 109 deletions

View file

@ -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);
};

View file

@ -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 = [];

View file

@ -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);
}

View file

@ -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

View file

@ -90,6 +90,8 @@ function (ProtocolHelper, GameController, User, Nc, Settings, DomController) {
}
}
this.gameController.onLevelLoaded();
this.sendGameCommand("clientReady");
};

View file

@ -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();
});

View file

@ -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) {

View file

@ -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 () {

View file

@ -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;
});

View file

@ -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;

View file

@ -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);

View file

@ -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) {

View file

@ -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,