I’m writing an iPhone game using the Cocos2d-iPhone framework. It’s been smooth sailing except for one little detail: I want a sprite to change it’s image based on a touch.
I think the problem is that there are a dozen ways to do this in Cocos2d. I wanted to find the simplest way to do it. A quick Google search pointed me in the direction of CCAnimationCache and CCTextureCache.
CCAnimationCache is used for running multi-frame animations inside a single sprite. I only have 2 frames for my sprite! CCAnimationCache could do it but it’s a more power than I need to respond to a touch. (If you want to give animation a try check out Ray Wenderlich’s wonderful tutorial.)
CCTextureCache would have been the way to go if I hadn’t already used CCSpriteFrameCache to load all my sprite images at the start of my game. CCSpriteFrameCache uses a plist that divides up a large image into rectangle so you can pack all your sprite images into one memory saving “texture atlas.” And you can use Zwoptex to generate the image and the plist for you. CCTextureCache is the manual way to do what CCSpriteFrameCache and Zwoptex automates for you. (If you like to be hard core check out Ben’s post on optimizing texture loading.)
I figured there had to be a way to use my sprite frames in my existing cache without having to resort to manually loading textures or creating animations I didn’t need.
There was! It’s simple and here’s how to do it…
First, create your texture atlas with Zwoptex and add the .plist and .png files to your Resources folder in your Xcode project.
Second, load the texture atlas into the shared frame cache early in your game…
CCSpriteFrameCache* frameCache = [CCSpriteFrameCache sharedSpriteFrameCache]; [frameCache addSpriteFramesWithFile:@"textureAtlas.png"];
Third, create your sprite in your layer’s – init method…
// Note: niceSprite is a CSprint* instance variable so we can reuse it niceSprite = [CCSprite spriteWithSpriteFrameName:@"initial_image.png"]; niceSprite.position = CGPointMake(240, 160); [self addChild:niceSprite z:0 tag:0];
Fourth, in your – ccTouchBegan or – ccTouchesBegan method add the following code to change the image associated with your sprite…
CCSpriteFrameCache* frameCache = [CCSpriteFrameCache sharedSpriteFrameCache]; CCSpriteFrame* frame = [frameCache spriteFrameByName:@"new_image.png"]; [niceSprite setDisplayFrame:frame];
That was easy!