Сплит 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". Не забудьте удалить выражение, когда вы закончите!