Skip to content

Instantly share code, notes, and snippets.

@KalpasWang
Created December 26, 2019 15:30
Show Gist options
  • Save KalpasWang/117408fb9bad3d8cb62ff337f444fced to your computer and use it in GitHub Desktop.
Save KalpasWang/117408fb9bad3d8cb62ff337f444fced to your computer and use it in GitHub Desktop.
觀察者模式範例2–按鍵遊戲
<!DOCTYPE html>
<!-- saved from url=(0051)http://www.jspatterns.com/book/7/observer-game.html -->
<html><head><meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
<title>Keypress challenge</title>
<style>
#results {text-align: center; font-size: 36px;}
strong {color: blue;}
</style>
</head>
<body cz-shortcut-listen="true">
<div id="results"></div>
<script>
var publisher = {
subscribers: {
any: []
},
on: function (type, fn, context) {
type = type || 'any';
fn = typeof fn === "function" ? fn : context[fn];
if (typeof this.subscribers[type] === "undefined") {
this.subscribers[type] = [];
}
this.subscribers[type].push({fn: fn, context: context || this});
},
remove: function (type, fn, context) {
this.visitSubscribers('unsubscribe', type, fn, context);
},
fire: function (type, publication) {
this.visitSubscribers('publish', type, publication);
},
visitSubscribers: function (action, type, arg, context) {
var pubtype = type || 'any',
subscribers = this.subscribers[pubtype],
i,
max = subscribers ? subscribers.length : 0;
for (i = 0; i < max; i += 1) {
if (action === 'publish') {
subscribers[i].fn.call(subscribers[i].context, arg);
} else {
if (subscribers[i].fn === arg && subscribers[i].context === context) {
subscribers.splice(i, 1);
}
}
}
}
};
function makePublisher(o) {
var i;
for (i in publisher) {
if (publisher.hasOwnProperty(i) && typeof publisher[i] === "function") {
o[i] = publisher[i];
}
}
o.subscribers = {any: []};
}
var game = {
keys: {},
addPlayer: function (player) {
var key = player.key.toString().charCodeAt(0);
this.keys[key] = player;
},
handleKeypress: function (e) {
e = e || window.event; // IE
if (game.keys[e.which]) {
game.keys[e.which].play();
}
},
handlePlay: function (player) {
var i,
players = this.keys,
score = {};
for (i in players) {
if (players.hasOwnProperty(i)) {
score[players[i].name] = players[i].points;
}
}
this.fire('scorechange', score);
}
};
function Player(name, key) {
this.points = 0;
this.name = name;
this.key = key;
this.fire('newplayer', this);
}
Player.prototype.play = function () {
this.points += 1;
this.fire('play', this);
};
var scoreboard = {
element: document.getElementById('results'),
update: function (score) {
var i, msg = '';
for (i in score) {
if (score.hasOwnProperty(i)) {
msg += '<p><strong>' + i + '<\/strong>: ';
msg += score[i];
msg += '<\/p>';
}
}
this.element.innerHTML = msg;
}
};
makePublisher(Player.prototype);
makePublisher(game);
Player.prototype.on("newplayer", "addPlayer", game);
Player.prototype.on("play", "handlePlay", game);
game.on("scorechange", scoreboard.update, scoreboard);
window.onkeypress = game.handleKeypress;
var playername, key;
while (1) {
playername = prompt("Add player (name)");
if (!playername) {
break;
}
while (1) {
key = prompt("Key for " + playername + "?");
if (key) {
break;
}
}
new Player(playername, key);
}
</script>
<div class="xl-chrome-ext-bar" id="xl_chrome_ext_{4DB361DE-01F7-4376-B494-639E489D19ED}" style="display: none;">
<div class="xl-chrome-ext-bar__logo"></div>
<a id="xl_chrome_ext_download" href="javascript:;" class="xl-chrome-ext-bar__option">&#19979;&#36733;&#35270;&#39057;</a>
<a id="xl_chrome_ext_close" href="javascript:;" class="xl-chrome-ext-bar__close"></a>
</div></body></html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment