Architecture of player hand in JavaScript card game
So, i'm attempting simple card game. I have player
"class" with draw
function, and public members deck
and hand
, both are Arrays.
I need to draw a card from the deck, put it in hand and show it in player "hand" area. I'm concerned about the way I do "flip" and "play" buttons (through closures).
Here is the code:
littlegame.player.prototype.draw = function() {
if (this.canDrawCard()) {
var card = this.deck.draw(); // this.deck is Array
//Create card element on the playfield
var card_object = $('<div class="card"></div>').append($('<span class="attack">' + card.attack + '</span>')).append($('<span class="defence">' + card.defence + '</span>'));
// Add controls to card
if (this.playerid == 1) {
var flipper = $('<span class="flip">Flip</span>');
flipper.click(function(){
card.flip();
});
var actuator = $('<span class="play">Play</span>');
console.log('Loading actuator closure with id ' + this.playerid + ' and name ' + this.playername);
var player = this;
var old_hand = this.hand.slice(0); // Store a copy of old hand. Stupid trick, i know. It doesn't work
actuator.click(function(){
card.play(player.playerid);
delete card;
player.hand = old_hand;
});
card_object = card_object.append(flipper).append(actuator);
}
this.element.append(card_object);
card.element = card_object;
// Put card in hand
this.hand.push(card);
}
};
What i need i开发者_JAVA技巧s a way to call card.play()
and card.flip()
on corresponding button presses, with card.play
knowing card position in hand, to remove the card. How can I do this?
littlegame.player.prototype.draw = function() {
if (this.canDrawCard()) {
var card = this.deck.draw(); // this.deck is Array
//Create card element on the playfield
var card_object = $('<div class="card"></div>').append($('<span class="attack">' + card.attack + '</span>')).append($('<span class="defence">' + card.defence + '</span>'));
// Add controls to card
if (this.playerid == 1) {
var flipper = $('<span class="flip">Flip</span>');
flipper.click(function(){
card.flip();
});
var actuator = $('<span class="play">Play</span>');
console.log('Loading actuator closure with id ' + this.playerid + ' and name ' + this.playername);
var player = this;
var old_hand = this.hand.slice(0); // Store a copy of old hand. Stupid trick, i know. It doesn't work
actuator.click(function(){
card.play(player.playerid);
delete card;
player.hand = old_hand;
});
card_object = card_object.append(flipper).append(actuator);
}
this.element.append(card_object);
card.element = card_object;
// Put card in hand
this.hand.push(card);
var hand = this.hand;
card.remove = function () {
var i;
for(i=0;i<hand.length;i++) {
if(hand[i]===this) {
hand.splice(i,1);
}
}
}
}
};
The key here is to define the remove function in the scope that contains the variables you're interested in. Here, I define the variable hand
, which makes it available inside the remove function that I define immediately after. You can then call the remove function whenever you like.
If you know that the card will not change position within the hand, you can shortcut by making the index some variable (say, cardposition
) and simply splice your array there, or whatever it is you want to do with your array.
I tried the following. I had to leave position of card in hand array in the closure along with links to player and the card itself. It goes like this:
littlegame.player.prototype.draw = function() {
if (this.hand.length < this.agility) {
var card = this.deck.draw();
// Put card in hand
this.hand.push(card);
var card_in_hand = this.hand[this.hand.length - 1];
var card_position = this.hand.length;
//Create card element on the playfield
var card_object = $('<div class="card"></div>').append($('<span class="attack">' + card.attack + '</span>')).append($('<span class="defence">' + card.defence + '</span>'));
// Add controls to card
if (this.playerid == 1) {
var flipper = $('<span class="flip">Flip</span>');
flipper.click(function(){
card_in_hand.flip();
});
var actuator = $('<span class="play">Play</span>');
console.log('Loading actuator closure with id ' + this.playerid + ' and name ' + this.playername);
var player = this;
actuator.click(function(){
card_in_hand.play(player.playerid);
player.hand.remove(card_position);
});
card_object = card_object.append(flipper).append(actuator);
}
this.element.append(card_object);
card_in_hand.element = card_object;
}
};
I also used Array.remove()
function from John Resig.
精彩评论