Цитата:
|
Получается во время обхода всех элементов массива - я выдергивал из него один элемент - массив сжимался - и на следующем обходе я "терял" один элемент?
|
Да, все правильно. По действию код был эквивалентен

Код AS3:
for (var i : int = 0; i < aBlt.length; i++)
if (...)
aBlt.splice(aBlt.indexOf(aBlt[i]), 1);
При удалении в позицию i перемещался следующий элемент (i+1), после чего i увеличивалось. Т.е. "следующий" элемент пропускался. Причем я еще не уверен, что на самом деле код итерации for each должен быть эквивалентен предыдушему (не особо искал в документации правда). А если он может быть не эквивалентен, то изменения при итерации могут иметь и еще более непредсказуемые эффекты.
Со slice эквивалентный код становится примерно следующим:

Код AS3:
var tmp : Array = aBlt.slice();
for (var i : int = 0; i < tmp.length; i++)
if (checkIntersection(tmp[i]))
aBlt.splice(aBlt.indexOf(tmp[i]));
В этом коде tmp - это новая копия aBlt, ничем не связанная со своим оригиналом. Ну а так как ее изменений в цикле не производится, то все работает предсказуемо.
Цитата:
|
slice выполняется каждый раз в начале цикла?
|
Да, в начале каждой итерации. "Эквивалент" кода чуть выше.
Хотя в вашем случае slice все таки тяжеловат. Лишняя копия, затем поиск в массиве (хотя и быстрый) и удаление. Можно проще, с явной итерацией по индексу:

Код AS3:
var idx : int = 0;
while (idx < aBlt.length) {
if (checkIntersection(aBlt[i])
aBlt.splice(i, 1);
else
idx++;
}
Итерация по индексу явно позволяет показать, когда выполнять сдвиг, а когда - нет.
В вашем конкретном случае есть и еще один принципиально отличный от приведенных выше вариант. Он использует то, что пули отсортированы по горизонтали и если какая-то пуля еще не долетела до стенки, все остальные тоже не долетели. Тогда проверка идет только по одному элементу:

Код AS3:
while (aBlt.length > 0 && checkIntersection(aBlt[0])) {
var m : MovieClip = aBlt.shift(); // удаляет первый элемент из aBlt
m.fnHit();
this.removeChild(m);
}
При выбранной стратегии удаления этот способ будет гораздо лучше - он не проверяет лишние элементы. При той же гипотезе отсортированности, но большом количестве пуль, которые могут одновременно пересекать стену, можно экономить и количество удалений:

Код AS3:
var firstMiss : int = 0;
while (firstMiss < aBlt.length && checkIntersection(aBlt[0]))
firstMiss++;
if (firstMiss > 0)
for each (var m : MovieClip in aBlt.splice(0, firstMiss)) {
m.fnHit();
this.removeChild(m);
}
В ряде случаев вызов fnHit и removeChild не писал, там восстановление их должно быть очевидно.
Выбирать в данном случае стоит тот вариант, котороый вам понятнее
