开发者

Loading screens in games (ensuring animations don't stutter during the transition)

I have a cocos2d game, it performs at between 55 and 60fps once the game is loaded and running.

However, due to using sprite sheets for both my menu's and game (one for each), there was a point of crossover when loading the game which would cause memory warnings, due to too many large png's loaded into memory.

I implemeneted a simple CCScene to transition to for loading, (lightweight, allowing the menu开发者_JS百科 to dealloc before proceeding to load the main gamescene).

This works brilliantly. However, i have hit a little road block, on my loading screen i have the main character spinning next to the word loading (to show something is happening).

I discovered that i could use NSThread to load the game in a different thread, allowing the animation of my loading scene to continue unhindered (this made for a very pleasant user experience).

However, 5-6/10 times, i get this error message.

 Received memory warning. Level=1
 *** -[NSLock dealloc]: lock (<NSLock: 0x3ded70> '(null)') deallocated while still in use
  *** Break on _NSLockError() to debug.
  *** -[CFDictionary setObject:forKey:]: message sent to deallocated instance 0x3decc0

I am using this code to load my game.

Within a button -

NSThread* thread = [[[NSThread alloc] initWithTarget:self selector:@selector(goToNextScene) object:nil] autorelease];
[thread start];

The method executed in the new thread -

-(void) goToNextScene {

NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init];

EAGLContext *k_context = [[[EAGLContext alloc]
                           initWithAPI :kEAGLRenderingAPIOpenGLES1
                           sharegroup:[[[[CCDirector sharedDirector] openGLView] context] sharegroup]] autorelease];
[EAGLContext setCurrentContext:k_context];

CCScene *gs = [GameEngine scene];

[[CCDirector sharedDirector] replaceScene:[CCTransitionFade transitionWithDuration:0.5 scene:gs]];

[autoreleasepool release];

}

Any ideas on how i can prevent whatever is happening from happening?

The NSLock is caused when the gameScene tries to load a gamesheet.plist (framenames of individual images within teh spritesheet and co-ordinates)


You diagnosed it correctly yourself, although it's not CCSpriteFrameCache that's being dealloced but the CCTextureCache it relies on.

If you created your project from the default cocos2d template, your app delegate responds to applicationDidReceiveMemoryWarning by calling [[CCDirector sharedDirector] purgeCachedData]. This in turn calls [CCTextureCache purgeSharedTextureCache], which releases and nils out the shared cache. That happens on your main app thread, and since your background thread is in the middle of using that same cache to store the textures it's loading... boom.

The simplest fix is just to remove that purgeCachedData call from your app delegate. You understand your app's memory consumption better than the OS does, so rather than let the OS tell you when to purge your cache, do it yourself: Call purgeCachedData only when you know you have textures cached that you won't be using anymore.

From your brief description, it sounds like you would do that at the start of your transition/loading scene. Just be sure to do the purge after you create the sprites you use for your progress animation, so that their textures are kept around. (The purge call doesn't delete anything that's currently in use.) Likewise, be sure to do the purge before you kick off your background thread, or else you'll get the same crash you're seeing now.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜