Skip to content

Commit

Permalink
Web frontend: Move CSS to separate files, escape player and game name…
Browse files Browse the repository at this point in the history
…s, prevent animation of second card play during the same turn, and only show relevant buttons at various parts of the game

IRC frontend: Remove extra 'error' event handler and add !help command

Game Manager: Gameplay direction should reset to left to right instead of right to left
  • Loading branch information
mscdex committed Apr 27, 2011
1 parent 365fe72 commit 775fa74
Show file tree
Hide file tree
Showing 7 changed files with 193 additions and 148 deletions.
26 changes: 20 additions & 6 deletions lib/frontends/irc/index.js
Expand Up @@ -101,30 +101,47 @@ GameInterface.prototype.init = function() {
var self = this,
manager = this.manager;

self.log('Connecting to IRC server ...', LOG.INFO);
conn = new IrcClient(this.config.server, this.config.nick, this.config)
conn.on('ready', function() {
self.log('Connected to IRC server', LOG.INFO);
self.log('Connected to IRC server!', LOG.INFO);
});
conn.on('error', function(err) {
if (err.rawCommand === '401') {
// Player disconnected?
manager.delPlayer(err.args[1], IRCPlayer);
} else
self.log('IRC Error: ' + util.inspect(err));
self.log('Connection error: ' + util.inspect(err, false, 4), LOG.ERROR);
});
conn.on('pm', function(from, msg) {
if (msg.length) {
var player, ret;
msg = msg.substring(1).toLowerCase();
if (msg === 'help') {
// List commands
[
'!help -- this listing',
'!games -- shows simple game stats',
'!points -- shows your current point count',
'!create [gameName] -- creates a new game',
'!start -- starts the game (if you are the owner)',
'!join <gameName> -- joins a game',
'!exit -- leaves the game',
'!hand -- shows your current hand',
'!draw -- draws a single card',
'!pass -- passes play to the next player',
'!play <cardIndex> [color] -- plays the specified card (if Wild, color must be specified)',
'(end of help)'
].forEach(function(line) {
conn.say(from, line);
});
} else if (msg === 'games') {
var stats = manager.gamesStats();
conn.say(from, stats[0] + ' game(s) waiting for players and ' + stats[1]
+ ' game(s) in progress');
} else if (msg === 'points') {
if (ret = manager.findPlayer(from, IRCPlayer))
conn.say(from, 'You currently have ' + ret.points + ' points');
conn.say(from, 'You currently have ' + ret.points + ' point(s)');
else
conn.say(from, 'You are not currently in a game');
} else if (msg === 'hand') {
Expand Down Expand Up @@ -218,9 +235,6 @@ GameInterface.prototype.init = function() {
}
}
});
conn.on('error', function(msg) {
self.log('Connection error: ' + util.inspect(msg, false, 4), LOG.ERROR);
});
};
// =============================================================================
function formatCard(card) {
Expand Down
4 changes: 4 additions & 0 deletions lib/frontends/web/index.js
Expand Up @@ -69,6 +69,8 @@ var GameInterface = module.exports = function(manager, fnLog) {
var pubPath = __dirname + '/public',
imgPath = pubPath + '/images';
localFiles['index.htm'] = fs.readFileSync(pubPath + '/index.htm');
localFiles['style.css'] = fs.readFileSync(pubPath + '/style.css');
localFiles['style.ie6.css'] = fs.readFileSync(pubPath + '/style.ie6.css');
localFiles['game.js'] = fs.readFileSync(pubPath + '/game.js');
localFiles['flashws.js'] = fs.readFileSync(pubPath + '/flashws.js');
localFiles['transport.js'] = fs.readFileSync(pubPath + '/transport.js');
Expand Down Expand Up @@ -110,6 +112,8 @@ GameInterface.prototype.init = function() {
if (localFiles[file]) {
if (ext === 'js')
type = 'text/javascript';
else if (ext === 'css')
type = 'text/css';
else if (ext === 'swf')
type = 'application/x-shockwave-flash';
else if (ext === 'htm')
Expand Down
90 changes: 57 additions & 33 deletions lib/frontends/web/public/game.js
@@ -1,10 +1,11 @@
var conn, callback, players = {}, me, imgBack = 'images/back.png',
inGame = false, isNewRound = false, isWild = false, elWild, dir = 1;
inGame = false, isNewRound = false, isWild = false, elWild, dir = 1,
isAnimating = false;

/* Game functions */
function addPlayer(p) {
players[p.id] = p;
$('#players').append('<div class="player ' + p.type.toLowerCase() + '" id="player-' + p.id + '"><span class="playerName">' + p.name + '</span><div class="cardcount"></div></div>');
$('#players').append('<div class="player ' + p.type.toLowerCase() + '" id="player-' + p.id + '"><span class="playerName">' + entities(p.name) + '</span><div class="cardcount"></div></div>');
return 'player-' + p.id;
}
function delPlayer(p) {
Expand Down Expand Up @@ -74,11 +75,11 @@ function toggleDir() {
$('#dir').html('&larr;');
}
function reset() {
isWild = inGame = false;
isWild = inGame = isAnimating = false;
dir = -1;
$('.playingarea').hide();
$('#players, #hand').empty();
$('#piles, #pass, #showWC').hide();
$('#piles, #pass, #showWC, #playingarea, #gameInfo, #btnLeave, #btnStart').hide();
$('#btnCreate, #btnJoin').show();
$('.owner').removeClass('owner');
$('.turn').removeClass('turn');
$('#myscore').html('0');
Expand All @@ -89,29 +90,32 @@ function reset() {
function handleEvent(res) {
if (res.event === 'playerjoin') {
addPlayer(res.player);
status(res.player.name + ' joined the game');
status(entities(res.player.name) + ' joined the game');
} else if (res.event === 'playerquit') {
delete players[res.player.id];
$('#player-' + res.player.id).remove();
if (res.newOwner)
$('#player-' + res.newOwner.id).addClass('owner');
if (players.length > 1)
status(res.player.name + ' left the game');
status(entities(res.player.name) + ' left the game');
} else if (res.event === 'start') {
var msg;
if (res.roundWinner) {
if (res.roundWinner.id === me.id) {
msg = 'You';
$('#myscore').html(res.roundWinner.points);
} else
msg = res.roundWinner.name;
msg = entities(res.roundWinner.name);
msg += ' won this round. Next round started.';
dir = -1;
toggleDir();
isNewRound = true;
isWild = false;
callback = undefined;
$('#hand').empty();
$('#pass, #showWC').hide();
} else {
$('#gameInfo').show();
inGame = true;
msg = 'Game started.';
}
Expand All @@ -134,7 +138,7 @@ function handleEvent(res) {
status(msg);
} else if (res.event === 'play') {
isNewRound = false;
var msg = res.player.name + ' played a ' + cardToText(res.card);
var msg = entities(res.player.name) + ' played a ' + cardToText(res.card);
if (typeof res.wildColor !== 'undefined') {
isWild = true;
$('#wildColor').attr('class', 'center wildColor' + res.wildColor);
Expand All @@ -149,34 +153,34 @@ function handleEvent(res) {
animPlay('#player-' + res.player.id + ' div.cardcount', res.card);
status(msg);
} else if (res.event === 'end') {
status('Game ended' + (res.player ? '. Game winner: ' + res.player.name : ''));
status('Game ended' + (res.player ? '. Game winner: ' + entities(res.player.name) : ''));
reset();
} else if (res.event === 'turn') {
$('.turn').removeClass('turn');
if (res.player.id === me.id)
status('Your turn');
$('#player-' + res.player.id).addClass('turn');
} else if (res.event === 'draw') {
var who = res.player.name;
var who = entities(res.player.name);
if (res.drawnCards) {
who = 'You';
var i = 0;
animDraw('#player-' + me.id, res.drawnCards.length, function() {
$('#hand').append('<img src="' + cardToImage(res.drawnCards[i++]) + '" />');
addCardCount(me.id, 1);
});
} else {
animDraw('#player-' + res.player.id + ' div.cardcount', res.numCards, function() {
addCardCount(res.player.id, 1);
});
}
status(who + ' drew ' + res.numCards + ' card' + (res.numCards > 1 ? 's' : ''));
} else if (res.event === 'pass') {
status(res.player.name + ' passed');
} else if (res.event === 'youknow') {
status(res.player.name + ' has one card left!');
} else {
} else if (res.event === 'pass')
status(entities(res.player.name) + ' passed');
else if (res.event === 'youknow')
status(entities(res.player.name) + ' has one card left!');
else
log('Received unexpected event \'' + res.event + '\': ' + data);
}
}
function animDraw(where, num, cbEach) {
if (num <= 0) return;
Expand Down Expand Up @@ -250,11 +254,13 @@ function animPlay(where, card, cbDone) {
opacity: 1
}, 250, function() {
$el.remove();
$('#discard img').attr('src', src);
if (!isNewRound)
$('#discard img').attr('src', src);
if ($handcard)
$handcard.remove();
if (cbDone)
cbDone();
isAnimating = false;
}
);
}
Expand Down Expand Up @@ -289,50 +295,57 @@ function preloadAssets() {
$('<img/>')[0].src = imgBack;
}
function initUIHandlers() {
$('#btnConnect').click(function() { conn.connect(address); });
$('#btnRegister').click(function() {
var name;
if (name = prompt('Enter a nickname to use:')) {
send('register ' + name, fnEmpty);
send('register ' + name, function() {
status('Registered player name');
$('#btnRegister').hide();
});
}
});
$('#btnCreate').click(function() {
var gameName = prompt('Enter new game name (blank to autogenerate):');
if (typeof gameName === 'string') {
send('create' + (gameName.length > 0 ? ' ' + gameName : ''), function(res) {
$('.playingarea').show();
$('#playingarea').show();
me = res.me;
var id = '#' + addPlayer(me);
$(id).addClass('owner');
$(id + ' .playerName').css('text-decoration', 'underline');
status('Created game: ' + entities(res.gameName));
$('#btnStart, #btnLeave').show();
$('#btnJoin, #btnCreate').hide();
});
}
});
$('#btnStart').click(function() {
send('start', fnEmpty);
send('start', function() {
$('#btnStart').hide();
});
});
$('#btnJoin').click(function() {
var gameName;
if (gameName = prompt('Join which game?')) {
send('join ' + gameName, function(res) {
$('.playingarea').show();
$('#btnJoin, #btnCreate, #btnStart').hide();
$('#playingarea, #btnLeave').show();
me = res.me;
if (res.players)
for (var i=0,len=res.players.length; i<len; ++i)
addPlayer(res.players[i]);
$('#player-' + res.ownerId).addClass('owner');
$('#' + addPlayer(me) + ' .playerName').css('text-decoration', 'underline');
status('Joined game: ' + gameName);
status('Joined game: ' + entities(gameName));
});
}
});
$('#btnLeave').click(function() {
send('leave', function() {
reset();
status('You have left the game');
});
});
$('#btnDisconnect').click(function() { conn.disconnect(); });

$('#draw').click(function() {
send('draw', function() {
Expand All @@ -351,6 +364,7 @@ function initUIHandlers() {
$.modal.close();
$('#colorchooser').hide();
isWild = true;
addCardCount(me.id, -1);
if (!isNewRound && inGame)
status(' ');
else
Expand All @@ -362,13 +376,19 @@ function initUIHandlers() {
});
});
$('#hand img').live('click', function() {
if (isAnimating)
return;
isAnimating = true;
var idx = $(this).index(), self = this,
card = imageToCard($(self).attr('src'));
if (card[0] > 3) {
elWild = self;
$('#colorchooser').modal({ overlayClose: true, opacity: 70 });
} else {
send('play ' + idx, function() {
addCardCount(me.id, -1);
isWild = false;
$('#showWC').hide();
if (!isNewRound && inGame)
status(' ');
else
Expand All @@ -384,7 +404,7 @@ function initUIHandlers() {

/* Setup the connnection */
conn = initTransport(function() {
log('Connected!');
status('Connected to server');
},
function(data) {
log('Received: ' + data);
Expand All @@ -398,21 +418,23 @@ conn = initTransport(function() {
if (res.event)
handleEvent(res);
else if (callback) {
if (res.error)
if (res.error) {
alert('Error: ' + res.error);
else
isAnimating = false;
} else
callback(res.ret);
callback = undefined;
}
else
} else {
log('Received unexpected response: ' + data);
isAnimating = false;
}
}, function() {
// disconnected cb
log('Lost connection with the server');
//reset();
status('Lost connection with the server');
reset();
}, function(msg) {
// error cb
log('Unexpected error while communicating with server: ' + msg);
status('Comm Error: ' + msg);
reset();
});
if (!conn.connect) {
Expand All @@ -423,5 +445,7 @@ if (!conn.connect) {

$(function() {
initUIHandlers();
$('#btnLeave, #btnStart').hide();
conn.connect(address);
});
}

0 comments on commit 775fa74

Please sign in to comment.