在游戏中加载屏幕(确保动画在过渡期间不会断断续续)

时间:2011-03-01 11:32:54

标签: iphone cocos2d-iphone nsthread nsautoreleasepool

我有一个cocos2d游戏,一旦游戏加载并运行,它的执行速度在55到60fps之间。

但是,由于我的菜单和游戏都使用了精灵表(每个都有一个),因此加载游戏时会出现交叉点,这会引起内存警告,因为有太多大的png被加载到内存中。

我实现了一个简单的CCScene转换到加载,(轻量级,允许菜单在继续加载主游戏币之前dealloc)。

这非常出色。然而,我已经遇到了一个小路障,在我的加载屏幕上,主要角色在加载一词旁边旋转(显示正在发生的事情)。

我发现我可以使用NSThread在不同的线程中加载游戏,允许我的加载场景的动画继续不受阻碍(这使得用户体验非常愉快)。

然而,5-6 / 10次,我收到此错误消息。

 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

我正在使用此代码加载我的游戏。

在按钮内 -

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

在新线程中执行的方法 -

-(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];

}

关于如何防止发生的事情发生的任何想法?

当gameScene尝试加载一个gameheet.plist(sphesheet和坐标中的单个图像的帧名)时,会导致NSLock

1 个答案:

答案 0 :(得分:2)

你自己正确地诊断了它,虽然它不是被解除分配的CCSpriteFrameCache但是依赖它的CCTextureCache。

如果您使用默认的cocos2d模板创建项目,则您的app委托通过调用[[CCDirector sharedDirector] purgeCachedData]来响应applicationDidReceiveMemoryWarning。这反过来调用[CCTextureCache purgeSharedTextureCache],它释放并删除共享缓存。这发生在您的主应用程序线程上,并且由于您的后台线程正在使用相同的缓存来存储它正在加载的纹理...繁荣。

最简单的解决方法是从应用委托中删除该purgeCachedData调用。您比应用程序更了解应用程序的内存消耗,所以不要让操作系统告诉您何时清除缓存,而是自己动手:只有当您知道缓存的纹理不再使用时才调用purgeCachedData。 / p>

从你的简短描述中,听起来你会在转换/加载场景开始时这样做。只需确保在之后执行清除,即可创建用于进度动画的精灵,以便保持其纹理。 (清除调用不会删除当前正在使用的任何内容。)同样,确保在启动后台线程之前执行清除 ,否则您将遇到同样的崩溃现在看。