Класс хранения Cocos2D CCTexture2D — ошибка

У меня есть класс под названием «Текстуры», который использует некоторые данные, подобные этому.

//Textures.h
#import <Foundation/Foundation.h>

@interface Textures
{
    CCTexture2D *Balloon_RED;
    CCTexture2D *Balloon_POP;
}
@property (nonatomic, retain) CCTexture2D* Balloon_RED;
@property (nonatomic, retain) CCTexture2D* Balloon_POP;

-(void)setTextures;
+(CCTexture2D*) cacheImg: (NSString*) image;
@end

//Textures.m
#import "Textures.h"

@implementation Textures
@synthesize Balloon_RED;
@synthesize Balloon_POP;
-(void)setTextures
{
    Balloon_RED = [Textures cacheImg:@"red.png"];
    Balloon_POP = [Textures cacheImg:@"pop.png"];
}
+(CCTexture2D*)cacheImg: (NSString*)image
{
    return [[CCTextureCache sharedTextureCache] addImage:image];
}
@end

И я использую его в своем основном классе следующим образом: (SpriteTextures имеет тип "Textures", а BalloonSprite имеет тип "Balloon ", который является моим подклассом CCSprite)

[SpriteTextures setTextures];
BalloonSprite = [Balloon spriteWithTexture: [SpriteTextures Balloon_RED]];

После загрузки заставки я получаю сообщение об ошибке, говорящее о том, что я использую недопустимую текстуру:

Assertion failure in -[Balloon initWithTexture:], /Users/Mark/Kobold2D/Kobold2D-1.0.5/__Kobold2D__/libs/cocos2d-iphone/cocos2d/CCSprite.m:192
2012-03-02 20:00:18.011 Game-iOS[1341:1ca03] ERROR: Uncaught exception Invalid texture for sprite
2012-03-02 20:00:18.011 Game-iOS[1341:1ca03] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid texture for sprite'

Дополнительная информация заключается в том, что я использую Kobold, как вы можете видеть в журнале ошибок, но это не должно иметь большого значения. Я уверен, что, вероятно, где-то делаю что-то не так.

Любая помощь приветствуется, спасибо!

Редактировать Как выглядит папка ресурсов, они также находятся в папках физического диска. Папка ресурсов

Кроме того, это отлично работает (добавление texture2ds в основной класс)

Texture_RED = [[CCTextureCache sharedTextureCache] addImage:@"red.png"];
Texture_POP = [[CCTextureCache sharedTextureCache] addImage:@"pop.png"];

BalloonSprite = [Balloon spriteWithTexture: Texture_RED];

Или действительно, в целом, есть ли лучший способ организовать множество спрайтов (многие из которых нуждаются в изменении текстуры) для игры с почти 100 различными изображениями?

Изменить

Основной класс (*.h)

#import "Textures.h"

@interface MainClass : CCLayer
{
    Textures *SpriteTextures;
}
-(void)loop;
@property (retain) Textures *SpriteTextures;

Выполнение

-(id) init
{
    if ((self = [super init]))
    {
        self.isTouchEnabled = true;
        [SpriteTextures setTextures];

        BalloonSprite = [Balloon spriteWithTexture: [SpriteTextures Balloon_RED]];
        .......

person Mark Lalor    schedule 03.03.2012    source источник


Ответы (2)


NSAsserts - настоящая боль, но когда поверх этого сообщение бесполезно :) ... хорошо, глядя на строку 192 в cocos2d (CCSprite), текстура равна нулю (вызывает сбой утверждения). Проверьте, не появились ли у вас сообщения, похожие на эти, для ваших текстур при их добавлении в sharedTextureCache.

2012-03-02 21:19:43.497 MyGame[55224:12203] cocos2d: CCTexture2D. Не могу создать текстуру. UIImage равен нулю

2012-03-02 21:19:43.498 MyGame[55224:12203] cocos2d: не удалось добавить изображение:a.png в CCTextureCache

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

часть 2: просто перечитав свой код, вы получите ту же ошибку, если SpriteTextures будет равен нулю в выражении

[SpriteTextures setTextures];
BalloonSprite = [Balloon spriteWithTexture: [SpriteTextures Balloon_RED]];

Это может объяснить, почему он работает в одном месте, но не работает в другом.

часть 3: вы не инициализируете и не устанавливаете SpritTextures в своем классе init. Пытаться:

    self.isTouchEnabled = true;
    self.SpriteTextures = [[Textures alloc] init];
    [SpriteTextures setTextures];
person YvesLeBorg    schedule 03.03.2012
comment
Через минуту я попытаюсь отредактировать изображение иерархии папок ресурсов. - person Mark Lalor; 03.03.2012
comment
Кроме того, что вы подразумеваете под членами цели, которую вы создаете? - person Mark Lalor; 03.03.2012
comment
как вы добавили файлы в проект? Обычно я перетаскиваю их из папки, в которой они находятся, на значок папки ресурсов в Xcode. Когда вы это сделаете, Xcode спросит вас, «какую цель» вы хотите включить в эти ресурсы. Например, в приведенном выше проекте «MyGame» у меня есть 2 цели: игра и облегченная версия. Когда я добавляю изображения, я проверяю обе цели, чтобы убедиться, что они включены в .app, созданный в процессе сборки. - person YvesLeBorg; 03.03.2012
comment
Я скопировал папку с изображениями непосредственно в папку ресурсов проектов, затем сделал «Файл» -> «Добавить файлы в имя проекта», когда папка ресурсов была выбрана, и перешел к папке изображений, которая теперь находится в папке ресурсов проектов. - person Mark Lalor; 03.03.2012
comment
@Mark: добавил часть 2 к моему ответу, что также может объяснить, почему вы получаете ошибку в одном месте, а не в основном классе. Если это работает в основном, то ваша папка ресурсов в порядке, а текстуры являются членами цели. - person YvesLeBorg; 03.03.2012
comment
Так почему это не работает с моим другим классом? Кроме того, есть ли лучший способ управлять большим количеством текстур/спрайтов? - person Mark Lalor; 03.03.2012
comment
У меня получается очень похоже на то, что делаете вы (более 2000 текстур) ... временами это может стать волосатым. Как и вы, я создаю подгруппы в Ресурсах и стараюсь держать вещи в полуупорядоченном порядке, чтобы я мог найти себя в этом беспорядке. Когда команда художников сбрасывает на меня большое количество обновлений, я склонен копировать файлы (с оболочкой) и не использовать перетаскивание Xcode (в основном перетаскивание, насколько я понимаю :)). Shell squash предназначен только для обновлений текстур: никаких новых, удаленных или переименованных файлов: для тех, которые я использую через графический интерфейс Xcode. - person YvesLeBorg; 03.03.2012
comment
для вашего другого вопроса, вы пытались определить, является ли SpriteTextures нулевым? Если это так, это проблема, которую вы должны решить. - person YvesLeBorg; 03.03.2012
comment
Хм, я установил точки останова, и да, я думаю, вы правы, они выглядят нулевыми, но я не знаю, почему. Я думаю, это связано с тем, что я также устанавливаю точки останова в функции [SpriteTextures setTextures];, но похоже, что она никогда не вызывается (она не останавливается для точек останова). - person Mark Lalor; 03.03.2012
comment
Он не вызывается, потому что SpriteTextures равен нулю, поэтому вы передаете nil в Balloon. Чтобы помочь вам больше, мне нужно увидеть, где и как вы объявляете и устанавливаете SpriteTextures. - person YvesLeBorg; 03.03.2012
comment
Хорошо, я добавил, как создаются текстуры спрайтов. - person Mark Lalor; 03.03.2012
comment
@Mark - добавил часть 3 к моему ответу. - person YvesLeBorg; 03.03.2012
comment
какой-то процесс зависает, симулятор дает мне минуту на перезагрузку - person Mark Lalor; 03.03.2012
comment
О, черт возьми, ошибка компоновщика после перезагрузки, мне нужно лечь спать на ночь, но завтра я посмотрю на это подробнее. Большое спасибо за Вашу помощь - person Mark Lalor; 03.03.2012

Я считаю, что ответ проще, чем вы думаете ..!

Texture_RED = [[CCTextureCache sharedTextureCache] addImage:@"red.png"];
Texture_POP = [[CCTextureCache sharedTextureCache] addImage:@"pop.png"];

Текстуры не сохранились. Пытаться:

self.Texture_RED = [[CCTextureCache sharedTextureCache] addImage:@"red.png"];
self.Texture_POP = [[CCTextureCache sharedTextureCache] addImage:@"pop.png"];

если вам нужна причина, вот мои рассуждения:

        if( tex )
            [textures_ setObject: tex forKey:path];
        else
            CCLOG(@"cocos2d: Couldn't add image:%@ in CCTextureCache", path);

        // autorelease prevents possible crash in multithreaded environments
        [tex autorelease];  

The previous code is found in the

CCTextureCache addImage:

Это означает, что вы должны сохранить свои текстуры.

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

person Mazyod    schedule 03.03.2012
comment
Кэш в CCTextureCache (одноэлементный) представляет собой NSMutableDictionary с ключом, производным от имени файла текстуры. Они сохраняются. Ваше приложение должно управлять очисткой кеша, и, конечно же, предупреждение о памяти будет хорошей возможностью для удаления неиспользуемых текстур. Если бы проблема Марка заключалась в отправке сообщения освобожденному объекту, программа не дошла бы до ошибки утверждения. - person YvesLeBorg; 03.03.2012
comment
Что ж, я получаю сообщение об ошибке компоновщика Apple match-o, поэтому мне нужно еще немного времени, чтобы проверить это, извините. - person Mark Lalor; 03.03.2012
comment
Совет: я понял, что в Xcode 4 ошибка компоновки Mac-O появляется всякий раз, когда у вас есть другие синтаксические ошибки. Поэтому сначала убедитесь, что вы устранили другие ошибки. - person Mazyod; 03.03.2012