在我的游戏中,我使用这样的方法异步加载such:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
[physicsSprite loadSprite];
dispatch_async(dispatch_get_main_queue(), ^{
[physicsSprite createAnimation];
[physicsSprite createBodyInWorld:world;
});
});physicsSprite,它只是一个节点,保存着CCSprite子节点。在方法loadSprite中,我只是通过
physicsSprite.sprite = [CCSprite spriteWithSpriteFrameName:@"bla.png"];和方法
[physicsSprite createAnimation];用于添加加载的雪碧到mainLayer节点。
所有这些逻辑都运行得很好。但是我在想,如果我做错了什么,因为我没有创建OpenGL context
因此,我尝试了我的代码与上下文:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
CCGLView *view = (CCGLView*)[[CCDirector sharedDirector] view];
EAGLContext *auxGLcontext = [[[EAGLContext alloc]
initWithAPI:kEAGLRenderingAPIOpenGLES2
sharegroup:[[view context] sharegroup]] autorelease];
if( [EAGLContext setCurrentContext:auxGLcontext] ) {
[physicsSprite loadSprite];
glFlush();
[EAGLContext setCurrentContext:nil];
}
dispatch_async(dispatch_get_main_queue(), ^{
[physicsSprite createAnimation];
[physicsSprite createBodyInWorld:world];
});
});结果,我看不出游戏中有什么不同。
但正如我所知,我需要为加载在另一个线程中的任何sprite创建上下文。所以,我做错了什么?不创造背景..。
发布于 2014-05-22 15:55:53
FRom CCTextureCache:addImageAsync:
if( [EAGLContext setCurrentContext:_auxGLcontext] ) {
// load / create the texture
texture = [self addImage:path];
glFlush();
// callback should be executed in cocos2d thread
[target performSelector:selector onThread:[[CCDirector sharedDirector] runningThread] withObject:texture waitUntilDone:NO];
[EAGLContext setCurrentContext:nil];
}所以,如果以代码为例,我需要在上下文中使用代码。刚查过这个。当纹理从内存中卸载时,我尝试使用loadSprite方法加载它--它首先加载纹理文件pvr.ccz(因为它没有加载到内存中),然后从纹理创建sprite,但是没有context,它将只是黑方块而不是图像。我之所以没有遇到这样的问题--我已经在iPad 4 :p上测试过了,它有足够的内存。检查iPad 3或iPhone4\4的这个结果会立即得到结果。
回答自己的问题很有趣。
发布于 2014-05-22 11:54:30
Cocos2d不是线程安全的,任何更改OpenGL状态或使用OpenGL上下文的代码都必须在主线程(与OpenGL上下文相同的线程)上运行。使用dispatch_async加载纹理(精灵)的尝试将是徒劳的。
最明确的是,您不应该创建自己的EAGLContext,也不应该在分派块中创建cocos2d视图。这个具有由cocos2d内部处理的。
但是,CCTextureCache和其他类都有异步加载纹理和精灵帧的方法,例如:
CCTextureCache* texCache = [CCTextureCache sharedTextureCache];
[texCache addImageAsync:image target:self selector:@selector(didLoadTexture:)];然后在纹理可用时调用选择器:
-(void) didLoadTexture:(CCTexture2D*)texture
{
}可以使用选择器来使用纹理初始化sprite。因为如果您在前面这样做,cocos2d将尝试使用正常的同步方法立即加载纹理。如果在异步加载的同时发生这种情况,它甚至可能崩溃。
https://stackoverflow.com/questions/23805623
复制相似问题