Сращивание Javascript изменяет более ранние значения в массиве

Я создаю игру, которая случайным образом отображает круги на холсте. Объекты кругов добавляются в массив, и всякий раз, когда игрок сталкивается с одним из них, я хочу удалить этот объект. Вот мой код в настоящее время для столкновения -

    for(var i = 0; i < currentGame.items.length; i++)
    {
        if (player1.x < currentGame.items[i].x + currentGame.items[i].radius*2  && player1.x + currentGame.items[i].radius*2  > currentGame.items[i].x &&
                player1.y < currentGame.items[i].y + currentGame.items[i].radius*2 && player1.y + player1.car.height > currentGame.items[i].y) {
            currentGame.score++;
            position = currentGame.items.indexOf(i);
            currentGame.items.splice(position, 1);
        }
    }

Этот код отлично работает, когда игрок попадает в последний круг, который был добавлен в массив / холст. Однако, если игрок нажимает на круги, которые находятся в середине массива, тогда все последующие элементы массива также будут удалены (не предыдущие). Счет игроков будет увеличен, однако многие круги будут удалены. Это говорит о том, что когда один из кругов удален, элементы сдвигаются вниз и занимают место только что удаленного, включая взятие его координат позиции, так что игрок сталкивается со всеми из них, и все они затем удаляются.

Я не знаю, как это исправить, или если я использую сращивания неправильно.

Вот мой код для добавления в массив -

function createItem(){
    item1 = new itemSmall();
    item1.x = Math.floor(Math.random()*((currentGame.windowWidth - 40)-40+1)+40);
    item1.y = Math.floor(Math.random()*((currentGame.windowHeight - 40)-40+1)+40);
    item1.fillStyle = "rgb(200,80,200)";
    item1.lineWidth = 4; //Stroke Thickness
    item1.strokeStyle = "rgb(255,215,0)";

    currentGame.items.push(item1);
}

элементы хранятся здесь (я убрал все остальное из этого объекта для ясности) -

function gameValues(){
    this.items = [];
}
currentGame = new gameValues();

1 ответ

Решение

При модификации массива, который вы зацикливаете, очень часто возникают проблемы.

Например, если вы удалите элемент в позиции i, затем более поздние элементы будут смещены влево, поэтому следующий элемент теперь будет находиться в положении i, но потому что следующая итерация вашего цикла проверяет i+1, этот пункт будет пропущен!

Теперь вы можете сделать i--; после сращивания, чтобы убедиться, что вы осмотрите новый элемент на месте i на следующей итерации, но более простое решение - просто вернуться назад. Тогда операции, которые влияют на остальную часть списка, не будут проблемой.

for(var i = currentGame.items.length; i--; )

В любом случае, я обеспокоен чем-то другим в вашем коде:

        position = currentGame.items.indexOf(i);

Разве мы уже не знаем, что позиция текущего элемента i? это indexOf ищет в списке элемент со значением i, я представляю себе position получит значение -1 когда indexOf поиск не удался. Я думаю, что вы действительно имеете в виду здесь:

        var position = i;

Наконец, если вам не нравится console.log Вы можете попробовать поместить это в свой блок if:

        debugger;

Это вручную устанавливает точку останова в вашем коде, так что вы можете проверить значения переменных, чтобы увидеть, что происходит не так. Вам нужно будет открыть отладчик вашего браузера или панель "dev tools". Не забудьте удалить заявление, когда вы закончите!

Другие вопросы по тегам