diff --git a/client/index.html b/client/index.html
index 10672d3..7a7bf8f 100644
--- a/client/index.html
+++ b/client/index.html
@@ -23,6 +23,7 @@
+
diff --git a/client/lib/core/page_base.js b/client/lib/core/page_base.js
index d1953d2..db414c6 100644
--- a/client/lib/core/page_base.js
+++ b/client/lib/core/page_base.js
@@ -31,6 +31,16 @@ NPGClient.AppPage.prototype = {
return self.uiElems;
},
+ //
+ hasUIElem: function(name) {
+ var self = this;
+ if (self.uiElems.length > 0) {
+ for (var i = 0; i < self.uiElems.length; i++)
+ if (self.uiElems[i].name == name) return true;
+ }
+ return false;
+ },
+
//
getUIElemByName: function(name) {
diff --git a/client/lib/core/page_handler.js b/client/lib/core/page_handler.js
index ecafe2e..0cb35df 100644
--- a/client/lib/core/page_handler.js
+++ b/client/lib/core/page_handler.js
@@ -57,6 +57,21 @@ NPGClient.PageHandler = {
return undefined;
},
+ //
+ getUIElem: function(name) {
+ var self = this;
+ var elem = [];
+ if (self.pages.length > 0) {
+ for (var i = 0; i < self.pages.length; i++) {
+ elem = self.pages[i].getUIElems();
+ for (e in elem) {
+ if (elem[e].name == name) return elem[e];
+ }
+ }
+ }
+ return undefined;
+ },
+
// @need rework
getUIElemFromPage: function(elem, page) {
var self = this;
@@ -82,6 +97,18 @@ NPGClient.PageHandler = {
return undefined;
},
+ //
+ updateServerInfos: function() {
+ var self = this;
+ // server infos
+ self.getUIElem('servinfo_users').update(NPGClient.SERVER.nPlayers);
+ self.getUIElem('servinfo_games_running').update(NPGClient.SERVER.nGamesRunning);
+ self.getUIElem('servinfo_games_avail').update(NPGClient.SERVER.nGamesAvail);
+
+ },
+
+
+
// create login page
createLoginPage: function() {
//
@@ -89,7 +116,8 @@ NPGClient.PageHandler = {
var self = this;
var p = new NPGClient.AppPage(NPGClient.LOGIN.NAME);
// Title label
- p.addUIObject(new NPGClient.UILabel('login_title', NPGClient.LOGIN.TITLE));
+ //p.addUIObject(new NPGClient.UILabel('login_title', NPGClient.LOGIN.TITLE));
+ p.addUIObject(new NPGClient.UILabel(NPGClient.LOGIN.TITLE));
// name input
p.addUIObject(new NPGClient.UIInputText('login_input', NPGClient.LOGIN.INPUT));
// Server status
@@ -108,11 +136,14 @@ NPGClient.PageHandler = {
var self = this;
var p = new NPGClient.AppPage(NPGClient.STARTMENU.NAME);
// Title label
- p.addUIObject(new NPGClient.UILabel('login_title', NPGClient.STARTMENU.TITLE));
+ //p.addUIObject(new NPGClient.UILabel('startmenu_title', NPGClient.STARTMENU.TITLE));
+ p.addUIObject(new NPGClient.UILabel(NPGClient.STARTMENU.TITLE));
// Start Menu
p.addUIObject(new NPGClient.UIMenu(NPGClient.STARTMENU.MENU));
- // Server Players and Games status
-
+ // Server Players and Games info
+ p.addUIObject(new NPGClient.UIStatusValue(NPGClient.STARTMENU.SERVINFO_USERS));
+ p.addUIObject(new NPGClient.UIStatusValue(NPGClient.STARTMENU.SERVINFO_GAMES_RUNNING));
+ p.addUIObject(new NPGClient.UIStatusValue(NPGClient.STARTMENU.SERVINFO_GAMES_AVAIL));
//
self.pages.push(p);
},
diff --git a/client/lib/keyboard/event_handler.js b/client/lib/keyboard/event_handler.js
index 54daf6b..85ef7e4 100644
--- a/client/lib/keyboard/event_handler.js
+++ b/client/lib/keyboard/event_handler.js
@@ -78,6 +78,7 @@ NPGClient.evtHandler = {
if (!NPGClient.Utils.nameEmpty()) {
NPGClient.Utils.removeChar();
NPGClient.PageHandler.getCurrPageUIElemByName('login_cursor').translateX(-15);
+ NPGClient.PageHandler.getCurrPageUIElemByName('login_cursor').resetBlink();
}
break;
default:
@@ -86,6 +87,7 @@ NPGClient.evtHandler = {
NPGClient.Utils.addChar(evt.keyCode);
newNameW = NPGClient.ui.ctx.measureText(NPGClient.userName).width;
NPGClient.PageHandler.getCurrPageUIElemByName('login_cursor').translateX(15);
+ NPGClient.PageHandler.getCurrPageUIElemByName('login_cursor').resetBlink();
}
break;
}
diff --git a/client/lib/npg_client.js b/client/lib/npg_client.js
index 3641e2b..9ed26a8 100644
--- a/client/lib/npg_client.js
+++ b/client/lib/npg_client.js
@@ -5,11 +5,31 @@
var NPGClient = { 'version': '' };
+
+// LOGIN NAME
NPGClient.NAMEMAXSIZE = 8;
NPGClient.userName = '';
-// ui
+// SERVER INFOS
+NPGClient.SERVER = {
+ isUp: false,
+ nPlayers : 0,
+ nGamesRunning : 0,
+ nGamesAvail : 0,
+ gamesList : [],
+ updateInfos: function(data) {
+ var self = this;
+ self.nPlayers = data.infos.nUsers;
+ self.nGamesRunning = data.infos.nGamesRunning;
+ self.nGamesAvail = data.infos.nGamesAvail;
+ self.gamesList = [];
+ for (g in data.games) self.gamesList(data.games[g]);
+ },
+};
+
+
+// UI
NPGClient.CAN_W = 800;
NPGClient.CAN_H = 500;
NPGClient.CAN_COL = '#000000';
@@ -51,6 +71,7 @@ NPGClient.LOGIN = {
},
},
TITLE: {
+ 'name': 'login_title',
'text': 'nodePong',
'x': 400,
'y': 150,
@@ -93,6 +114,7 @@ NPGClient.LOGIN = {
NPGClient.STARTMENU = {
NAME: 'start_menu',
TITLE: {
+ 'name': 'start_menu_title',
'text': 'nodePong',
'x': 400,
'y': 150,
@@ -132,19 +154,39 @@ NPGClient.STARTMENU = {
}
}
},
- SERVSTATUS: {
- 'text': {
- 'online' : 'server: online',
- 'offline' : 'server: offline',
- },
- 'x': 380,
- 'y': 250,
+ SERVINFO_USERS: {
+ 'name': 'servinfo_users',
+ 'label': 'Users online:',
+ 'x': 70,
+ 'y': 470,
'style': {
- 'font': '15px Arial',
+ 'font': '15px Monospace',
+ 'col': '#FFFFFF',
+ 'align': 'left'
+ },
+ },
+ SERVINFO_GAMES_RUNNING: {
+ 'name': 'servinfo_games_running',
+ 'label': 'Games running:',
+ 'x': 400,
+ 'y': 470,
+ 'style': {
+ 'font': '15px Monospace',
'col': '#FFFFFF',
'align': 'center'
},
},
+ SERVINFO_GAMES_AVAIL: {
+ 'name': 'servinfo_games_avail',
+ 'label': 'Games available:',
+ 'x': 730,
+ 'y': 470,
+ 'style': {
+ 'font': '15px Monospace',
+ 'col': '#FFFFFF',
+ 'align': 'right'
+ },
+ },
};
diff --git a/client/lib/socket/socketio_handler.js b/client/lib/socket/socketio_handler.js
index 74a08a9..d4d4af2 100644
--- a/client/lib/socket/socketio_handler.js
+++ b/client/lib/socket/socketio_handler.js
@@ -81,11 +81,17 @@ NPGClient.SocketIO = {
self.isConnected = false;
});
+ // 'serverInfosUpdate'
+ self.socket.on('serverInfosUpdate', function(data) {
+ NPGClient.Utils.log(' > Server infos update. ' + data);
+ NPGClient.SERVER.updateInfos(data);
+ NPGClient.PageHandler.updateServerInfos();
+ });
+
// 'regDone'
self.socket.on('regDone', function() {
NPGClient.Utils.log(' > Server: User registration done');
- //NPGClient.PageHandler.moveToPage(NPGClient.STARTMENU.NAME);
- NPGClient.PageHandler.setCurrPage(NPGClient.STARTMENU.NAME);
+ NPGClient.PageHandler.setCurrPage(NPGClient.STARTMENU.NAME);
});
// 'regNameTaken'
diff --git a/client/lib/ui/objects/ui_cursor.js b/client/lib/ui/objects/ui_cursor.js
index 035c15e..775669e 100644
--- a/client/lib/ui/objects/ui_cursor.js
+++ b/client/lib/ui/objects/ui_cursor.js
@@ -34,8 +34,18 @@ NPGClient.UICursor.prototype.constructor = NPGClient.UICursor;
NPGClient.UICursor.prototype.reset = function() {
var self = this;
self.moveTo(self.x0, self.y0);
+ self.bState = true;
+ self.bCount = 0;
}
+// resetBlink
+NPGClient.UICursor.prototype.resetBlink = function() {
+ var self = this;
+ self.bState = true;
+ self.bCount = 0;
+}
+
+
// draw
NPGClient.UICursor.prototype.draw = function(ctx) {
var self = this;
diff --git a/client/lib/ui/objects/ui_label.js b/client/lib/ui/objects/ui_label.js
index cdc2af9..a88f2e1 100644
--- a/client/lib/ui/objects/ui_label.js
+++ b/client/lib/ui/objects/ui_label.js
@@ -3,35 +3,39 @@
* @author frtk@tetalab
*/
-NPGClient.UILabel = function(n, o) {
-
+NPGClient.UILabel = function(o) {
+ //
+ NPGClient.UIObject.call(this, o);
// obj name
- this.name = n !== undefined ? n : '';
- // bkg rect
- //this.bkg = r !== undefined ? r : new NPGClient.UIRect();
+ this.name = o.name !== undefined ? o.name : '';
// pos
this.x = o.x !== undefined ? o.x : 0;
this.y = o.y !== undefined ? o.y : 0;
-
// text
this.text = o.text !== undefined ? o.text : '';
// text style
- this.s = o.style !== undefined ? o.style : new NPGClient.UITextStyle();
+ this.s = o.style !== undefined ? o.style : '';
};
-NPGClient.UILabel.prototype = {
+/**
+ * Inheritance
+ */
+NPGClient.UILabel.prototype = Object.create(NPGClient.UIObject.prototype);
- // Constructor
- constructor: NPGClient.UILabel,
-
- //
- draw: function(ctx) {
- var self = this;
- NPGClient.Utils.setTxtStyle(ctx, self.s);
- ctx.fillText(self.text, self.x, self.y);
- }
+
+/**
+ * Functions
+ */
+//
+NPGClient.UILabel.prototype.constructor = NPGClient.UILabel;
+
+//
+NPGClient.UILabel.prototype.draw = function(ctx) {
+ var self = this;
+ NPGClient.Utils.setTxtStyle(ctx, self.s);
+ ctx.fillText(self.text, self.x, self.y);
};
diff --git a/client/lib/ui/objects/ui_menu.js b/client/lib/ui/objects/ui_menu.js
index 454c577..5ba382c 100644
--- a/client/lib/ui/objects/ui_menu.js
+++ b/client/lib/ui/objects/ui_menu.js
@@ -56,6 +56,7 @@ NPGClient.UIMenu.prototype.selectPrevItem = function(t) {
}
if (self.hasCursor) {
self.cursor.translateY(cShift);
+ self.cursor.resetBlink();
}
}
};
@@ -76,6 +77,7 @@ NPGClient.UIMenu.prototype.selectNextItem = function(t) {
}
if (self.hasCursor) {
self.cursor.translateY(cShift);
+ self.cursor.resetBlink();
}
}
};
diff --git a/client/lib/ui/objects/ui_status_value.js b/client/lib/ui/objects/ui_status_value.js
new file mode 100644
index 0000000..2345406
--- /dev/null
+++ b/client/lib/ui/objects/ui_status_value.js
@@ -0,0 +1,52 @@
+/**
+ * @file ui_status_value.js
+ * @author frtk@tetalab
+ */
+
+NPGClient.UIStatusValue = function(o) {
+ //
+ NPGClient.UIObject.call(this, o);
+ // obj name
+ this.name = o.name !== undefined ? o.name : '';
+ // pos
+ this.x = o.x !== undefined ? o.x : 0;
+ this.y = o.y !== undefined ? o.y : 0;
+ //
+ this.s = o.style !== undefined ? o.style : '';
+ // label
+ this.label = o.label !== undefined ? o.label : '';
+ // widget var value
+ this.value = 0;
+
+};
+
+
+/**
+ * Inheritance
+ */
+NPGClient.UIStatusValue.prototype = Object.create(NPGClient.UIObject.prototype);
+
+
+/**
+ * Functions
+ */
+//
+NPGClient.UIStatusValue.prototype.constructor = NPGClient.UIStatusValue;
+
+//
+NPGClient.UIStatusValue.prototype.update = function(v) {
+ var self = this;
+ self.value = v;
+};
+
+//
+NPGClient.UIStatusValue.prototype.draw = function(ctx) {
+ var self = this;
+ NPGClient.Utils.setTxtStyle(ctx, self.s);
+ //
+ var txt = self.label + ' ' + self.value;
+ //
+ ctx.fillText(txt, self.x, self.y);
+
+};
+
diff --git a/package.json b/package.json
index 6a2516e..c846fbf 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "npg_app.js",
- "version": "0.2.1",
+ "version": "0.2.2",
"description": "Multiplayer online Pong Game using nodejs and socket.io",
"directories": {
"server": "server",
diff --git a/server/npg_server.js b/server/npg_server.js
index ffb4614..908ef22 100644
--- a/server/npg_server.js
+++ b/server/npg_server.js
@@ -123,13 +123,10 @@ var NPGServer = {
self.log('Server: User name already taken - reseting client UI');
} else {
self.createUser(data, socket);
+ self.updateAllClientsServerInfos();
+ //
+ self.sendMsgToSocket(socket, 'regDone');
}
-/*
- self.updateClientsServerInfo(); // update all clients info
- io.sockets.sockets[socketId].emit('playerCreated'); // send socket msg
- },
-*/
-
},
//
@@ -139,6 +136,8 @@ var NPGServer = {
if (self.isUser(id)) {
self.log('[Client:' + id + '] User ' + u.name + ' disconnected');
self.deleteUser(u.name);
+ //
+ self.updateAllClientsServerInfos();
}
},
@@ -207,13 +206,6 @@ var NPGServer = {
self.users.push(new User(name, socket));
self.log('Server: number of players: n= ' + self.users.length);
self.log('Server: player registered, send user ' + name + ' to menu page.');
- // send user auth
- self.sendMsgToSocket(socket, 'regDone');
- },
-
- removeDuplicateUser: function(name) {
- var self = this;
- self.log('Server: player already registered, removing duplicate.');
},
//
@@ -229,6 +221,76 @@ var NPGServer = {
}
},
+
+
+ /**
+ *
+ * Server Infos (players and games)
+ *
+ */
+ //---
+ updateAllClientsServerInfos: function(socket) {
+ var self = this;
+ for (u in self.users) {
+ self.users[u].sendMsg('serverInfosUpdate', { infos: self.getServerInfos(), games: self.getGamesList() });
+ }
+ self.log('Server: updated server infos for all clients');
+ },
+
+ //---
+ updateClientServerInfos: function(socket) {
+ var self = this;
+ socket.emit('serverInfosUpdate', { infos: self.getServerInfos(), games: self.getGamesList() });
+ self.log('Server: update client server info');
+ },
+
+ //---
+ getServerInfos: function() {
+ var self = this;
+ return {
+ nUsers: self.nPlayers(),
+ nGamesRunning: self.nGamesRunning(),
+ nGamesAvail: self.nGamesAvail()
+ }
+ },
+
+ //---
+ getGamesList: function() {
+ var self = this;
+ var res = [];
+ for (g in self.games) {
+ res.push(self.games[g].getHostName());
+ }
+ return res;
+ },
+
+ //---
+ nPlayers: function() {
+ var self = this;
+ return self.users.length;
+ },
+
+ //---
+ nGamesRunning: function() {
+ var self = this;
+ var n = 0;
+ for (g in self.games) {
+ if (self.games[g].status == 'running') n++;
+ }
+ return n;
+ },
+
+ //---
+ nGamesAvail: function() {
+ var self = this;
+ var n = 0;
+ for (g in self.games) {
+ if (self.games[g].status == 'available') n++;
+ }
+ return n;
+ },
+
+
};
@@ -240,13 +302,11 @@ var NPGServer = {
*
*/
var User = function(name, socket) {
-
//
this.name = (name !== undefined) ? name : '';
this.socket = (socket !== undefined) ? socket : '';
//
this.status = '';
-
};
//
User.prototype.constructor = User;
diff --git a/version.md b/version.md
index e73159a..7d3eeef 100644
--- a/version.md
+++ b/version.md
@@ -1,4 +1,26 @@
+
+# **v0.2.2:**
+## focus: Start Menu Page
+--------------------------
+### client objects update
+- UICursor: added resetBlink() function to reset blink on menu item change (to avoid "shadow" cursor)
+- UIMenu: added cursor resetBlink() in select next/previous item function
+- UILabel: added UIObject inheritance and changed param initialization
+
+### client objects creation
+- UIStatusValue: ui element to display server infos (number of users, games running and games available)
+
+### client start menu page
+- added 3 UIStatusValue elements
+- all 3 elements are updated within the page_handler
+
+### server
+- added server infos update for all clients when a user register or disconnect
+
+
+
+
# **v0.2.1:**
## focus: Start Menu Page
--------------------------