簡體   English   中英

如何聆聽另一個物體的事件發射?

[英]How to listen to another object's event emissions?

我正在嘗試使用事件偵聽器和排放來復制后院捕撈游戲。 A人“拋出”,並且-在十分之九的時間內-B人“抓住”,然后拋出。 任何人都無法抓住自己的目標。 我該怎么做呢? 下面的示例/偽代碼。

var events = require('events'),
    EventEmitter = require('events').EventEmitter;

var a = new EventEmitter(),
    b = new EventEmitter();

a.on('start', function() {
  this.emit('throw', b);
})

a.on('catch', function() {
  console.log('a caught b\'s throw');
  this.emit('throw', b);
});

b.on('catch', function() {
  console.log('b caught a\'s throw');
  this.emit('throw', a);
});

a.emit('start');

如果我想將游戲擴展到包括第三個人,該怎么辦(在這種情況下,投擲的目標只能是兩個可能的接收者之一)

我不完全了解您的游戲如何運作,因此我使用不同的游戲邏輯對游戲進行了編碼。 但是您可以輕松地根據自己的需要進行調整。

游戲的工作原理如下:

每個玩家交替交替投擲兩個骰子。 第一個玩家1比玩家2擲骰子,依此類推。 每個玩家可以隨機抓取其他玩家的骰子。 抓到的骰子被加到分數中,得分最高的玩家將贏得比賽。

現在到代碼。 起初,我沒有看到您正在做一個nodeJs應用程序。 但是我的前端應用程序應該可以通過一些調整在節點上運行。

我已將SignalsJS用於事件。 您可以在此處找到示例。

以下引用來自這里

信號類似於事件發射器/分派器或發布/訂閱系統,主要區別在於每種事件類型都有其自己的控制器,並且不依賴於字符串來廣播/訂閱事件

將signalJS視為發布者和訂閱者系統是最好的了解它在做什么的方法。

訂閱者/收聽者正在偵聽來自發布者的事件。 一旦發布者分發了某些內容,將調用訂閱者的回調。

為了管理事件,您需要某種注釋中建議的中介者,以便您能夠處理所有事情。 在我的演示中,對象DiceGame充當中介程序,因為它將玩家和擲出的骰子保持在數組中。

請在下面和jsFiddle中找到游戲演示。

(如果有什么需要改進的地方,請在評論中讓我知道。)

  //store local reference for brevity var Signal = signals.Signal; /* // simple signals demo code here as an example //custom object that dispatch signals var dice = { threw: new Signal(), //past tense is the recommended signal naming convention carched: new Signal() }; function onThrew(param1, param2) { console.log(param1 + param2); } dice.threw.add(onThrew); //add listener dice.threw.dispatch('user1', ' - dice no. = 6'); //dispatch signal passing custom parameters dice.threw.remove(onThrew); //remove a single listener */ var DiceGame = function(settings) { this.settings = $.extend(DiceGame.defaultSettings, settings); var activePlayer = {}; this.addPlayer = function() { var index = this.players.push({ name: 'player' + (this.players.length + 1), //custom object that dispatch signals dice: { threw: new Signal(), //past tense is the recommended signal naming convention catched: new Signal() }, score: 0, dicesThrown: 0 }); activePlayer = this.players[index-1]; activePlayer.index = index-1; this.setActivePlayer(activePlayer); // add display listener activePlayer.dice.threw.add(this.onDiceThrew, this); activePlayer.dice.catched.add(this.onDiceCatched, this); //console.log(this.players, index, this.$activePlayerInfo, activePlayer); }; this.getActivePlayer = function() { return activePlayer; }; this.setActivePlayer = function(player, index){ if ( typeof index != 'undefined' ) { console.log(index, this.players[index]); activePlayer = this.players[index]; } else { activePlayer = player; } this.updatePlayerInfo(activePlayer.name); this.$activePlayerScore.html(activePlayer.score); }; this.initGame = function() { this.$activePlayerInfo = $(this.settings.elActivePlayer); this.$activePlayerScore = $(this.settings.elActivePlayerScore); this.$gameInfo = $(this.settings.elGameInfo); this.$playField = $(this.settings.elPlayField); // add click handlers (bind to DiceGame obj. with this) $('#newGame').click(this.reset.bind(this)); $('#addPlayer').click(this.addPlayer.bind(this)); $('#changePlayer').click(this.nextPlayer.bind(this)); $('#throw').click(this.throwDice.bind(this)); $('#catch').click(this.catchDice.bind(this)); // add two players _.each(new Array(this.settings.defaultPlayerCount), function(){ this.addPlayer(); }, this); this.setActivePlayer(null, 0); // can change current player by index } this.initGame(); }; DiceGame.defaultSettings = { elActivePlayer: '#activePlayer', elActivePlayerScore: '#activePlayerScore', elGameInfo: '#gameInfo', elPlayField: '#playField', defaultPlayerCount: 2, maxThrownCount: 2 }; DiceGame.prototype = { players: [], diceList: [], updatePlayerInfo: function(text) { this.$activePlayerInfo.html(text); }, reset: function() { this.diceList = []; $.each(this.players, function(index, item) { console.log(item); item.score = 0; item.dicesThrown = 0; }); this.setActivePlayer(null, 0); // can change current player by index this.refreshPlayField(); //this.showGameInfo(''); this.hideGameInfo(); }, nextPlayer: function() { var index = this.getActivePlayer().index; index++; if (index >= this.players.length ) { //'roll over' required! index = 0; } //var playerCopy = this.players.slice(0); this.setActivePlayer(this.players[index]); // next player }, onDiceThrew: function(diceNo) { console.log('threw dice', diceNo); var newDice = {player: this.getActivePlayer(), diceValue: diceNo}; if ( newDice.player.dicesThrown < this.settings.maxThrownCount ) { this.diceList.push(newDice); this.$playField.append($('<p/>').text(newDice.player.name + ' - threw dice: ' +newDice.diceValue)); //console.log('threw', this.diceList); newDice.player.dicesThrown++; } else { //alert(newDice.player.dicesThrown+ ' dices thrown. None left.'); //show message that all dices are thrown this.showGameInfo(newDice.player.dicesThrown+ ' dices thrown. None left.'); return; } console.log(newDice); this.nextPlayer(); // change to next player }, checkGameOver: function() { // all thrown and nothing to catch --> game is over var winner = _.max(this.players, function(player) { console.log(player); return player.score; }); console.log("winner", winner, this.players); var otherPlayers = _.omit(this.players, function(value) { console.log('value', value, value===winner); return value === winner;}); var scoresStr = ''; _.each(otherPlayers, function(player) { scoresStr += player.name + ': ' + player.score + '<br/>'; }); // check if we have a draw. //this.players[0].score = 5; // needed for testing //this.players[1].score = 5; var draw = _.every(this.players, function(player) { return player.score === winner.score; }); console.log(draw); if (draw) { this.showGameInfo('Game over!<br/>Draw with score ' + winner.score, true); } else { // call showGameInfo with true --> keeps message displayed this.showGameInfo('Game over!<br/>' + winner.name + ' wins the game with score ' + winner.score + '!<br/>Other scores:<br/>' + scoresStr, true); } }, onDiceCatched: function() { // catch one dice of other player var player = this.getActivePlayer(); var diceList = this.diceList.slice(0); // copy dice list var allowedDice = _.filter(diceList, function(dice) { return dice.player.name !== player.name; }); var catched = allowedDice[Math.floor(Math.random()*allowedDice.length)]; // console.log('catched dice = ', catched); // add score to active player if ( catched ) { player.score += catched.diceValue; this.$activePlayerScore.html(player.score); // update play field var newDiceList = this.removeItem(diceList, catched); this.diceList = newDiceList.slice(0); // copy new list to the dice list this.refreshPlayField(); var allDone = _.every(this.players.dicesThrown, function(element) { return element == this.settings.maxThrownCount; }); if ( this.diceList.length == 0 && allDone ){ this.checkGameOver(); } } else { // nothing catched // check if game is over? if yes, who is the winner? if ( player.dicesThrown >= this.settings.maxThrownCount ) { this.checkGameOver(); return; } } this.nextPlayer(); // change to next player }, removeItem: function(array, id) { // remove dice from list return _.reject(array, function(item) { //console.log(item, id, item===id); return item === id; // or some complex logic }); }, refreshPlayField: function() { var $field = this.$playField, $row = $('<p/>'); $field.empty(); $.each(this.diceList, function(index, item) { console.log(index, item); $row.text(item.player.name + ' - threw dice: ' +item.diceValue) $field.append($row.clone()); }); }, showGameInfo: function(message, keep) { var $info = this.$gameInfo; $info.html(message); // show info with jQuery animation $info .stop() .animate({opacity:1}, 'fast'); if ( !keep ) { // don't auto hidde --> required for game over $info .delay(2000) // display time of message .animate({opacity:0},'fast'); } }, hideGameInfo: function() { // required to hide gameover message this.$gameInfo.stop() .animate({opacity:0}, 'fast'); // also stop every animation if any is active }, throwDice: function() { var player = this.getActivePlayer(); player.dice.threw.dispatch(Math.floor(Math.random()*6+1)); }, catchDice: function() { console.log('catch dice method'); var player = this.getActivePlayer(); player.dice.catched.dispatch(); } } $(function() { // start game after DOM ready var game = new DiceGame(); }); 
 .playerInfo { position: absolute; top: 0px; right: 10px; border: 1px solid black; width: 200px; } #gameInfo { opacity: 0; margin: 0 auto; color: red; text-align: center; width: 300px; height: 100px; /* center div horizontally and vertically */ position:absolute; left:50%; top:50%; margin:-50px 0 0 -150px; border: 0px solid black; background-color: #FAFFBF; } 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.7.0/underscore.js"></script> <script src="https://cdn.rawgit.com/millermedeiros/js-signals/master/dist/signals.js"></script> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <button id="newGame">New Game</button> <button id="addPlayer">New Player</button> <!-- <button id="changePlayer">Change player</button> --> <button id="throw">Throw dice</button> <button id="catch">Catch dice</button> <div class="playerInfo"> Active player: <span id="activePlayer"></span><br/> Score: <span id="activePlayerScore"></span> </div> <div id="gameInfo"></div> <div id="playField"></div> 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM