Ошибка удаления спрайтов из таблицы спрайтов в Cocos2D - PullRequest
0 голосов
/ 20 февраля 2012

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

Яхранение моих изображений спрайтов в spritesheets, используя CCSpriteBatchNode.Сейчас я просто делаю тест начальной настройки, когда вы нажимаете на экран, чтобы создать новый случайный набор людей.Странно то, что вы можете нажать один раз, и он удалит старых людей и заменит их новыми, но во второй раз происходит сбой с ошибкой: «CCSpriteBatchNode не содержит спрайт. Не могу удалить его»Теперь я уверен, что я добавил спрайт в узел пакета, в моем конструкторе Person.m у меня есть эта строка:

        [spriteSheet addChild:person];

В моем тестовом коде в ccTouchesEnded я получил следующий код:

//updated with changes suggested by Mazyod and Jer
for(int i=6; i>=0; i--){
    Person *per = [_people objectAtIndex:i];
    [_people fastRemoveObjectAtIndex:i];
    [_spritesheet removeChild:per cleanup:YES];
    per = nil;
}


for(int i = 0; i < 7; i++){
    Person *per = nil;
    per = [Citizen personFromCountry:_country1 WithSpriteSheet:_spritesheet];
    per.position = ccp(100 + (50 * i),160);
    [_people addObject:per];
    [_spritesheet addChild:per];
}

Кто-нибудь может подсказать, что мне не хватает?Я прочитал кучу спрайтов в cocos2d, и мне дано понять, что удаление отдельных спрайтов довольно сложно, поэтому я уверен, что есть некоторые важные строки, которые мне нужно добавить здесь.Спасибо за вашу помощь!

Редактировать: Я погуглил ошибку и нашел эту тему: http://www.cocos2d -iphone.org / forum / topic / 17170 , которая кажетсяподтвердите, что Cocos2d считает, что я не добавляю спрайт в таблицу спрайтов - но я, как доказывает тот факт, что спрайты добавляются правильно в первый раз, а не во второй.

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

Ответы [ 3 ]

1 голос
/ 21 февраля 2012

Похоже, вам нужно изменить

[_people addObject:per];

до

[_people replaceObjectAtIndex:i withObject:per];

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

Дайте мне знать, если это работает.

1 голос
/ 14 ноября 2012

Я просто хочу рассказать о своем опыте здесь с этой проблемой и о том, как я ее решил.

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

OR

ПЫТАЕТСЯ УДАЛИТЬ ДЕТЯ ДВАЖДЫ

Это был случай для меня. Обнаружение столкновений в моей игре было надежным (по крайней мере, я так думал). Затем случайно, как 1 из каждых 7-10 прогонов ... Я бы получил этот сбой. Я понял, что это потому, что я закодировал свои снаряды, которые будут удалены, когда они пересекут цель.

Я, однако, не поставил отказоустойчивый, если мой тиковый метод обнаружил, что он находится в столкновении с БОЛЕЕ 1 целью за раз.

Это было связано с тем, что для каждого снаряда я проходил итерацию по каждой цели для проверки на столкновение, а затем удалял соответствующую проекцию, если столкновение было обнаружено. Поэтому я создал простую BOOL и установил ее на YES, если она уже столкнулась с целью. Тогда я проверял только на столкновение, если снаряд не столкнулся ни с чем.

Итак ... до:

if (CGRectIntersectsRect(projectileRect, targetRect))
{
//code to remove projectile
}

После того, как:

if (CGRectIntersectsRect(projectileRect, targetRect) && projectile.hasHitaTarget == NO)
{
//code to remove projectile
}
1 голос
/ 20 февраля 2012

Ну, я могу помочь вам прояснить одну вещь:

Любой CCNode может быть только дочерним по отношению к одному из родителей. т.е. он должен иметь одного родителя.

Но что у вас здесь:

for(int i=0; i<7; i++){
    Person *per = [_people objectAtIndex:i];
    [self removeChild:per cleanup:YES];
    [_spritesheet removeChild:per cleanup:YES];
    per = nil;
}

Предположим, вы пытаетесь добавить пользователя в spriteSheet и себя одновременно. Проверьте свой журнал, он должен иметь что-то вроде:

cocos2d: removeChild, дочерний элемент не найден.

И из-за ошибки, которую вы получаете, я держу пари, что этот человек добавлен к себе, а не к спрайт-листу.

Итак, как это решить?

Ну, вы должны добавить человека в spriteSheet как ребенка, а затем добавить spriteSheet для себя в качестве ребенка. (На самом деле, порядок их добавления не имеет значения).

Разберитесь, и, возможно, эта проблема исчезнет, ​​или, по крайней мере, она прояснится, и мы сможем вам помочь.

...