Permalink
Browse files

add scoring

  • Loading branch information...
1 parent 502b0c1 commit ef9810d8210f61d64f9853aecb895f4973daf0b7 @cri5ti committed Mar 12, 2012
View
18 server/game.js
@@ -98,6 +98,7 @@
_.each(this.blocks, function(b) {
this.map.setAbsMap(b.x, b.y, TILE_EMPTY);
}, this);
+
this.map.trigger('notify');
},
@@ -127,6 +128,23 @@
getBomb: function(x,y) {
return this.bombs.find(function(b) { return b.get('x') == x && b.get('y') == y; });
+ },
+
+ scoreKill: function(whoId, byWhoId) {
+ var who = this.playersById[whoId];
+ if (!who) return;
+
+ if (whoId == byWhoId) { // suicide
+ console.log(who.get('name') + " suicided");
+ who.set('score', who.get('score') - 1);
+ } else {
+ var byWho = this.playersById[byWhoId];
+ if (!byWho) return;
+
+ console.log(who.get('name') + " was killed by " + byWho.get('name'));
+ byWho.set('score', byWho.get('score') + 1);
+ }
+ this.trigger('score-changes');
}
});
View
2 server/map.js
@@ -31,7 +31,7 @@
if (i%2==0 && j%2==0)
this.setMap(i,j, TILE_SOLID);
- else if ( Math.floor(Math.random()*2)==0)
+ else if ( Math.floor(Math.random()*20)==0)
this.setMap(i,j, TILE_BRICK);
}
View
3 server/model.js
@@ -9,7 +9,8 @@
timePlaced: 0,
timeTrigger: 0,
fuseTime: 2500,
- strength: 4
+ strength: 4,
+ owner: 0
}
});
View
17 server/player.js
@@ -7,7 +7,8 @@
defaults: {
alive: false,
- spawnAt: 0
+ spawnAt: 0,
+ score: 0
},
initialize: function(opt) {
@@ -35,12 +36,12 @@
return {
id: this.get('id'),
name: this.get('name'),
- character: this.get('character')
+ character: this.get('character'),
+ score: this.get('score')
}
},
die: function() {
- console.log(this.get('name') + " died");
this.set('alive', false);
}
});
@@ -75,9 +76,12 @@
onDead: function(d) {
this.me.die();
+
+ this.game.scoreKill(d.id, d.flameOwner);
+
this.me.set('spawnAt', this.game.lastTick + SPAWNING_TIME);
// notify everyone else
- this.socket.broadcast.emit('player-dying', d);
+ this.endpoint.emit('player-dying', d);
},
onDisconnect: function() {
@@ -90,12 +94,13 @@
onPlaceBomb: function(d) {
console.log('Placing bomb at ' + d.x + ", " + d.y);
+ // can place bomb there?
if (!this.game.bombs.any(function(b) { return b.get('x') == d.x && b.get('y') == d.y; }))
{
// no bomb here
- this.game.bombs.add(new Bomb({x: d.x, y: d.y}));
+ this.game.bombs.add(new Bomb({x: d.x, y: d.y, owner: this.id}));
// notify everyone
- this.endpoint.emit('bomb-placed', {x: d.x, y: d.y});
+ this.endpoint.emit('bomb-placed', {x: d.x, y: d.y, owner: this.id});
} else {
console.log('A bomb at ' + d.x + ", " + d.y + " already exists!");
}
View
19 server/server.js
@@ -30,6 +30,9 @@ require("./player.js");
this.game.bombs.on('remove', this.onBombRemoved, this);
+ this.game.on('score-changes', _.debounce(this.notifyScoreUpdates, 50), this);
+
+
this.endpoint = io.of('/game');
this.endpoint.on('connection', _.bind(this.connection, this));
},
@@ -81,13 +84,6 @@ require("./player.js");
ctrl.notifyGameState();
}, this));
-
- // TODO spawn
- // TODO var newPlayerInfo = this.game.map.getSpawnLocation();
-// socket.emit('spawn', {
-// x: newPlayerInfo.x,
-// y: newPlayerInfo.y
-// })
},
onBombRemoved: function(b) {
@@ -98,6 +94,15 @@ require("./player.js");
y: b.get('y'),
strength: b.get('strength')
});
+ },
+
+ notifyScoreUpdates: function() {
+ var scoring = {};
+ _.each(this.game.playersById, function(p,id) {
+ scoring[id] = p.get('score');
+ });
+
+ this.endpoint.emit('score-updates', scoring);
}
View
105 web/css/app.css
@@ -107,23 +107,39 @@ canvas {
#chat .mychat {
color: #fff;
}
+/* line 41, ../sass/app.scss */
+#chat .kill {
+ color: #fa6;
+}
+/* line 45, ../sass/app.scss */
+#chat .bomb {
+ display: inline-block;
+ vertical-align: middle;
+ margin: 0 5px;
+}
-/* line 42, ../sass/app.scss */
+/* line 52, ../sass/app.scss */
a {
color: #f60;
}
-/* line 46, ../sass/app.scss */
+/* line 56, ../sass/app.scss */
a.disabled {
color: #333;
}
-/* line 50, ../sass/app.scss */
+/* line 60, ../sass/app.scss */
a:hover {
color: #fff;
}
-/* line 55, ../sass/app.scss */
+/* line 64, ../sass/app.scss */
+#map {
+ position: absolute;
+ top: 20px;
+}
+
+/* line 69, ../sass/app.scss */
#console {
position: fixed;
bottom: 0;
@@ -138,7 +154,60 @@ a:hover {
box-shadow: black 0px -3px 20px;
}
-/* line 67, ../sass/app.scss */
+/* line 81, ../sass/app.scss */
+#score-table {
+ padding: 12px;
+ font: 13px Arial;
+ background: black;
+ border-bottom: solid 1px #4A4;
+}
+/* line 87, ../sass/app.scss */
+#score-table .score-item {
+ display: inline-block;
+ margin: 0 10px;
+ color: #aaa;
+}
+/* line 92, ../sass/app.scss */
+#score-table .score-item .player {
+ display: inline-block;
+ margin-right: 3px;
+}
+/* line 97, ../sass/app.scss */
+#score-table .score-item .score {
+ display: inline-block;
+ font-size: 15px;
+ padding: 2px 10px;
+ -moz-border-radius: 10px;
+ -webkit-border-radius: 10px;
+ -o-border-radius: 10px;
+ -ms-border-radius: 10px;
+ -khtml-border-radius: 10px;
+ border-radius: 10px;
+}
+/* line 105, ../sass/app.scss */
+#score-table .score-item.color-mary .score {
+ background: #a00;
+ color: #fd6;
+}
+/* line 106, ../sass/app.scss */
+#score-table .score-item.color-john .score {
+ background: #fff;
+ color: #33f;
+}
+/* line 107, ../sass/app.scss */
+#score-table .score-item.color-joe .score {
+ background: #333;
+ color: #0f0;
+ border: solid 1px #0f0;
+ padding: 0 8px;
+}
+/* line 108, ../sass/app.scss */
+#score-table .score-item.color-betty .score {
+ background: #05e;
+ color: #ffa;
+}
+
+/* line 111, ../sass/app.scss */
#waitserver {
position: absolute;
top: 0;
@@ -152,7 +221,7 @@ a:hover {
opacity: 0.5;
}
-/* line 80, ../sass/app.scss */
+/* line 124, ../sass/app.scss */
#chatbox {
width: 90%;
font-size: 14px;
@@ -162,14 +231,14 @@ a:hover {
color: #888;
}
-/* line 89, ../sass/app.scss */
+/* line 133, ../sass/app.scss */
#chatbox:focus {
border: none;
color: #fff;
outline: none;
}
-/* line 96, ../sass/app.scss */
+/* line 140, ../sass/app.scss */
.bubble {
position: absolute;
background: #000;
@@ -187,7 +256,7 @@ a:hover {
border-radius: 8px 8px 8px 0;
}
-/* line 111, ../sass/app.scss */
+/* line 155, ../sass/app.scss */
#footer {
position: fixed;
bottom: 0;
@@ -199,19 +268,19 @@ a:hover {
color: #aaa;
z-order: -100;
}
-/* line 122, ../sass/app.scss */
+/* line 166, ../sass/app.scss */
#footer a {
color: #fff;
}
-/* line 127, ../sass/app.scss */
+/* line 173, ../sass/app.scss */
#welcome {
position: fixed;
width: 100%;
height: 100%;
background: #273;
}
-/* line 133, ../sass/app.scss */
+/* line 179, ../sass/app.scss */
#welcome #form {
background: #384;
position: absolute;
@@ -232,12 +301,12 @@ a:hover {
-o-box-shadow: 0 0 30px #005511;
box-shadow: 0 0 30px #005511;
}
-/* line 146, ../sass/app.scss */
+/* line 192, ../sass/app.scss */
#welcome #form p {
color: #051;
margin-bottom: 20px;
}
-/* line 151, ../sass/app.scss */
+/* line 197, ../sass/app.scss */
#welcome #form input {
background: #273;
border: none;
@@ -247,11 +316,11 @@ a:hover {
padding: 10px;
width: 210px;
}
-/* line 161, ../sass/app.scss */
+/* line 207, ../sass/app.scss */
#welcome #form input:focus {
outline: none;
}
-/* line 165, ../sass/app.scss */
+/* line 211, ../sass/app.scss */
#welcome #form button {
background-color: #384;
border: none;
@@ -265,12 +334,12 @@ a:hover {
-khtml-border-radius: 16px;
border-radius: 16px;
}
-/* line 174, ../sass/app.scss */
+/* line 220, ../sass/app.scss */
#welcome #form button:hover {
background-color: yellow;
color: #384;
}
-/* line 179, ../sass/app.scss */
+/* line 225, ../sass/app.scss */
#welcome #form button:disabled {
color: #384;
}
View
43 web/index.html
@@ -12,24 +12,39 @@
</head>
<body>
- <div id="console" style="display: none;">
- &gt; <input id="chatbox"/>
- </div>
+ <div id="ingame" style="display: none;">
- <div id="chat">
- Press &lt;Enter&gt; to type on chat.
- </div>
+ <div id="console" style="display: none;">
+ &gt; <input id="chatbox"/>
+ </div>
- <div id="footer">
- <p>Using: node.js, socket.io, backbone, underscore, jquery, compass, sass, html5 (css3, canvas).</p>
- <p>An open source project by <a href="http://twitter.com/cri5ti">@cri5ti.</a></p>
- <p>Fork me on <a href="https://github.com/cri5ti/html5-bomberman">GitHub</a>.</p>
- </div>
+ <div id="chat">
+ Press &lt;Enter&gt; to type on chat.
+ </div>
- <div id="map">
- </div>
+ <div id="footer">
+ <p>Using: node.js, socket.io, backbone, underscore, jquery, compass, sass, html5 (css3, canvas).</p>
+ <p>An open source project by <a href="http://twitter.com/cri5ti">@cri5ti.</a></p>
+ <p>Fork me on <a href="https://github.com/cri5ti/html5-bomberman">GitHub</a>.</p>
+ </div>
+
+ <div id="score-table">
+ <div class="score-item">
+ <div class="player">John</div>
+ <div class="score">2</div>
+ </div>
+ <div class="score-item">
+ <div class="player">Jane</div>
+ <div class="score">22</div>
+ </div>
+ </div>
+
+ <div id="map">
+ </div>
+
+ <div id="waitserver">Waiting for connection
+ </div>
- <div id="waitserver">Waiting for connection
</div>
<div id="welcome">
View
7 web/js/Character.js
@@ -17,7 +17,8 @@ define([
y: 0,
orient: ORIENT_DOWN,
moving: false,
- dead: true
+ dead: true,
+ score: 0
},
deltaMove: function(x, y) {
@@ -38,9 +39,9 @@ define([
// nothing to do..
},
- die: function() {
+ die: function(flame) {
this.set('dead', true);
- this.trigger('die', this);
+ this.trigger('die', flame);
},
sendMessage: function(msg) {
View
28 web/js/World.js
@@ -99,11 +99,15 @@ define([
var cv = new CharacterView({model: c});
this.playerViews.push(cv);
this.$container.append(cv.el);
+
+ this.updateScoring(true);
},
onCharacterRemoved: function(c) {
var cv = _.find(this.playerViews, function(v) { return v.model == c });
cv.$el.remove();
+
+ this.updateScoring(true);
// TODO FIXME: this.playerViews.remove
},
@@ -118,6 +122,7 @@ define([
var bx = b.get('x');
var by = b.get('y');
+ var owner = b.get('owner');
_.each(ortho,_.bind(function(o) {
for(var i=1; i<=strength; i++) {
@@ -127,23 +132,26 @@ define([
if (this.map.getTile(fx, fy) != 0)
return; // stop on obstacle
- this.addMergeFlame(fx, fy, i == strength ? o.e : o.d);
+ this.addMergeFlame(fx, fy, i == strength ? o.e : o.d, owner);
if (o.d == 0) return; // special case for center
}
},this));
},
- addMergeFlame: function(x, y, type) {
+ addMergeFlame: function(x, y, type, owner) {
var ef = this.map.getFlame(x,y);
if (ef) {
// merge
ef.mergeWith(type);
+
+ if (owner != this.player.id)
+ ef.set('owner', owner);
} else {
// add new
- ef = new Flame({x: x, y: y, type: type});
+ ef = new Flame({x: x, y: y, type: type, owner: owner});
this.flames.add(ef);
this.map.setFlame(x, y, ef);
}
@@ -200,11 +208,21 @@ define([
_.each(this.flamesView, function(fv){
fv.update(dt);
});
+ },
+
+ updateScoring: function(recreate) {
+ var $st = $("#score-table");
+ if (recreate) {
+ $st.empty();
+ _.each(this.players.sortBy(function(p) { return -p.get('score'); }), function(p) {
+ var si = $(scoreItem({name: p.get('name'), score: p.get('score'), color: p.get('character')}));
+ $st.append(si);
+ });
+ }
}
});
-
-
+ var scoreItem = _.template('<div class="score-item color-<%= color %>"><div class="player"><%= name %></div><div class="score"><%= score %></div></div>');
});
View
10 web/js/app.js
@@ -66,6 +66,8 @@ require([
$userid.blur();
$("#welcome").hide();
+ $("#ingame").show();
+
start(userid);
}
@@ -115,6 +117,14 @@ function info(m) {
chat(m, "info");
}
+function kill(p1, p2) {
+ chat("<div class='bomb'></div><u>"+p1+"</u> killed by <u>"+p2+"</u>", "kill");
+}
+
+function suicide(p1, p2) {
+ chat("<div class='bomb'></div><u>"+p1+"</u> suicided", "kill");
+}
+
function chat(m, cls) {
var d = $("<div>");
d.html(m);
View
3 web/js/bomb.js
@@ -12,7 +12,8 @@ define([
Bomb = Backbone.Model.extend({
defaults: {
x: 0,
- y: 0
+ y: 0,
+ owner: -1
},
initialize: function() {
View
5 web/js/flames.js
@@ -21,7 +21,8 @@ define([
defaults: {
x: 0,
y: 0,
- type: 0
+ type: 0,
+ owner: -1
},
initialize: function() {
@@ -46,6 +47,8 @@ define([
this.set('type', t);
this.trigger('merged');
+
+
}
});
View
5 web/js/local.js
@@ -98,8 +98,9 @@ define([
var cx = Math.floor(this.me.get('x'));
var cy = Math.floor(this.me.get('y'));
- if (this.world.map.getFlame(cx, cy)!=null)
- this.me.die();
+ var flame = this.world.map.getFlame(cx, cy);
+ if (flame!=null)
+ this.me.die(flame);
},
tryPlaceBomb: function() {
View
45 web/js/network.js
@@ -32,6 +32,8 @@ define([
this.socket.on('player-disconnected', $.proxy(this.onPlayerDisconnected, this));
this.socket.on('chat', $.proxy(this.onChat, this));
+ this.socket.on('score-updates', $.proxy(this.onScoreUpdates, this));
+
this.socket.on('bomb-placed', $.proxy(this.onBombPlaced, this));
this.socket.on('bomb-boomed', $.proxy(this.onBombBoomed, this));
},
@@ -57,6 +59,8 @@ define([
character: this.world.player.get('character')
});
+ this.world.player.id = this.id;
+
// mark ourself in the peer list
this.peers[this.id] = this.world.player;
},
@@ -75,8 +79,10 @@ define([
info("<u>" + d.name + "</u> joined");
console.log(d.name + " #" + d.id + " joined");
var c = new Character({
+ id: d.id,
name: d.name,
- character: d.character
+ character: d.character,
+ score: d.score
});
this.world.players.add(c);
this.peers[d.id] = c;
@@ -133,17 +139,35 @@ define([
console.log("Update from unknown #"+ d.id);
return;
}
- c.die();
+ console.log("Dying", d);
+ if (d.id != this.id)
+ c.die();
+
+ if (d.id == d.flameOwner)
+ suicide(c.get('name'));
+ else {
+ var killer = this.peers[d.flameOwner];
+ if (killer)
+ kill(c.get('name'), killer.get('name'));
+ }
},
playerChange: function(player) {
_.debounce(this.sendPlayerChange)
this.sendPlayerChange(player);
},
- playerDie: function(player) {
+ playerDie: function(flame) {
+ var flameOwner = -1;
+ if (flame) {
+ flameOwner = flame.get('owner');
+ var oc = this.peers[ flameOwner ];
+ console.log("Killed by: ", oc.get('name'));
+ }
+
this.socket.emit('dead', {
- id: this.id
+ id: this.id,
+ flameOwner: flameOwner
});
},
@@ -182,7 +206,7 @@ define([
},
onBombPlaced: function(d) {
- this.world.bombs.add(new Bomb({x:d.x, y:d.y}));
+ this.world.bombs.add(new Bomb({x:d.x, y:d.y, owner:d.owner}));
},
onBombBoomed: function(d) {
@@ -192,6 +216,17 @@ define([
// locate bomb
this.world.explodeBomb(b, d.strength);
+ },
+
+ onScoreUpdates: function(d) {
+ console.log("score updates: ", d);
+
+ _.each(d, _.bind(function(score, id) {
+ var p = this.peers[id];
+ if (p) p.set('score', score);
+ }, this));
+
+ this.world.updateScoring(true);
}
});
View
BIN web/res/char-betty.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN web/res/char-joe.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN web/res/char-mary.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
46 web/sass/app.scss
@@ -37,6 +37,16 @@ canvas {
.mychat {
color: #fff;
}
+
+ .kill {
+ color: #fa6;
+ }
+
+ .bomb {
+ display: inline-block;
+ vertical-align: middle;
+ margin: 0 5px;
+ }
}
a {
@@ -51,6 +61,10 @@ a:hover {
color: #fff;
}
+#map {
+ position: absolute;
+ top: 20px;
+}
#console {
position: fixed;
@@ -64,6 +78,36 @@ a:hover {
@include box-shadow(#000 0px -3px 20px);
}
+#score-table {
+ padding: 12px;
+ font: 13px Arial;
+ background: black;
+ border-bottom: solid 1px #4A4;
+
+ .score-item {
+ display: inline-block;
+ margin: 0 10px;
+ color: #aaa;
+
+ .player {
+ display: inline-block;
+ margin-right: 3px;
+ }
+
+ .score {
+ display: inline-block;
+ font-size: 15px;
+ padding: 2px 10px;
+ @include border-radius(10px);
+ }
+ }
+
+ .score-item.color-mary .score { background: #a00; color: #fd6; }
+ .score-item.color-john .score { background: #fff; color: #33f; }
+ .score-item.color-joe .score { background: #333; color: #0f0; border: solid 1px #0f0; padding: 0 8px; }
+ .score-item.color-betty .score { background: #05e; color: #ffa; }
+}
+
#waitserver {
position: absolute;
top: 0;
@@ -124,6 +168,8 @@ a:hover {
+
+
#welcome {
position: fixed;
width: 100%;

0 comments on commit ef9810d

Please sign in to comment.