1
\$\begingroup\$

I recently started game development, but one of the things that I never put much thought to was the loading of images. I'm curious as to advice for improving my current code on loading images. I'm using cocos2d in iOS code, but if you know of optimization techniques in other languages I'd like to hear that as well.

//above the @implementation
#define kZLayerBase -1
#define kOffsetImg1 (-50)
#define kOffsetImg2 (50)
#define kPositionXImg1 (screenSize.width/2)
#define kPositionYImg1 (screenSize.height/2)
#define kPositionXImg2 kPositionXImg1
#define kPositionYImg2 kPositionYImg1
#define kWidthImg1 100
#define kHeightImg1 100
#define kWidhtImg2 100
#define kHeightImg2 100

//...

//individually
-(void)loadImages1{
    CGSize screenSize = [[CCDirector sharedDirector] winSize];

    CCSprite *img1 = [CCSprite spriteWithFile:@"img1.png"];
    [img1 setPosition:ccp(kPositionXImg1, kPositionImg1)];
    [self addChild:img1 z:kTagLayerBase];

    CCSprite *img2 = [CCSprite spriteWithFile:@"img2.png"];
    [img2 setPosition:ccp(kPositionXImg2, kPositionImg2)];
    [self addChild:img2 z:kTagLayerBase];

}

//using a sprite sheet
-(void)loadImages2{
    CCSprite *img1 = [CCSprite spriteWithFile:@"img.png" rect:CGRectMake(kWidthBean*0, kHeightBean*0, kWidthBean, kHeightBean)];
    [img1 setPosition:ccp(kPositionXImg1, kPositionImg1)];
    [self addChild:img1 z:kTagLayerBase];

    CCSprite *img2 = [CCSprite spriteWithFile:@"img.png" rect:CGRectMake(kWidthBean*1, kHeightBean*0, kWidthBean, kHeightBean)];
    [img2 setPosition:ccp(kPositionXImg2, kPositionImg2)];
    [self addChild:img2 z:kTagLayerBase];       
}

As you can see in loadImages1, I've basically just made 2 images, and loaded them separately.

I'm curious on your input on this:

  • Is this slow or a bad way to load images?
  • Is there some sort of sprite cache in cocos2d?
  • If this wasn't using ARC, does this ever pose a memory problem?

As you can see in loadImages2, I tried having a sprite sheet and loading from there.

I'm curious:

  • Is this better way to load images than the first?
  • Is there a way to load the picture at once and then just pick out segments of it? The code seems to keep reloading the same image.
\$\endgroup\$
1
\$\begingroup\$

is this slow or a bad way to load images?

Actually, yes and no. Cocos-2d goes the smart route and caches your sprite image internally, which makes the sprite's image not only re-useable, but it drastically speeds up the next time the method is called during program execution (it doesn't have to read an image off the disk into memory).

At the same time, you have access to sprite-sheet optimizations, so why not use them? It's much cheaper to load a large sprite sheet of 10-20 sprites, than to query the disk and load 10-20 images.

is there some sort of sprite cache in cocos2d?

See above. The class is called CCTextureCache, and it actually does some very low-level caching of the image (depending on your version of Cocos, it should even drop into OGL territory).

if this wasn't using ARC, does this ever pose a memory problem?

Actually, no. Convenience constructors (+[CCSprite spriteWithFile:]) are supposed to return autoreleased objects under MRC. Your local variables would be owned by you (0 -> 1), then autoreleased and crushed when they fell out of scope (1 -> 0).

is this better way to load images than the first? is there a way to load the picture at once and then just pick out segments of it? the code seems to keep reloading the same image

No, and Yes (respectively). I will direct you to one Ray Wenderlich, who has written more thoroughly on the subject than I.

A note on #defines

Defines are ultimately abstractions away from text. They are not magic, they are not intrinsic, and they are not smart. If you want truly good constants (which is really what you are using), define them as

static CGFloat const myVarName = someConstValue;

Although, kPositionXImg1 and kPositionYImg1 cannot be made into compile-time constants by definition, those can stay defined, however it would be quite a bit more readable to just eliminate the macro altogether and inline it.

\$\endgroup\$
  • \$\begingroup\$ Wow. thanks so much for your answer, this explains a lot!! the only reason i haven't accepted is to wait a little while to see if anyone else is going to give it a shot, but this is pretty darn awesome, thanks!! \$\endgroup\$ – David T. Nov 21 '12 at 20:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.