首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用大中心调度在cocos2d中加载sprites

使用大中心调度在cocos2d中加载sprites
EN

Stack Overflow用户
提问于 2014-05-22 11:32:11
回答 2查看 480关注 0票数 1

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

代码语言:javascript
运行
复制
    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中,我只是通过

代码语言:javascript
运行
复制
physicsSprite.sprite = [CCSprite spriteWithSpriteFrameName:@"bla.png"];

和方法

代码语言:javascript
运行
复制
[physicsSprite createAnimation];

用于添加加载的雪碧到mainLayer节点。

所有这些逻辑都运行得很好。但是我在想,如果我做错了什么,因为我没有创建OpenGL context

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

代码语言:javascript
运行
复制
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创建上下文。所以,我做错了什么?不创造背景..。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-05-22 15:55:53

FRom CCTextureCache:addImageAsync:

代码语言:javascript
运行
复制
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的这个结果会立即得到结果。

回答自己的问题很有趣。

票数 0
EN

Stack Overflow用户

发布于 2014-05-22 11:54:30

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

最明确的是,您不应该创建自己的EAGLContext,也不应该在分派块中创建cocos2d视图。这个具有由cocos2d内部处理的

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

代码语言:javascript
运行
复制
CCTextureCache* texCache = [CCTextureCache sharedTextureCache];
[texCache addImageAsync:image target:self selector:@selector(didLoadTexture:)];

然后在纹理可用时调用选择器:

代码语言:javascript
运行
复制
-(void) didLoadTexture:(CCTexture2D*)texture
{
}

可以使用选择器来使用纹理初始化sprite。因为如果您在前面这样做,cocos2d将尝试使用正常的同步方法立即加载纹理。如果在异步加载的同时发生这种情况,它甚至可能崩溃。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23805623

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档