Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   Удаление объекта со сцены (http://www.flasher.ru/forum/showthread.php?t=187965)

TurboDizel 26.11.2012 23:52

Удаление объекта со сцены
 
Здравствуйте! Появилась проблема при удалении объекта со сцены (объект находится в массиве, хотя это, скорее всего, не важно). Код:
Код AS3:

private function collisions():void {
        for (var i = 0; i < Bullets.length; i++) {
                var temp:int; // temp в условии ниже будет равна номеру зомби в массиве, который столкнулся с пулей i
                if (Zombie.hitTestObject(Bullets[i])) { //проверка столкновения пули и зомби
                        temp = knowzombi(i);
                        trace("Попал");
                        removeChild(Bullets[i]);
                        Bullets.splice(i, 1);
                        removeChild(Zombies[temp]);
                        Zombies.splice(temp, 1);
                }
        }
}

Проблема в том, что во время игры, когда пуля сталкивается с зомби, сама пуля пропадает (удаляется из массива и со сцены без ошибок), а вот с зомби другая ситуация. Сама его картинка пропадает, но если стрельнуть в то место где стоял зомби ещё раз, то выдается ошибка:

Цитата:

ArgumentError: Error #2025: The supplied DisplayObject must be a child of the caller.
at flash.display::DisplayObjectContainer/removeChild()
at main/::collisions()
at main/::ef()
Т. е. получается, что зомби всё ещё не удалился (пуля опять сталкивается с ним и что-то пытается сделать), хотя с виду, кажется, что пропал.

Вопрос в общем, почему он не удаляется? :) Я так понимаю, что вызываю его не в том месте, но я понятия не имею как решить данную проблему, во флеше недавно.

SlashMan 27.11.2012 00:46

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

TurboDizel 27.11.2012 01:08

Цитата:

Сообщение от SlashMan (Сообщение 1106438)
Скорее всего ты проверяешь столкновение пули и зомби путем сравнения координат, зомби продолжает находится на той же координате, только его не видно, но тогда ты пытаешься удалить из списка отображения объект, которого там нет - и получаешь ошибку. Проверяй при столкновении пули с зомби находится ли зомби на экране или нет

Как-то не понял). "пытаешься удалить из списка отображения объект, которого там нет" - но он же там есть. Когда его убиваешь, потом опять стреляешь, пуля снова пропадает на том месте где раньше был зомби, значит столкновение опять было, и т.е. зомби никуда не делся, просто стал невидимым, а удаления так и не произошло. К тому же если бы зомби пропал, условие бы не выполнялось, поэтому бы до повторного удаления того, чего нет, дело не дошло бы.
Надеюсь я правильно понял то, что Вы написали).

Zebestov 27.11.2012 01:23

В документации не указано, что аргумент метода hitTestObject должен быть объектом, расположенным на сцене. Отсюда true при сравнении и ошибка при попытке удалить со сцены то, чего на сцене нет.

Интересно, а такой код тоже выдает ошибку?

Код AS3:

private function collisions():void {
        for (var i = 0; i < Bullets.length; i++) {
                var temp:int = knowzombi(i); // temp в условии ниже будет равна номеру зомби в массиве, который столкнулся с пулей i
                if ((Zombies[temp] as DisplayObject).hitTestObject(Bullets[i])) { //проверка столкновения пули и зомби
                        trace("Попал");
                        removeChild(Bullets[i]);
                        Bullets.splice(i, 1);
                        removeChild(Zombies[temp]);
                        Zombies.splice(temp, 1);
                }
        }
}


TurboDizel 27.11.2012 01:37

Но hitTestObject это же проверка того, не пересекаются ли два сравниваемых объекта, и так как после того как пуля пропала, зомби ни с кем не пересекается, что значит false. Может я и не прав, чего-то не знаю, поэтому это догадки.

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

Ваш код тоже выдает ошибку :(.

На всякий случай: ошибка вылазит именно тогда, когда я стреляю уже в невидимого зомби (второй и остальные разы).

AlexLucas 27.11.2012 02:45

Покажите что это за функция knowzombie() и кто такой Zombie у вас в if'e, вы всех зомби в одном мувике 'Zombie' держите? Тогда hitTest может быть тру, вы же его не удаляете.
Возможно вы удаляете не того зомби из массива, соответственно на него ссылка остаётся, а когда вы опять пытаетесь его удалить, то выскакивает ошибка.

TurboDizel 27.11.2012 03:00

Цитата:

Сообщение от AlexLucas (Сообщение 1106457)
Покажите что это за функция knowzombie() и кто такой Zombie у вас в if'e, вы всех зомби в одном мувике 'Zombie' держите?
Возможно вы удаляете не того зомби из массива, соответственно на него ссылка остаётся, а когда вы опять пытаетесь его удалить, то выскакивает ошибка.

Тот Zombies[i] в if`е это один из тех зомби, который содержится в массиве. Вот как создавался массив:
Код AS3:

private function createZombies(count:int) : void {
        for (var i = 0; i < count; i++) {
                Zombies[i] = Zombie;
                addChild(Zombies[i]);
                var randNumX: Number = Math.round(Math.random() * 780);
                var randNumY: Number = Math.round(Math.random() * 580);
                Zombies[i].x = randNumX;
                Zombies[i].y = randNumY;
                trace("Создался " + (i+1) + " зомби с координатами (" + randNumX + ", " + randNumY + ").");
        }
}

В функции Zombie это public var Zombie:MovieClip = new zombie1();
zombie1 - класс самого зомби, к которому привязан символ в библиотеке.
Вызывается функция из главной функции: createZombies(3); Кстати зомби должно быть три на поле, но появляется один (с этим тоже ещё не разобрался). В trace показывается, что они трое появились по разным координатам, но виден только последний (второй заменил первого, третий второго).

knowzombie узнает какой именно зомби из массива Zombies столкнулся с пулей.
Код AS3:

private function knowzombi(k:int) : int {
        var temp:int = 0;
        for (var i = 0; i < Zombies.length; i++) {
                if (Zombies[i].hitTestObject(Bullets[k])) {
                        temp = i;
                        break;
                }
        }
        return temp;
}


AlexLucas 27.11.2012 15:34

То есть по сути - Zombie это один объект, вы заполняете массив ссылками на один и тот же объект, потому и появляется всего один зомби
Код AS3:

//если 
var Zombie:MovieClip = new zombie1();
//......
//тогда
for (var i = 0; i < count; i++) {
                Zombies[i] = Zombie;
//.....
}
//заполнит ваш массив, и в нём будет count ссылок на один и тот же объект

, потом удаляете одну ссылку, но остальные всё равно указывают на тот же объект который вы удалили, и выскакивает ошибка.
Надо создавать нового зомби для каждого элемента массива.
И ещё - вы 2 раза проверяете hitTest - в collisions, и в knowzombie - зачем ? Немного не понимаю почему всё же выдаёт hitTest. Сделайте трейс
Код AS3:

removeChild(Bullets[i]);
Bullets.splice(i, 1);
//тут трейс
removeChild(Zombies[temp]);

и проверьте если он выдаст вам трейс перед ошибкой, когда вы стреляете второй раз.

TurboDizel 27.11.2012 17:46

Долго писал этот пост, и когда уже дописал, всё заработало (после того как убрал второе сравнение). Поэтому если кто-то попадет в эту тему с похожей проблемой, пост оставлю написанным!
Всем спасибо за то, что откликнулись, особенно AlexLucas!!
:)

Цитата:

Сообщение от AlexLucas (Сообщение 1106543)
То есть по сути - Zombie это один объект, вы заполняете массив ссылками на один и тот же объект, потому и появляется всего один зомби

По идее понял, и в функции createZombies вместо прежнего присваивания массиву Zombies, написал Zombies[i] = new zombie1(); Появилось три зомби в разных местах как положено. Убиваю первых двоих нормально, они пропадают и после того как стреляю снова в тоже место пуля пролетает мимо в общем с ними всё отлично. Но вот когда убиваю третьего, то всё так же хорошо, но бесконечно без остановки сыпется ошибка (между ошибками trace`а, в том месте где Вы показывали, нет):
Цитата:

TypeError: Error #1009: Cannot access a property or method of a null object reference.
at main/::collisions()
at main/::ef()
Создал 10 зомби, ошибка начинает появляться убивая десятого, т.е. в любом случае последнего зомби на сцене.

Цитата:

Сообщение от AlexLucas (Сообщение 1106543)
И ещё - вы 2 раза проверяете hitTest - в collisions, и в knowzombie - зачем ?

В collisions второй раз я проверяю для того, чтобы убедиться, что функция не вернула мне тот же 0 и не удаляла зомби 0 в любом случае. Хотя, что бы не использовать hitTestObject лишний раз, сделал так:
Код AS3:

private function collisions():void {
        for (var i = 0; i < Bullets.length; i++) {
                var temp:int = knowzombi(i); // temp равна номеру зомби в массиве, который столкнулся с пулей i
                if (temp != -1) { //если temp -1, то функция knowzombie не нашла зомби, который столкнулся с пулей i
                        removeChild(Bullets[i]);
                        Bullets.splice(i, 1);
                        trace("Попал");
                        removeChild(Zombies[temp]);
                        Zombies.splice(temp, 1);
                }
        }
}
 
private function knowzombi(k:int) : int { //проверяем столкнулся ли какой-то зомби с пулей, если да, то -
        var temp:int = -1;                    // - возвращаем номер зомби в массиве, если нет, то возвращается -1
        for (var i = 0; i < Zombies.length; i++) {
                if (Zombies[i].hitTestObject(Bullets[k])) {
                        temp = i;
                        break;
                }
        }
        return temp;
}



Часовой пояс GMT +4, время: 11:41.

Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.