>[success] # 中介者模式 ~~~ ~~~ >[info] ## 书中泡泡堂游戏例子 ~~~ ~~~ >[danger] ##### 书中作者最初构想写的思路 ~~~ 1.定义一个玩家类'Player',玩家类属性分别有'name 用户名字','enemy 用户的敌人对象', 'win 胜利触发的方法','lose 失败触发的方法','die 角色死亡执行触发自己失败方法和对手的胜利方法' ~~~ ~~~ // 定义一个玩家类 function Player(name){ this.name = name this.enemy = null // 敌人 } // 胜利方法 Player.prototype.win = function () { console.log(this.name + 'won') } // 失败方法 Player.prototype.lose = function () { console.log(this.name+'lose') } // 死亡方法 Player.prototype.die = function () { this.lose(); this.enemy.win() } // -------------创建生成用户-------------- var player1 = new Player('w') var player2 = new Player('c') player1.enemy = player2 player2.enemy = player1 player1.die() ~~~ >[danger] ##### 代码升级 增加玩家 ~~~ 1.刚才的玩家是两个人这把玩家增加到八个人,玩家数量增多后,刚才的'Player'类也需要 进行简单的合理化升级 2.现在的玩家类比刚才多了'一群对手'和'一群队友',因此'enemies 变成数组用来存储敌人', 还多了一个'partners 队友列表','state 当前玩家状态','teamColor 队伍颜色' 3.在方法上'die' 方法和之前不同,思路是玩家如果死亡循环玩家的所有的队友看看是不是都死了, 如果都死了就通知所有失败玩家和胜利玩家 4.整个案例还创建了一个工厂函数,用来分配没给个队伍的对应队友 ~~~ ~~~ function Player(name, teamColor) { this.partners = [] // 队友列表 this.enemies = [] // 敌人列表 this.state = 'live' // 玩家状态 this.name = name // 玩家姓名 this.teamColor = teamColor // 队伍颜色 } // 玩家胜利触发的方法 Player.prototype.win = function () { console.log('winner' + this.name) } // 玩家失败触发的方法 Player.prototype.lose = function () { console.log('loser' + this.name) } // 玩家死亡触发的方法 Player.prototype.die =function () { var all_dead = true this.state = 'dead' // 玩家状态死亡 for(var i = 0,partner;partner = this.partners[i++];){ if(partner.state !== 'dead'){ // 队伍中还有玩家没死以为队伍还没有失败 all_dead = false break } } if(all_dead === true){ this.lose() for ( var i = 0, partner; partner = this.partners[ i++ ]; ){ // 通知所有队友玩家游戏失败 partner.lose(); } for ( var i = 0, enemy; enemy = this.enemies[ i++ ]; ){ // 通知所有敌人游戏胜利 enemy.win(); } } } var players = []; var playerFactory = function( name, teamColor ){ var newPlayer = new Player( name, teamColor ); // 创建新玩家 for ( var i = 0, player; player = players[ i++ ]; ){ // 通知所有的玩家,有新角色加入 if ( player.teamColor === newPlayer.teamColor ){ // 如果是同一队的玩家 player.partners.push( newPlayer ); // 相互添加到队友列表 newPlayer.partners.push( player ); }else{ player.enemies.push( newPlayer ); // 相互添加到敌人列表 newPlayer.enemies.push( player ); } } players.push( newPlayer ); return newPlayer; }; // --------使用------- //红队: var player1 = playerFactory( '皮蛋', 'red' ), player2 = playerFactory( '小乖', 'red' ), player3 = playerFactory( '宝宝', 'red' ), player4 = playerFactory( '小强', 'red' ); //蓝队: var player5 = playerFactory( '黑妞', 'blue' ), player6 = playerFactory( '葱头', 'blue' ), player7 = playerFactory( '胖墩', 'blue' ), player8 = playerFactory( '海盗', 'blue' ); // 红队团灭 player1.die(); player2.die(); player4.die(); player3.die(); ~~~ >[danger] ##### 总结这两版的代码 ~~~ 1.' 问题:' 1.1.每个对象的状态发生改变,比如角色移动、吃到道具或者死亡 时,都必须要显式地遍历通知其他对象。 如果任务角色上升到几百,那么每次玩家死亡都要需要循环他的队友来判断是否队伍失败,让整个代码, 每个玩家和其他玩家都是紧 紧耦合在一起的。 ~~~