How do I load a CCSpriteBatchNode from the documents directory? - cocos2d-iphone

I have a file in the documents directory that I verify does exist before I call this method:
CCSpriteBatchNode *batchNode = [[CCSpriteBatchNode alloc] initWithFile:filePath capacity:9];
The error reported is:
-[CCFileUtils fullPathFromRelativePath:resolutionType:] : cocos2d: Warning: File not found: decompressed_file.png
cocos2d: CCTexture3d: Can't create Texture. cgImage is nil;
Using Cocos2d 2.0

You can use CCSpriteBatchNode and pull files from the Documents directory (or any other directory you want) by setting the searchPath, e.g. like so:
NSString *documentDirectory = aDirectory;
NSMutableArray * loadSearchPath = [[CCFileUtils sharedFileUtils].searchPath mutableCopy];
[loadSearchPath addObject:documentDirectory];
[CCFileUtils sharedFileUtils].searchPath = [loadSearchPath copy];
This adds aDirectory to the searchable paths where Cocos2D will be looking for the file with the name you specify in [CCSpriteBatchNode batchNodeWithFile:#"aFile"];

The cocos2d functions file methods assume you are loading from your bundle resources. I do not think you can load the file directly but what you can do is load it into a UIImage and then create a CCTexture2D with a CGImage. With your CCTexture2D you can create a CCSpriteBatchNode.
UIImage *img = [UIImage imageWithContentsOfFile:filePath];
CCTexture2d *tex = [[CCTextureCache sharedTextureCache] addCGImage:[img CGImage] forKey:#"myTexture"];
CCSpriteBatchNode *batch = [CCSpriteBatchNode batchNodeWithTexture:tex capacity:9];
These steps are whats going on in the background anyway when you create a CCSpriteBatchNode using the normal methods. Except for the bundle assumption.
If you are making the sprite batch node more than once for some reason, you can check if the texture already exists in the cache before reloading the UIImage.

Related

Using Tecture packer image not showing properly in cocos2D V3.3 iOS

I am trying to add images from TexturePacker, image is showing but images appears messed up like refered image some parts coming with another image ->
[[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:#"sprites-hd.plist"];
CCSprite* lobjSprite = [CCSprite spriteWithImageNamed:#"bird.png"];
[self addChild:lobjSprite];

Cocos2D: Best way to display text from font atlas?

Based on the use CCDirector makes of CCLabelAtlas, I tried the following:
scoreLabel = [[CCLabelAtlas alloc] initWithString:#"0123456789" charMapFile:#"fps_images.png" itemWidth:8 itemHeight:12 startCharMap:'.'];
[scoreLabel setPosition:ccp(200, 200)];
[self addChild:scoreLabel];
I must be missing something as nothing displays. I'm using the basic .png that's supplied with Cocos2D.
What am I missing? Thanks!

Get CGImageRef from CCSprite, CCTexture2D or even directly from CCSpriteFrameCache?

I have written some code that takes a UIImage.CGImageRef and puts it into a context so that I can analyze it. This all works great. BUT, I now wish to implement this process in a Cocos2D app.
All of my graphics for the app are done as sprite sheets using Texture Packer so I am looking for any way to get the CGImageRef that I require out of the sprite sheet.
My theory is that you can init a CCSprite with a CGImageRef so why can't I simply get it back out again?
Maybe I am missing something simple like does Cocos2D have a CGImageRef equivalent?
you can try smth like this
CCRenderTexture *renderer = [CCRenderTexture renderTextureWithWidth:size.width height:size.height];
[renderer begin];
CCSpriteBatchNode *spriteSheet = [m_sprite batchNode];
if (spriteSheet != nil)
[spriteSheet visit];
else
[m_sprite visit];
[renderer end];
NSData* uidata = [renderer getUIImageAsDataFromBuffer:kCCTexture2DPixelFormat_RGBA8888];
UIImage* uiimage = [UIImage imageWithData:uidata];
CGImageRef image = [uiimage CGImage];
You can get image data from OpenGL via glReadPixels. It needs some adjustments, but it would be wrong solution in performance aspect. OpenGL is designed as one-way conveyer (you pass data and don't read it back). Depending on your concrete task you may preload image data when loading textures from file.
As example we use alpha channel of textures for per-pixel touch test. So, when we load image we store its bitmask of alpha threshold in memory.
no
cctexture direct from [CCTextureCache sharedTextureCache] read from photo file
ccspriteframe direct from [CCSpriteFrameCache sharedSpriteFrameCache] read from ".plist" file

multiple CCSpritevFramevCache at one time

i am using the CCSpriteFrameCache a lot but cant understand somthing about it.
can i load many .plist to the cache at the start of my game ? or the CCSpriteFrameCache has ONLY one plist at a time ?
by now there is a sprite which is a child of a CCSpriteBatchNode ,that is been created many times during the game , with different images. so every time i create a new sprite i do this:
[[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:[NSString stringWithFormat:#"cand%i.plist",stage]];
candySheet = [CCSpriteBatchNode batchNodeWithFile:[NSString stringWithFormat:#"cand%i.png",stage]];
[self addChild:candySheet];
sprite1 = [CCSprite spriteWithSpriteFrameName:[NSString stringWithFormat:#"cand%i.png",1]];
is it ok ?
now lets say i have 2 spriteSheets, and 2 .plist, and i want to load both of them on my init , and add 2 sprites, each to be a child of one CCSpriteBatchNode and render images for each sprite from his own spriteSheet and Plist. but i get error then that :
CCSprite is not using the same texture id
so, i understand that each time i have to load to the cache the plist that i need at that specific time ????
thanks.
Someone asked a similar thing earlier.
You cannot make sprites children of the same CCSpriteBatchNode if they are not from the same spritesheet.
You need to create a new CCSpriteBatchNode for each spritesheet you use (by spritesheet I mean the combined image file and .plist file)
The CCSpriteFrameCache is a single cache shared across all your scenes and classes. When you call this method:
[CCSpriteFrameCache sharedSpriteFrameCache]
You are not making a new CCSpriteFrameCache object everytime, there is just ONE instance. You store all your loaded spritesheets in this single cache. So you could load 2 spritesheets into the cache like so:
[[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:#"sheet1.plist"]; [[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:#"sheet2.plist"];
You then need to create a CCSpriteBatchNode for EACH spritesheet, you cannot have more than one sheet in a batch node:
CCSpriteBatchNode *spriteSheet1 = [CCSpriteBatchNode batchNodeWithFile:#"sheet1.pvr.ccz"];
CCSpriteBatchNode *spriteSheet2 = [CCSpriteBatchNode batchNodeWithFile:#"sheet2.pvr.ccz"];
You can then add both of these batch nodes to a layer if you wish. Sprites added to batch nodes must be from the spritesheet that batch node is using.
[[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:#"some.plist"];
The above line takes quite a chunk of time even if the sprite frames are already loaded/cached. So make sure to avoid doing this unless you're absolutely certain that these sprite frames haven't been cached before, like at the beginning of the game or after purging the sprite frame cache.

Proper implementation of Particle Designer plist emitters in cocos2d?

I'm confused about how to properly use emitters made in Particle Designer with Retina displays in cocos2d. I have tried using an emitter with a non-hd texture (fire.png for example) saved as "particle.plist" with and without the texture embedded and I get a warning of some kind either way. I then made another emitter with fire-hd.png and the name "particle-hd.plist", and I get the same types of warnings, stuff like, cocos2d: Filename(fire-hd.png) contains -hd suffix. Removing it. See cocos2d issue #1040
Searching for issue #1040 yields a little info, but not enough for me to fix this.
A little enlightenment?
You need to prepare these files.
particle.plist (it uses texture 'fire.png' with or without the texture embedded)
fire-hd.png
CCParticleSystem searches -hd texture file first, then non-hd texture file, and then embedded texture data.
hd / retina partcle systems
EDIT
"Warning HD file not found" for Particle plist is false warning. You can use CCParticleSystem initWithDictionary method without any warning in this case.
NSString *path = [[NSBundle mainBundle]
pathForResource:#"particle1_traile" ofType:#"plist"];
NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile:path];
CCParticleSystem *particle = [[[CCParticleSystemQuad alloc]
initWithDictionary:dict] autorelease];