zoukankan      html  css  js  c++  java
  • Cocos2dx 多线程

    多-threaded负荷plist特征。获取知识的必要性:

    1.多线程开启:pthread

    2.怎样在线程中载入plist


    一.多线程开启

    当我们想在程序中开多线程中。第一想到的是cocos2d-x有没有自带方法。幸运的是我们找到了CCThread,不幸却发现里面什么都没有。

    cocos2d-x自带了一个第三方插件--pthread,在cocos2dxplatform hird_partywin32pthread能够找到。既然是自带的,必须它的理由。想在VS中应用这个插件须要两个步骤:

    1.须要右键project--属性--配置属性--链接器--输入--编缉右側的附加依赖项--在当中加入pthreadVCE2.lib,例如以下图所看到的:


    2..须要右键project--属性--配置属性--C/C++--常规--编缉右側的附加包括文件夹--加入新行--找到pthread文件夹所在位置。例如以下图所看到的:



    然后我们就能够应用这个插件在程序中开启新线程。简单线程开启方法例如以下代码所看到的:

    头文件:

    1. #ifndef _LOADING_SCENE_H__  
    2. #define _LOADING_SCENE_H__  
    3.   
    4. #include "cocos2d.h"  
    5. #include "pthread/pthread.h"  
    6. class LoadingScene : public cocos2d::CCScene{  
    7. public:  
    8.     virtual bool init();  
    9.     CREATE_FUNC(LoadingScene);  
    10.     int start();    
    11.     void update(float dt);  
    12. private:  
    13.     pthread_t pid;  
    14.     static void* updateInfo(void* args); //注意线程函数必须是静态的  
    15. };  


    cpp文件
    1. #include "LoadingScene.h"  
    2. #include "pthread/pthread.h"  
    3.   
    4. using namespace cocos2d;  
    5. bool LoadingScene::init(){  
    6.     this->scheduleUpdate();  
    7.     start();  
    8.     return true;  
    9. }  
    10. void LoadingScene::update(float dt){  
    11.            //能够在这里重绘UI  
    12. }  
    13. void* LoadingScene::updateInfo(void* args){  
    14.       //能够在这里载入资源  
    15.     return NULL;  
    16. }  
    17. int LoadingScene::start(){  
    18.     pthread_create(&pid,NULL,updateInfo,NULL); //开启新线程  
    19.     return 0;  
    20. }  



    二 载入Plist

    我们能够在新开的线程中。载入资源,设置一个静态变量bool,在新线程中。当载入全然部资源后,设置bool值为真。在主线程中Update中,检測bool值,为假,能够重绘UI(比如,显示载入图片,或者模拟载入进度),为真,则载入目标场景。相关代码例如以下:

    1. void* LoadingScene::updateInfo(void* args){  
    2.      CCSpriteFrameCache *cache = CCSpriteFrameCache::sharedSpriteFrameCache();  
    3.      cache->addSpriteFramesWithFile("BattleIcons.plist");  
    4.      cache->addSpriteFramesWithFile("ArcherAnim.plist");  
    5.      cache->addSpriteFramesWithFile("DeathReaperAnim.plist");  
    6.      loadComplete = true;  //状态值设为真,表示载入完毕  
    7.      return NULL;  
    8. }  


    成功载入且执行后,你会发现新场景中全部精灵都不显示(类似于黑屏了)。为什么呢?

    由于我们在载入plist文件时,addSpriteFramesWithFile方法里会帮我们创建plist相应Png图的Texture2D,并将其载入进缓存中。但是这里就遇到了一个OpenGl规范的问题:不能在新开的线程中。创建texture,texture必须在主线程创建.通俗点,就是全部的opengl api都必须在主线程中调用;其他的操作,比方文件,内存。plist等,能够在新线程中做,这个不是cocos2d不支持,是opengl的标准,无论你是在android,还是windows上使用opengl,都是这个原理。

    所以不能在新线程中创建Texture2D,导致纹理都不显示。那么该怎么办?让我们看看CCSpriteFrameCache源代码。发现CCSpriteFrameCache::addSpriteFramesWithFile(const char *pszPlist, CCTexture2D *pobTexture)方法,是能够传入Texture2D參数的。

    是的。我们找到了解决方法:

    相关代码例如以下:

    1. int LoadingScene::start(){  
    2.     CCTexture2D *texture = CCTextureCache::sharedTextureCache()->addImage("BattleIcons.png"); //在这里(主线程中)载入plist相应的Png图片进纹理缓存  
    3.     CCTexture2D *texture2 = CCTextureCache::sharedTextureCache()->addImage("ArcherAnim.png"); //以这样的方法载入的纹理,其Key值就是文件path值,即比如  
    4. texture2的key值就是ArcherAnim.png  
    5.     CCTexture2D *texture3 = CCTextureCache::sharedTextureCache()->addImage("DeathReaperAnim.png");  
    6.     pthread_create(&pid,NULL,updateInfo,NULL); //开启新线程  
    7.     return 0;  
    8. }  
    9. void* LoadingScene::updateInfo(void* args){  
    10.     CCSpriteFrameCache *cache = CCSpriteFrameCache::sharedSpriteFrameCache();  
    11.     CCTextureCache* teCache = CCTextureCache::sharedTextureCache();     
    12.     CCTexture2D* texture1 = teCache->textureForKey("BattleIcons.png"); //从纹理缓存中取出Texure2D,并将其当參数传入addSpriteFramesWithFile方法中  
    13.     cache->addSpriteFramesWithFile("BattleIcons.plist",texture1);  
    14.     CCTexture2D* texture2 = teCache->textureForKey("ArcherAnim.png");  
    15.     cache->addSpriteFramesWithFile("ArcherAnim.plist",texture2);  
    16.     CCTexture2D* texture3 = teCache->textureForKey("DeathReaperAnim.png");  
    17.     cache->addSpriteFramesWithFile("DeathReaperAnim.plist",texture3);  
    18.     loadComplete = true;  
    19.     return NULL;  
    20. }  


    解决。这是不是违背OpenGl产品规格,不要创建一个新的线程Texture2D。


  • 相关阅读:
    PHP+MYSQL不错的环境架设软件
    ASV2011(Action Script Viewer)免费升级
    Win2003证书服务配置/客户端(服务端)证书申请/IIS站点SSL设置
    Entity FrameWork 4 PoCo使用
    使用Forms Authentication实现用户注册、登录
    验证数字的正则表达式集
    web.config/app.config敏感数据加/解密的二种方法
    如何创建一个标准的Windows服务
    抛弃WebService 在.NET4中用jQuery调用WCF
    EF 中调用带输出参数的存储过程
  • 原文地址:https://www.cnblogs.com/hrhguanli/p/4874291.html
Copyright © 2011-2022 走看看