首先我们可以根据队颜色来判断是队友还是敌人;同样也有三个方法win(赢),lose(输),和die(死亡);如果每次死亡一个人的时候,循环下该死亡的队友有没有全部死亡,如果全部死亡了的话,就输了,因此需要循环他们的队友,分别告诉每个队友中的成员他们输了,同时需要循环他们的敌人,分别告诉他们的敌人他们赢了;因此每次死了一个人的时候,都需要循环一次判断他的队友是否都死亡了;因此每个玩家和其他的玩家都是紧紧耦合在一起了。
下面我们可以使用中介者模式来改善上面的demo;
首先我们仍然定义Hero构造函数和Hero对象原型的方法,在Hero对象的这些原型方法中,不再负责具体的执行的逻辑,而是把操作转交给中介者对象,中介者对象来负责做具体的事情,我们可以把中介者对象命名为playerDirector;
在playerDirector开放一个对外暴露的接口ReceiveMessage,负责接收player对象发送的消息,而player对象发送消息的时候,总是把自身的this作为参数发送给playerDirector,以便playerDirector 识别消息来自于那个玩家对象。
代码如下:
var players = []; // 定义一个数组 保存所有的玩家 function Hero(name,teamColor) { this.state = 'live'; // 玩家状态 this.name = name; // 角色名字 this.teamColor = teamColor; // 队伍的颜色 } Hero.prototype.win = function(){ // 赢了 console.log("win:" + this.name); }; Hero.prototype.lose = function(){ // 输了 console.log("lose:" + this.name); }; // 死亡 Hero.prototype.die = function(){ this.state = 'dead'; // 给中介者发送消息,玩家死亡 playerDirector.ReceiveMessage('playerDead',this); } // 移除玩家 Hero.prototype.remove = function(){ // 给中介者发送一个消息,移除一个玩家 playerDirector.ReceiveMessage('removePlayer',this); }; // 玩家换队 Hero.prototype.changeTeam = function(color) { // 给中介者发送一个消息,玩家换队 playerDirector.ReceiveMessage('changeTeam',this,color); }; // 定义一个工厂类来创建玩家 var heroFactory = function(name,teamColor) { // 创建一个新的玩家对象 var newHero = new Hero(name,teamColor); // 给中介者发送消息,新增玩家 playerDirector.ReceiveMessage('addPlayer',newHero); return newHero; }; var playerDirector = (function(){ var players = {}, // 保存所有的玩家 operations = {}; // 中介者可以执行的操作 // 新增一个玩家操作 operations.addPlayer = function(player) { // 获取玩家队友的颜色 var teamColor = player.teamColor; // 如果该颜色的玩家还没有队伍的话,则新成立一个队伍 players[teamColor] = players[teamColor] || []; // 添加玩家进队伍 players[teamColor].push(player); }; // 移除一个玩家 operations.removePlayer = function(player){ // 获取队伍的颜色 var teamColor = player.teamColor, // 获取该队伍的所有成员 teamPlayers = players[teamColor] || []; // 遍历 for(var i = teamPlayers.length - 1; i>=0; i--) { if(teamPlayers[i] === player) { teamPlayers.splice(i,1); } } }; // 玩家换队 operations.changeTeam = function(player,newTeamColor){ // 首先从原队伍中删除 operations.removePlayer(player); // 然后改变队伍的颜色 player.teamColor = newTeamColor; // 增加到队伍中 operations.addPlayer(player); }; // 玩家死亡 operations.playerDead = function(player) { var teamColor = player.teamColor, // 玩家所在的队伍 teamPlayers = players[teamColor]; var all_dead = true; //遍历 for(var i = 0,player; player = teamPlayers[i++]; ) { if(player.state !== 'dead') { all_dead = false; break; } } // 如果all_dead 为true的话 说明全部死亡 if(all_dead) { for(var i = 0, player; player = teamPlayers[i++]; ) { // 本队所有玩家lose player.lose(); } for(var color in players) { if(color !== teamColor) { // 说明这是另外一组队伍 // 获取该队伍的玩家 var teamPlayers = players[color]; for(var i = 0,player; player = teamPlayers[i++]; ) { player.win(); // 遍历通知其他玩家win了 } } } } }; var ReceiveMessage = function(){ // arguments的第一个参数为消息名称 获取第一个参数 var message = Array.prototype.shift.call(arguments); operations[message].apply(this,arguments); }; return { ReceiveMessage : ReceiveMessage }; })(); // 红队 var p1 = heroFactory("aa",'red'), p2 = heroFactory("bb",'red'), p3 = heroFactory("cc",'red'), p4 = heroFactory("dd",'red'); // 蓝队 var p5 = heroFactory("ee",'blue'), p6 = heroFactory("ff",'blue'), p7 = heroFactory("gg",'blue'), p8 = heroFactory("hh",'blue'); // 让红队玩家全部死亡 p1.die(); p2.die(); p3.die(); p4.die(); // lose:aa lose:bb lose:cc lose:dd // win:ee win:ff win:gg win:hh