Cocos2d-x 3.0多线程异步资源载入代码
// AppDelegate.cpp bool AppDelegate::applicationDidFinishLaunching() { … … FlashScene* scene = FlashScene::create(); pDirector->runWithScene(scene); return true; }
//FlashScene.h //在FlashScene init时,我们创建一个Resource Load Thread。我们用一个ResourceLoadIndicator作为渲染线程与Worker线程之间交互的媒介。struct ResourceLoadIndicator { pthread_mutex_t mutex; bool load_done; void *context; }; class FlashScene : public Scene { public: FlashScene(void); ~FlashScene(void); virtual bool init(); CREATE_FUNC(FlashScene); bool getResourceLoadIndicator(); void setResourceLoadIndicator(bool flag); private: void updateScene(float dt); private: ResourceLoadIndicator rli; };
// FlashScene.cpp bool FlashScene::init() { bool bRet = false; do { CC_BREAK_IF(!CCScene::init()); Size winSize = Director::getInstance()->getWinSize(); //FlashScene自己的资源仅仅能同步载入了 Sprite *bg = Sprite::create("FlashSceenBg.png"); CC_BREAK_IF(!bg); bg->setPosition(ccp(winSize.width/2, winSize.height/2)); this->addChild(bg, 0); this->schedule(schedule_selector(FlashScene::updateScene) , 0.01f); //start the resource loading thread rli.load_done = false; rli.context = (void*)this; pthread_mutex_init(&rli.mutex, NULL); pthread_attr_t attr; pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); pthread_t thread; pthread_create(&thread, &attr, resource_load_thread_entry, &rli); bRet=true; } while(0); return bRet; } static void* resource_load_thread_entry(void* param) { AppDelegate *app = (AppDelegate*)Application::getInstance(); ResourceLoadIndicator *rli = (ResourceLoadIndicator*)param; FlashScene *scene = (FlashScene*)rli->context; //load music effect resource … … //init from config files … … //load images data in worker thread SpriteFrameCache::getInstance()->addSpriteFramesWithFile( "All-Sprites.plist"); … … //set loading done scene->setResourceLoadIndicator(true); return NULL; } bool FlashScene::getResourceLoadIndicator() { bool flag; pthread_mutex_lock(&rli.mutex); flag = rli.load_done; pthread_mutex_unlock(&rli.mutex); return flag; } void FlashScene::setResourceLoadIndicator(bool flag) { pthread_mutex_lock(&rli.mutex); rli.load_done = flag; pthread_mutex_unlock(&rli.mutex); return; } //我们在定时器回调函数中对indicator标志位进行检查。当发现载入ok后,切换到接下来的游戏開始场景: void FlashScene::updateScene(float dt) { if (getResourceLoadIndicator()) { Director::getInstance()->replaceScene( WelcomeScene::create()); } }
加入1:
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) #include "platform/android/jni/JniHelper.h" #include <jni.h> #endif static void* resource_load_thread_entry(void* param) { … … JavaVM *vm; JNIEnv *env; vm = JniHelper::getJavaVM(); JavaVMAttachArgs thread_args; thread_args.name = "Resource Load"; thread_args.version = JNI_VERSION_1_4; thread_args.group = NULL; vm->AttachCurrentThread(&env, &thread_args); … … //Your Jni Calls … … vm->DetachCurrentThread(); … … return NULL; }
加入2:
static void* resource_load_thread_entry(void* param) { … … allSpritesImage = new Image(); allSpritesImage->initWithImageFile("All-Sprites.png"); … … } void FlashScene::updateScene(float dt) { if (getResourceLoadIndicator()) { // construct texture with preloaded images Texture2D *allSpritesTexture = TextureCache::getInstance()-> addImage(allSpritesImage, "All-Sprites.png"); allSpritesImage->release(); SpriteFrameCache::getInstance()->addSpriteFramesWithFile( "All-Sprites.plist", allSpritesTexture); Director::getInstance()->replaceScene(WelcomeScene::create()); } }