Использование Object.create в цикле forEach
Я пишу карточную игру, используя javascript/html5
Я получаю состояние игры как запрос ajax. это данные JSON, в которых перечислены игроки и какие карты у них в руке
Я пытаюсь перебрать каждого игрока и установить данные руки следующим образом
gameState.Players.forEach(function (player, i) {
var inx = i + 1;
var canvas = document.getElementById("player" + inx);
var ctx = canvas.getContext("2d");
var hand = Object.create(Hand);
hand.initialiseHand(player.Hand);
hand.setPosition(10, 10);
hand.draw(ctx);
});
На странице шесть полотен. Один на каждого игрока
Я использую Object.create для создания нового "экземпляра" руки. И затем вызывая метод draw, который выкладывает изображения на холст
Однако на самом деле происходит то, что данные каждого игрока просто добавляются в один и тот же экземпляр.
т.е. каждый раз, когда я обхожу цикл forEach, объекту раздачи просто назначается все больше и больше карт
Я хотел бы иметь отдельный экземпляр для каждого игрока
Так как мне этого добиться?
Я хочу перебрать данные и создать новую руку для каждой итерации цикла
Я предполагаю, что переменная hand была выведена из цикла, и поэтому я получаю одно и то же каждый раз?
и вот как выглядит Рука
var Hand = {
faceDownCards: [],
faceUpCards: [],
inHandCards: [],
initialiseHand: function (handData) {
handData.FaceDownCards.forEach(function (c, i) {
this.faceDownCards.push(Object.create(Card, pd({ rank: c.Rank, suit: c.Suit })));
}, this);
handData.FaceUpCards.forEach(function (c, i) {
this.faceUpCards.push(Object.create(Card, pd({ rank: c.Rank, suit: c.Suit })));
}, this);
handData.InHandCards.forEach(function (c, i) {
this.inHandCards.push(Object.create(Card, pd({ rank: c.Rank, suit: c.Suit })));
}, this);
},
draw: function (context) {
this.faceDownCards.forEach(function (c, i) {
c.draw(context);
});
this.faceUpCards.forEach(function (c, i) {
c.draw(context);
});
this.inHandCards.forEach(function (c, i) {
c.draw(context);
});
},
setPosition: function (x, y) {
this.x = x;
this.y = y;
this.faceDownCards.forEach(function (c, i) {
c.setPosition(x + i * 70, y);
});
this.faceUpCards.forEach(function (c, i) {
c.setPosition(x + i * 70, y + 60);
});
this.inHandCards.forEach(function (c, i) {
c.setPosition(x + i * 20, y + 80);
//c.rotation = 3;
});
}
};
1 ответ
Ваша ручная переменная не выводится из цикла. Переменные Javascript имеют область действия функции, и вам уже удобно использовать функцию внутри цикла forEach.
Что такое Hand
? Обычное соглашение гласит, что имена с заглавными буквами представляют функции конструктора, но Players и Object.create делают его похожим Hand
это просто объект?
Если Hand
это уже объект (а не конструктор, которым вы злоупотребляете), лучше всего было бы, чтобы initializeHand / setPosition устанавливали закрытые переменные вместо доступа к ним через this
, (Конечно, это просто дикое предположение, не глядя на Hand
код)
Посмотрев на ваш Hand
код, я теперь думаю, что проблема в том, что руки разделяют faceDownCards
и т. д., массивы. Базовый прототип должен использоваться только для общих черт, а массивы и другое состояние экземпляра должны быть установлены при инициализации:
Для конкретного примера измени
handData.FaceDownCards.forEach(function (c, i) {
this.faceDownCards.push(Object.create(Card, pd({ rank: c.Rank, suit: c.Suit })));
}, this);
в
this.faceDownCards = handData.FaceDownCards.map(function (c, i) {
return Object.create(Card, pd({ rank: c.Rank, suit: c.Suit }));
});
PS: все, что происходит с Object.create - это не совсем идиоматический Javascript. Но тогда, я думаю, у вас должна быть идея о том, что вы делаете, верно?