我正在尝试使用事件侦听器和排放来复制后院捕捞游戏。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>
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句