2012-03-06 4 views
1

Уже некоторое время работает над игрой Tower Defense для iOS. Я использую Cocos2d (v0.99.5 не уверен). Недавно я начал сталкиваться с некоторыми проблемами, когда начал удалять спрайты.Как отладить удаление проблемы спрайта Cocos2d

Есть профили с помощью инструментов и зомби, и вот что я получаю:

Zombie trace код для обновления спрайтов (а также удалять их) находится в обновлении:

-(void) update:(ccTime)deltaTime { 
if (paused) 
    return; 

CCArray *childs = [textureAtlas children]; 

//Update all objects 
for (GameSprite *tempChar in childs) { 
    if ([tempChar respondsToSelector:@selector(updateStateWithDeltaTime:andListOfGameObjects:andAtlas:)]) { 
     [(GameSprite*)tempChar updateStateWithDeltaTime:deltaTime andListOfGameObjects:[textureAtlas children] andAtlas:textureAtlas]; 
    } 
} 

//Remove dead projectiles 
for (GameSprite *tempChar in childs) {   
    if ([tempChar isKindOfClass:Projectile.class]) { //(**) 
     if (![tempChar alive]) { 
      [tempChar remove]; 
     } 
    } 
} 

//Remove dead towers 
for (GameSprite *tempChar in childs) { 
    if ([tempChar isKindOfClass:Tower.class]) { 
     if (![tempChar alive]) { 
      [tempChar remove]; 
     } 
    } 
} 
//Remove dead creeps 
for (GameSprite *tempChar in childs) { 
    if ([tempChar isKindOfClass:Creep.class]) { 
     if (![tempChar alive]) { 
      [tempChar remove]; 
     } 
    } 
} 
} 

Метод удалить в GameSprite.m:

-(void)remove { 
    CCLOG(@"remove"); 
    [self removeFromParentAndCleanup:YES]; 
} 

Первый блок обновляет спрайтов в SpriteBatchNode/текстурный атлас. Три оставшихся блока проверяют разные объекты, если они должны быть удалены. (их живая переменная установлена ​​на NO?). Причина, по которой у меня есть три блока разных типов, связана с тем, что снаряды имеют (слабую) ссылку на ползучесть, на которую они стреляют, и должны быть удалены до ползучести.

Таким образом, моя проблема в том, что она случайным образом падает, когда снаряд попадает в ползучесть, а проектиль (и все другие снаряды, стреляющие при этой ползучести) должны быть удалены). Счетчик значений крипов уменьшается до 0, но, похоже, все еще находится в массиве childs. Причина ошибки я получаю:

*** -[NormalProjectile isKindOfClass:]: message sent to deallocated instance 0xff33e30 

на строке я обозначенному (**)

Либо проблема со мной понимание removeFromParentAndCleanUP Cocos2D в: или, что мое «решение» для обработки снарядом-крип -отношение плохое с точки зрения памяти. Любые идеи о том, как решить эту проблему или отладить ее дальше?

ответ

3

Ваши быстрые методы перечисления для прохождения массива бросают все ваши спрайты в этом массиве в качестве настраиваемого подкласса CCSprite, а затем проверяют, являются ли они другим пользовательским подклассом, например Tower и т. Д. Я не рассматривайте это как полезную практику программирования, так как методы в одном классе могут быть не в другом, но тем не менее вы их бросаете.

Это может быть или не способствовать вашей проблеме, но более разумный подход заключается в том, чтобы сохранить iVar CCArray для детей определенного класса. т.е. поместите все ваши снаряды в один массив в момент их создания и добавьте в пакетный узел, после чего вы можете перебирать все снаряды, башни и т. д., пройдя через эти отдельные массивы, где вы знаете, какой класс они уже представляют , Затем удалите их из массива, а также из родителя, когда это необходимо. Я бы подумал, что это немного безопаснее, чем прохождение всех спрайтов в игре, которые находятся в вашем batchnode, который может включать в себя не используемые, возможно, spites, а также их литье и тестирование их как разных классов.

+0

Спасибо. Решил его, создав три новых массива и перечислив их через них. Хотел пропустить это, но кажется, что итерация через детей текстурыAtlas не является безопасным способом сделать это. – Sunkas

+0

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

Смежные вопросы