var publisher = {
// 订阅者数组
subscribers : {
"any" : []
},
// 增加订阅者
on : function(type, fn, context){
var subscribers = this.subscribers;
type = type || "any";
context = context || this;
fn = typeof fn === "function" ? fn : context[fn];
if(!subscribers[type]){
subscribers[type] = [];
}
subscribers[type].push({"fn" : fn, "context" : context});
},
// 移除订阅者
off : function(type, fn, context){
this.visit("unPublish", type, fn, context)
},
// 通知
fire : function(type, arg){
this.visit("publish", type, arg);
},
// 访问订阅者数组
visit : function(action, type, arg, context){
var subscribers, i, len;
type = type || "any";
subscribers = this.subscribers[type];
len = subscribers.length || 0;
switch(action){
case "publish" :
for(i = 0; i < len; i++){
subscribers[i].fn.call(subscribers[i].context, arg);
}
break;
case "unPublish":
for(i = 0; i < len; i++){
if(subscribers[i].fn === arg && subscribers[i].context === context){
subscribers.splice(i, 1);
}
}
break;
}
}
};
function makePublisher(o){
o.subscribers = {"any" : []};
for(var p in publisher ){
if(publisher.hasOwnProperty(p) && typeof publisher[p] === "function"){
o[p] = publisher[p];
}
}
return o;
}
// 发布者Play
// 发布两个事件:1、有玩家加入 2、玩家开始玩
function Player(name, key){
this.point = 0;
this.name = name;
this.key = key;
this.fire("add", this);
}
Player.prototype.play = function(){
this.point += 1;
this.fire("play", this);
};
// 观察者/订阅者 game,观察2个事件:1、有玩家加入 2、玩家开始玩
// 同时作为发布者game,通知积分榜更新
var game = {
// 存储对象和按键key的关系
keys : {},
// 订阅
addPlayer : function(player){
this.keys[player.key] = player;
},
// 通知订阅者scoreboard更新
handlyPlay : function(){
var score = {}, keys = this.keys, p;
for(p in keys){
if(keys.hasOwnProperty(p)){
score[keys[p].name] = keys[p].point;
}
}
this.fire("update", score);
},
// 封装keypress事件
keydown : function(e){
var which, code;
e = e || event;
which = e.which || e.keyCode;
code = String.fromCharCode(which);
if(this.keys[code]){
this.keys[code].play();
}
}
};
// 积分榜
var scoreboard = {
dom : document.getElementById("score_board"),
// 更新积分榜 参数格式 {playname1 : point, playname2 : point }
update : function(score){
var p, html = "";
for(p in score){
if(score.hasOwnProperty(p)){
html += p + "获得了" + score[p] + "<br/>";
}
}
this.dom.innerHTML = html;
}
};
// Player作为发布者,因其需要通知订阅者game新增玩家以及玩家积分变化
// game对Player而言是订阅者,因其需要订阅Player的特定活动add(新增玩家)和play(玩家积分发生变化)
// game对scoreboard而言是发布者,因其在观察到Player的play事件之后需要通知scoreboard更新积分
makePublisher(Player.prototype);
makePublisher(game);
Player.prototype.on("add", game.addPlayer, game);
Player.prototype.on("play", game.handlyPlay, game);
game.on("update", scoreboard.update, scoreboard);
//excute
while(true){
var name = prompt("say your name, man"), key;
if(name && name !== "null"){
while(true){
key = prompt("what is your key");
if(key && key !== "null"){
break;
}
alert("亲,还是指定个key吧,不然你没办法玩的,相信我");
}
new Player(name, key);
}
else {
break;
}
}
document.onkeydown = function(e){
game.keydown.call(game, e);
};