Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Multithreading 使用grand central dispatch在cocos2d中加载精灵_Multithreading_Cocos2d Iphone_Loading_Grand Central Dispatch_Ccsprite - Fatal编程技术网

Multithreading 使用grand central dispatch在cocos2d中加载精灵

Multithreading 使用grand central dispatch在cocos2d中加载精灵,multithreading,cocos2d-iphone,loading,grand-central-dispatch,ccsprite,Multithreading,Cocos2d Iphone,Loading,Grand Central Dispatch,Ccsprite,在我的游戏中,我使用这样的方法异步加载精灵: dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{ [physicsSprite loadSprite]; dispatch_async(dispatch_get_main_queue(), ^{ [physicsSprite createAnimation];

在我的游戏中,我使用这样的方法异步加载精灵:

    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上下文

因此,我尝试了使用上下文的代码:

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];
                            });
                        });
结果我看不出游戏性有什么不同


但正如我所知,我需要为加载到另一个线程中的任何精灵创建上下文。那么,我做错了什么?如果不创建上下文…

Cocos2d不是线程安全的,任何更改OpenGL状态或使用OpenGL上下文的代码都必须在主线程上运行(与OpenGL上下文相同的线程)。尝试使用
dispatch\u async
加载纹理(精灵)将是徒劳的

最明确的是,您不应该创建自己的EAGLContext,也不应该在调度块中创建cocos2d视图。此由cocos2d内部处理

但是,CCTextureCache和其他类具有异步加载纹理和精灵帧的方法,例如:

CCTextureCache* texCache = [CCTextureCache sharedTextureCache];
[texCache addImageAsync:image target:self selector:@selector(didLoadTexture:)];
然后在纹理可用时调用选择器:

-(void) didLoadTexture:(CCTexture2D*)texture
{
}

可以使用选择器使用纹理初始化精灵。因为如果您更早这样做,cocos2d将尝试使用正常的同步方法立即加载纹理。如果这与异步加载同时发生,它甚至可能崩溃。

来自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];
}
所以,如果以代码为例:我需要使用带有上下文的代码。刚刚检查过这个。当纹理从内存卸载时,我尝试使用justloadSprite方法加载它-它首先加载纹理文件pvr.ccz(因为它没有加载到内存),然后从纹理创建sprite,但如果没有上下文,它将只是黑色方形,而不是图像。我没有遇到这样的问题的原因是——我在iPad4:p上测试过,它有足够的内存。检查iPad 3或iPhone4\4s的这一点,立即给出结果


p、 回答自己的问题很有趣。

我在加载屏幕上使用addImageAsync。因此,纹理已经加载到内存中。然而,有时会卸载一些纹理,因为游戏会收到内存警告。我有3个非常大的纹理,大约3500x4000px,可能还有2个更小的纹理1000x1500px。当游戏运行时,它会在加载屏幕上加载所有这些文件,但稍后,在内存警告后,它会卸载其中的一些文件。无论如何,即使在这种情况下,我也能很好地工作。。所以,我不明白我的代码中是否需要上下文。您是否知道,大于2048x2048的纹理大小会使您的应用程序无法在iPad 1、iPhone 4及更早版本上运行?您的3500x4000(每像素32位的倍数)每台电脑消耗大约53兆字节?您最好的选择是将颜色深度减少到16位到内存使用量的一半,或者使用.pvr.ccz使其加载速度超快,并使用更少的内存。TexturePacker可以创建.pvr.ccz纹理。是的,使用这么大的纹理是疯狂的(而且基本上毫无意义)。是的,可以肯定,min iOS 7,所以只有iPhone 4在这里。。。是的,53mb,但我能做的是,我的游戏需要如此漂亮的图形:)当然我使用的是pvr.ccz。但不管怎样,有时我的比赛会落后。。比如小挂起..我已经检查了一些其他格式,5551看起来适合大多数图像。。也许我需要试试。。