在游戏中加载屏幕(确保动画在转换过程中不会卡顿)

发布于 2024-10-19 14:45:29 字数 1527 浏览 6 评论 0原文

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

然而,由于我的菜单和游戏都使用精灵表(每个精灵表一个),加载游戏时会出现一个交叉点,这会导致内存警告,因为内存中加载了太多大的 png。

我实现了一个简单的 CCScene 来过渡到加载(轻量级,允许菜单在继续加载主游戏场景之前解除分配)。

这非常有效。然而,我遇到了一个小障碍,在我的加载屏幕上,我的主角在“加载”一词旁边旋转(以显示正在发生的事情)。

我发现我可以使用 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];

}

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

NSLock 是在 gameScene 尝试加载 gamesheet.plist(精灵表中各个图像的帧名和坐标)时引起的

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 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)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

路还长,别太狂 2024-10-26 14:45:29

您自己诊断正确,尽管被释放的不是CCSpriteFrameCache,而是它所依赖的CCTextureCache。

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

最简单的修复方法就是从应用程序委托中删除 purgeCachedData 调用。您比操作系统更了解应用程序的内存消耗,因此不要让操作系统告诉您何时清除缓存,而是自己做:仅当您知道缓存了不再使用的纹理时才调用 purgeCachedData。

从您的简短描述来看,听起来您会在过渡/加载场景开始时执行此操作。请务必在创建用于进度动画的精灵之后进行清除,以便保留它们的纹理。 (清除调用不会删除当前正在使用的任何内容。)同样,请务必在启动后台线程之前进行清除,否则您将遇到与之前相同的崩溃现在看到了。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文