diff --git a/app/Game/Client/Networker.js b/app/Game/Client/Networker.js
index c45448d..304e9f2 100755
--- a/app/Game/Client/Networker.js
+++ b/app/Game/Client/Networker.js
@@ -9,7 +9,9 @@ define([
function (ProtocolHelper, GameController, User, Nc, Settings, DomController) {
- function Networker (socketLink) {
+ function Networker (socketLink, channelName, nickname) {
+ this.channelName = channelName;
+ this.nickname = nickname;
this.socketLink = socketLink;
this.gameController = null;
this.users = {};
@@ -38,14 +40,13 @@ function (ProtocolHelper, GameController, User, Nc, Settings, DomController) {
Networker.prototype.onConnect = function () {
console.log('connected.')
- var channel = JSON.parse(localStorage["channel"]);
- var player = JSON.parse(localStorage["player"]);
- if(channel.name) {
+ if(this.channelName) {
var options = {
- channelName: channel.name,
- nickname: player.nickname
+ channelName: this.channelName,
+ nickname: this.nickname
}
this.sendCommand('join', options);
+ DomController.setConnected(true);
} else {
window.location.href = "/";
}
@@ -55,7 +56,7 @@ function (ProtocolHelper, GameController, User, Nc, Settings, DomController) {
//if(this.gameController) this.gameController.destruct();
//this.gameController = null;
console.log('disconnected. game destroyed. no auto-reconnect');
- document.body.style.backgroundColor = '#aaaaaa';
+ DomController.setConnected(false);
}
Networker.prototype.onJoinSuccess = function (options) {
diff --git a/app/Game/Client/View/DomController.js b/app/Game/Client/View/DomController.js
index 89fb78e..2a9cd9c 100755
--- a/app/Game/Client/View/DomController.js
+++ b/app/Game/Client/View/DomController.js
@@ -123,6 +123,14 @@ function (Settings, Nc, Stats, Screenfull) {
this.health.innerHTML = "Health: " + parseInt(health, 10);
};
+ DomController.prototype.setConnected = function(connected) {
+ if(connected) {
+ document.body.style.backgroundColor = '';
+ } else {
+ document.body.style.backgroundColor = '#aaaaaa';
+ }
+ };
+
return new DomController();
diff --git a/app/Game/Config/Settings.js b/app/Game/Config/Settings.js
index d856841..62a2525 100755
--- a/app/Game/Config/Settings.js
+++ b/app/Game/Config/Settings.js
@@ -62,12 +62,12 @@ define(function() {
// NETWORKING
NETWORK_UPDATE_INTERVAL: 70,
- CHANNEL_DESTRUCTION_TIME: 30,
NETWORK_LOG_INCOMING: false,
NETWORK_LOG_OUTGOING: false,
NETWORK_LOG_FILTER: ['ping', 'pong', 'worldUpdate', 'lookAt'],
// CHANNEL
+ CHANNEL_DESTRUCTION_TIME: 5 * 60,
CHANNEL_END_ROUND_TIME: 4, //10,
CHANNEL_DEFAULT_MAX_USERS: 40,
CHANNEL_DEFAULT_SCORE_LIMIT: 10,
diff --git a/client.js b/client.js
index 6bc6999..416ce4b 100755
--- a/client.js
+++ b/client.js
@@ -6,7 +6,8 @@ requirejs.config({
waitSeconds: 0
});
-var inspector = {};
+if(!Chuck) var Chuck = {};
+Chuck.inspector = {};
requirejs([
"Game/Client/Networker",
@@ -18,18 +19,20 @@ requirejs([
function (Networker, SocketIO, Settings, Exception, PIXI) {
- var options = {
- "reconnect": false,
- "reconnection delay": 500,
- "max reconnection attempts": 10,
- "transports": [
- "websocket",
- "flashsocket"
- ]
- };
- var socket = SocketIO.connect("/", options);
- var networker = new Networker(socket);
- inspector.networker = networker;
- inspector.settings = Settings;
- inspector.resetLevel = function() { networker.sendGameCommand("resetLevel"); }
+ Chuck.run = function(channelName, nickname) {
+ var options = {
+ "reconnect": false,
+ "reconnection delay": 500,
+ "max reconnection attempts": 10,
+ "transports": [
+ "websocket",
+ "flashsocket"
+ ]
+ };
+ var socket = SocketIO.connect("/", options);
+ var networker = new Networker(socket, channelName, nickname);
+ Chuck.inspector.networker = networker;
+ Chuck.inspector.settings = Settings;
+ Chuck.inspector.resetLevel = function() { networker.sendGameCommand("resetLevel"); }
+ }
});
\ No newline at end of file
diff --git a/static/css/screen.css b/static/css/screen.css
new file mode 100644
index 0000000..bd8d316
--- /dev/null
+++ b/static/css/screen.css
@@ -0,0 +1,108 @@
+html, body {
+ width: 100%;
+ height: 100%;
+}
+
+body {
+ background: #222;
+ color: #ccc;
+ font-family: "Lucida Grande", sans-serif;
+ margin: 0;
+ padding: 0;
+ display: table;
+}
+
+::selection {
+ background: #607950; /* Safari */
+ }
+::-moz-selection {
+ background: #607950; /* Firefox */
+}
+
+input, button {
+ background: black;
+ color: #ccc;
+ border: 0;
+ padding: 0.3em 0.6em;
+ font-size: 1em;
+}
+
+#createform, #customjoinform, #game {
+ display: none;
+}
+
+article#menu {
+ margin: 4em auto;
+ background: #1a1a1a;
+ padding: 2em;
+ max-width: 30em;
+}
+
+table, th, td {
+ border: 1px solid #777;
+ border-collapse: collapse;
+}
+
+th, td {
+ padding: 0.5em 1em;
+}
+
+ul {
+ list-style-type: none;
+ padding-left: 0;
+}
+
+#link {
+ width: 100%;
+}
+
+.offline {
+ background: #ccc;
+}
+
+tr:hover td {
+ background: #222;
+}
+
+a {
+ color: #ccc;
+}
+
+
+#canvasContainer {
+ /*
+ text-align: center;
+ display: table-cell;
+ vertical-align: middle;
+ */
+ height: 100%;
+}
+
+canvas {
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ margin-top: -200px;
+ margin-left: -300px;
+}
+
+:-webkit-full-screen {
+ top: 0;
+ left: 0;
+ margin: 0;
+ padding: 0;
+}
+
+#devtools {
+ font-family: monospace;
+ position: absolute;
+ right: 0;
+ top: 0;
+ padding: 10px;
+ background: #222;
+}
+
+#devtools p {
+ padding: 5px 0 0 0;
+ margin: 0;
+}
\ No newline at end of file
diff --git a/static/html/game.html b/static/html/game.html
deleted file mode 100755
index 29ac5eb..0000000
--- a/static/html/game.html
+++ /dev/null
@@ -1,63 +0,0 @@
-
-
-
-
- Chuck
-
-
-
-
-
-
-
-
-
diff --git a/static/html/index.html b/static/html/index.html
index 6b7399a..63eaf6f 100644
--- a/static/html/index.html
+++ b/static/html/index.html
@@ -2,20 +2,10 @@
Chuck Lobby
-
+
-
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/static/js/menu.js b/static/js/menu.js
index 600a41b..7edfd30 100644
--- a/static/js/menu.js
+++ b/static/js/menu.js
@@ -1,276 +1,309 @@
-function $(selector) {
- return document.querySelector(selector);
-}
+if(!Chuck) var Chuck = {};
+(function(Chuck) {
-function $$(selector) {
- return document.querySelectorAll(selector);
-}
-
-if(localStorage["player"]) {
- var player = JSON.parse(localStorage["player"]);
- if(player.nickname) {
- $("#nick").value = player.nickname;
+ window.onhashchange = function() {
+ if(window.location.hash) {
+ refresh(function(list) {
+ var channelName = unescape(window.location.hash.substr(1));
+ if(channelExists(list, channelName)) {
+ showCustomJoinForm()
+ } else {
+ alert("Channel \"" + channelName + "\" does not exist (anymore).")
+ window.location.href = "/";
+ }
+ });
+ }
}
-}
-if(localStorage["customname"]) {
- $("#customname").value = localStorage["customname"];
-}
+ window.onload = window.onhashchange;
-var lastRefreshResponse;
-function refresh(callback) {
+ function $(selector) {
+ return document.querySelector(selector);
+ }
+
+ function $$(selector) {
+ return document.querySelectorAll(selector);
+ }
+
+ if(localStorage["player"]) {
+ var player = JSON.parse(localStorage["player"]);
+ if(player.nickname) {
+ $("#nick").value = player.nickname;
+ }
+ }
+
+ if(localStorage["customname"]) {
+ $("#customname").value = localStorage["customname"];
+ }
+
+ var lastRefreshResponse;
+ function refresh(callback) {
+ try {
+ var xhr = new XMLHttpRequest();
+ xhr.onreadystatechange = function() {
+ if(xhr.readyState == 4) {
+ if(xhr.status == 200) {
+
+ var response = xhr.responseText;
+ if(response != lastRefreshResponse) {
+ lastRefreshResponse = response;
+ populate(JSON.parse(response).success);
+ }
+ document.body.className = "";
+
+ if(typeof callback == 'function') {
+ callback(JSON.parse(response).success)
+ }
+ } else {
+ console.error("Ajax error: " + xhr.status + " " + xhr.responseText)
+ $("#list").innerHTML = "";
+ document.body.className = "offline";
+ }
+ }
+ }
+ xhr.open("POST", "/api", true);
+ xhr.send(JSON.stringify({command:"getChannels"}));
+ } catch(e) {
+ console.error(e)
+ }
+ return false;
+ }
+
+ function populate(list) {
+ var html = "";
+ if(list.length > 0) {
+ for (var i = 0; i < list.length; i++) {
+ var channel = list[i];
+ html += "| ";
+ html += "";
+ html += channel.name
+ html += " | death match |
";
+ };
+ } else {
+ html += "| No channels found. |
";
+ }
+
+ $("#list").innerHTML = html;
+ }
+
+ $("form#listform").onsubmit = function(e) {
try {
- var xhr = new XMLHttpRequest();
- xhr.onreadystatechange = function() {
- if(xhr.readyState == 4) {
- if(xhr.status == 200) {
+ var nickname = $("#nick").value;
+ var channelName = getSelectedChannel();
+ join(nickname, channelName);
+ } catch(e) {
+ console.error(e)
+ }
- var response = xhr.responseText;
- if(response != lastRefreshResponse) {
- lastRefreshResponse = response;
- populate(JSON.parse(response).success);
- }
- document.body.className = "";
-
- if(typeof callback == 'function') {
- callback(JSON.parse(response).success)
- }
- } else {
- console.error("Ajax error: " + xhr.status + " " + xhr.responseText)
- $("#list").innerHTML = "";
- document.body.className = "offline";
- }
- }
- }
- xhr.open("POST", "/api", true);
- xhr.send(JSON.stringify({command:"getChannels"}));
- } catch(e) {
- console.error(e)
+ return false;
}
- return false;
-}
-function populate(list) {
- var html = "";
- if(list.length > 0) {
+ $("form#createform").onsubmit = function(e) {
+ try {
+ var channelName = $("#customname").value;
+ create(channelName, onCreateSuccess);
+ } catch(e) {
+ console.error(e)
+ }
+
+ return false;
+ }
+
+ $("form#customjoinform").onsubmit = function(e) {
+ try {
+ var nickname = $("#nick").value;
+ var channelName = $("#customname").value;
+ join(nickname, channelName);
+ } catch(e) {
+ console.error(e);
+ }
+
+ return false;
+ }
+
+ function onCreateSuccess(options) {
+ window.location.hash = options.channelName;
+ startTimer(options.timeout);
+ }
+
+ function showCustomJoinForm() {
+ $("#customname").value = unescape(window.location.hash.substr(1));
+ $("#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";
+
+ if(id != "#customjoinform") {
+ history.pushState("", document.title, window.location.pathname);
+ }
+
+ $(id).style.display = "block";
+ }
+
+ function quickstart() {
+ refresh(function(list){
+ var defaultChannelName = "Dungeon";
+ var nickname = $("#nick").value;
+
+ if(!nickname) {
+ nickname = "Guest" + (Math.floor(Math.random() * 899) + 100)
+ }
+
+ if(!channelExists(list, defaultChannelName)) {
+ create(defaultChannelName, function() {
+ join(nickname, defaultChannelName); // only called on success
+ });
+ } else {
+ join(nickname, defaultChannelName);
+ }
+ });
+ }
+
+ function startTimer(seconds) {
+ var now = new Date();
+ var end = new Date(now.getTime() + seconds * 1000);
+ setInterval(function() {
+ now = new Date();
+ var diff = new Date(end.getTime() - now.getTime());
+ if(diff.getTime() < 0) {
+ alert("Your channel has timed out.");
+ window.location.href = "/";
+ } else {
+ $("#timeout").innerHTML = " within " + formatDate(diff) + " minutes";
+ }
+ }, 1000);
+ }
+
+ function formatDate(date) {
+ var minutes = date.getMinutes();
+ var seconds = date.getSeconds();
+ if(minutes < 10) minutes = "0" + minutes;
+ if(seconds < 10) seconds = "0" + seconds;
+
+ return minutes + ":" + seconds;
+ }
+
+ function channelExists(list, channelName) {
for (var i = 0; i < list.length; i++) {
var channel = list[i];
- html += " | |
";
- };
- } else {
- html += "| No channels found. |
";
- }
-
- $("#list").innerHTML = html;
-}
-
-$("form#listform").onsubmit = function(e) {
- try {
- var nickname = $("#nick").value;
- var channelName = getSelectedChannel();
- join(nickname, channelName);
- } catch(e) {
- console.error(e)
- }
-
- return false;
-}
-
-$("form#createform").onsubmit = function(e) {
- try {
- var channelName = $("#customname").value;
- create(channelName, onCreateSuccess);
- } catch(e) {
- console.error(e)
- }
-
- return false;
-}
-
-$("form#customjoinform").onsubmit = function(e) {
- try {
- var nickname = $("#nick").value;
- var channelName = $("#customname").value;
- join(nickname, channelName);
- } catch(e) {
- console.error(e);
- }
-
- return false;
-}
-
-function onCreateSuccess(options) {
- $("#customname").value = options.channelName;
- $("#link").value = window.location.href + options.link;
- show("#customjoinform");
- startTimer(options.timeout);
-}
-
-function show(id) {
- $("#createform").style.display = "none";
- $("#listform").style.display = "none";
- $("#customjoinform").style.display = "none";
-
- $(id).style.display = "block";
-}
-
-function quickstart() {
- refresh(function(list){
- var defaultChannelName = "Dungeon";
- var nickname = $("#nick").value;
-
- if(!nickname) {
- nickname = "Guest" + (Math.floor(Math.random() * 899) + 100)
+ if(channel.name == channelName) {
+ return true;
+ }
}
+ return false;
+ }
- if(!channelExists(list, defaultChannelName)) {
- create(defaultChannelName, function() {
- join(nickname, defaultChannelName); // only called on success
+ function validateForJoin(nickname, channelName) {
+ if(!nickname || nickname.length < 3) {
+ alert("Nickname too short")
+ return false;
+ }
+ if(!channelName) {
+ alert('No channel name provided');
+ return false;
+ }
+ return true;
+ }
+
+ function validateForCreate(channelName, maps) {
+ return true;
+ if(maps.length < 1) {
+ alert("Please choose at least one map.")
+ return false;
+ }
+
+ if(!channelName) {
+ alert("Please provide a channel name.")
+ return false;
+ }
+ return true;
+ }
+
+ function getSelectedMaps() {
+ var maps = [];
+ var checkboxes = document.querySelectorAll("form#createform input[name=maps]");
+ for (var i = 0; i < checkboxes.length; i++) {
+ var checkbox = checkboxes[i];
+ if(checkbox.checked) {
+ maps.push(checkbox.value);
+ }
+ };
+ return maps;
+ }
+
+ function getSelectedChannel() {
+ var name = null;
+ var radios = document.querySelectorAll("form#listform input[name=channel]");
+ for (var i = 0; i < radios.length; i++) {
+ var radio = radios[i];
+ if(radio.checked) {
+ name = radio.value;
+ break;
+ }
+ };
+ return name
+ }
+
+ function join(nickname, channelName) {
+
+ if(validateForJoin(nickname, channelName)) {
+ localStorage["player"] = JSON.stringify({
+ nickname: nickname
+ });
+ localStorage["channel"] = JSON.stringify({
+ name: channelName
});
- } else {
- join(nickname, defaultChannelName);
- }
- });
-}
-function startTimer(seconds) {
- var now = new Date();
- var end = new Date(now.getTime() + seconds * 1000);
- setInterval(function() {
- now = new Date();
- var diff = new Date(end.getTime() - now.getTime());
- if(diff.getTime() < 0) {
- alert("Your channel has timed out.");
- window.location.href = "/";
- } else {
- $("#timeout").innerHTML = " within " + formatDate(diff) + " minutes";
- }
- }, 1000);
-}
-
-function formatDate(date) {
- var minutes = date.getMinutes();
- var seconds = date.getSeconds();
- if(minutes < 10) minutes = "0" + minutes;
- if(seconds < 10) seconds = "0" + seconds;
-
- return minutes + ":" + seconds;
-}
-
-function channelExists(list, channelName) {
- for (var i = 0; i < list.length; i++) {
- var channel = list[i];
- if(channel.name == channelName) {
- return true;
+ //window.location.href = "/game.html";
+ $("#menu").style.display = "none";
+ $("#game").style.display = "block";
+ Chuck.run(channelName, nickname);
}
}
- return false;
-}
-function validateForJoin(nickname, channelName) {
- if(!nickname || nickname.length < 3) {
- alert("Nickname too short")
- return false;
- }
- if(!channelName) {
- alert('No channel name provided');
- return false;
- }
- return true;
-}
+ function create(channelName, callback) {
+ var maps = getSelectedMaps();
+
+ if(validateForCreate(channelName, maps)) {
-function validateForCreate(channelName, maps) {
- return true;
- if(maps.length < 1) {
- alert("Please choose at least one map.")
- return false;
- }
-
- if(!channelName) {
- alert("Please provide a channel name.")
- return false;
- }
- return true;
-}
+ var options = {
+ channelName: channelName,
+ levelUids: maps,
+ maxUsers: 10,
+ minUsers: 2,
+ scoreLimit: parseInt($("#scoreLimit").value, 10)
+ }
-function getSelectedMaps() {
- var maps = [];
- var checkboxes = document.querySelectorAll("form#createform input[name=maps]");
- for (var i = 0; i < checkboxes.length; i++) {
- var checkbox = checkboxes[i];
- if(checkbox.checked) {
- maps.push(checkbox.value);
+ localStorage["customname"] = channelName;
+
+ var xhr = new XMLHttpRequest();
+ xhr.onreadystatechange = function() {
+ if(xhr.readyState == 4) {
+ if(xhr.status == 200) {
+ if(typeof callback == 'function') {
+ callback(JSON.parse(xhr.responseText).success);
+ }
+ } else {
+ console.log(xhr.responseText)
+ alert(JSON.parse(xhr.responseText).error)
+ }
+ }
+ }
+ xhr.open("POST", "/api", true);
+ xhr.send(JSON.stringify({command:"createChannel", options: options}));
}
- };
- return maps;
-}
-
-function getSelectedChannel() {
- var name = null;
- var radios = document.querySelectorAll("form#listform input[name=channel]");
- for (var i = 0; i < radios.length; i++) {
- var radio = radios[i];
- if(radio.checked) {
- name = radio.value;
- break;
- }
- };
- return name
-}
-
-function join(nickname, channelName) {
-
- if(validateForJoin(nickname, channelName)) {
- localStorage["player"] = JSON.stringify({
- nickname: nickname
- });
- localStorage["channel"] = JSON.stringify({
- name: channelName
- });
-
- window.location.href = "/game.html";
}
-}
-function create(channelName, callback) {
- var maps = getSelectedMaps();
-
- if(validateForCreate(channelName, maps)) {
+ $("#refresh").onclick = refresh;
+ refresh();
+ setInterval(refresh, 5000);
- var options = {
- channelName: channelName,
- levelUids: maps,
- maxUsers: 10,
- minUsers: 2,
- scoreLimit: parseInt($("#scoreLimit").value, 10)
- }
-
- localStorage["customname"] = channelName;
-
- var xhr = new XMLHttpRequest();
- xhr.onreadystatechange = function() {
- if(xhr.readyState == 4) {
- if(xhr.status == 200) {
- if(typeof callback == 'function') {
- callback(JSON.parse(xhr.responseText).success);
- }
- } else {
- console.log(xhr.responseText)
- alert(JSON.parse(xhr.responseText).error)
- }
- }
- }
- xhr.open("POST", "/api", true);
- xhr.send(JSON.stringify({command:"createChannel", options: options}));
+ Chuck.menu = {
+ show: show
}
-}
-
-$("#refresh").onclick = refresh;
-refresh();
-setInterval(refresh, 5000);
-
+})(Chuck);
\ No newline at end of file