PDA

Просмотр полной версии : Не удаляются элементы массива


GrabMaPaw
08.01.2011, 11:37
Здравствуйте!
Я в данный момент только начал изучать ActionScript и в учебных целях решил сделать игру аналогичную вот этой (http://www.kongregate.com/games/TubeGame/helicopter-game).
У меня возникла проблема с генерацией "потолка" и "пола". Вот какой алгоритм я избрал:
1. У нас есть "кирпичик" в виде movieclip'а, из которого мы будем строить неровную поверхность.
2. В цикле Event.ENTER_FRAME:
добавляем кирпичик на сцену и помещаем его в массив
для последнего элемента массива устанавливаем положение на экране
пробегаем по каждому элементу массива, где проверяем: если элемент массива вышел за пределы экрана, то удаляем его


То есть, по моему замыслу, существовать будут только те movieclip'ы, которые видны на экране, а уйдя за его пределы, они будут уничтожаться и всем будет хорошо.
Но в результате совсем не так, и я не понимаю, почему.

Вот кусочек кода, который за это отвечает:
for (var i:uint = 0; i < wallArr.length; i++) {
if (wallArr[i].x < 0) {
trace(i+" is OUT!");
wallArr.splice(i,1);
}
}
Как видите, для проверки корректности работы я трейсом вывожу на экран элементы массива, которые удовлетворяют этому условию. Всё выводится правильно - как только movieclip'ы начинают выходить за пределы экрана, мы начинаем получать "0 is OUT!". Соответственно, если закомментировать "wallArr.splice(i,1);" то начинаем получать номера всех элементов массива, находящихся за пределами экрана. То есть, условие поставлено верно и, вроде бы, элементы массива даже удаляются.
Однако, если трейсить wallArr.length, то мы увидим, что массив абсолютно не уменьшается. И в результате, когда он разрастается до неимоверных пределов, всё начинает дико тормозить (что естественно).
И ещё, справедливы ли мои подозрения, что у меня неправильный подход, и удаление элемента из массива в данном случае не повлечёт за собой удаление movieclip'a со сцены?

Я, честно говоря, уже голову сломал над этой загадкой и был бы благодарен, если бы кто-то смог пролить хоть какой-то свет на неё. Искал уже не только в рунете, но и в зарубежном интернете подобные проблемы - ничего нет.

Кстати, сдаётся мне, что тут можно сделать всё проще, но я не знаю, как. Может, можно в AS3 как-то удалить со сцены все movieclip'ы, которые удовлетворяют тем или иным условиям (в данном случае выходят за пределы экрана)?

vinch
08.01.2011, 12:47
1) Да, при удалении элемента из массива он не удалится со сцены

2) Я особо не вникал проблему, но на лицо промах с циклом. Для простоты заменим клипы числами и поставим задачу удалить из массива числа > 3. Пусть наш массив - [4, 5, 6]. Тогда на каждой итерации будет вот что:

1. i == 0, массив == [5, 6] после удаление i-го элемента
2. i == 1, массив == [5] после удаление i-го элемента
3. i == 2, длина массива == 1 => остановка

После цикла массив == [5]

Как видно, это не то, что нам надо ;)

samana
08.01.2011, 13:22
for (var i:uint = 0; i < wallArr.length; i++) {
if (wallArr[i].x < 0) {
trace(i+" is OUT!");
wallArr.splice(i,1);
removeChild(MovieClip(wallArr[i]));
i--
}
}

andrew911
08.01.2011, 16:18
for (var i:uint = 0; i < wallArr.length; i++) {
if (wallArr[i].x < 0) {
trace(i+" is OUT!");
wallArr.splice(i,1);
removeChild(MovieClip(wallArr[i]));
i--
}
}

Можно проще (пройтись с конца массива)

for (var i:int = wallArr.length -1;i >= 0;i--)
{
if (wallArr[i].x < 0)
{
trace(i+" is OUT!");
wallArr.splice(i,1);
removeChild(wallArr[i]);
}
}

и лучше не использовать wallArr.length в цикле

Gaen
08.01.2011, 18:56
и лучше не использовать wallArr.length в цикле
Преждевременная оптимизация - корень всех зол! :)

GrabMaPaw
08.01.2011, 21:26
Уважаемые господа, огромное всем спасибо.
Ваши советы очень помогли, буду многое переосмысливать :)