cocos2d-x多线程 plist(转)

转载 2014年01月07日 13:45:56

转自:http://blog.sina.com.cn/s/blog_7608655901017s2b.html


最近在修改一个cocos2d的项目,要把它移植到cocos2d-x,原来的项目中用到了多线程,但是在cocos2d-x中的实现有点不太一样,在CSDN上找了一篇文章,有详细的代码示例:在新的线程中加载资源文件。原文地址:http://blog.csdn.net/we000636/article/details/8641270

原文章是在windows系统下讲解的,在xcode中同样需要导入pThread类库。

简单线程开启方法如下代码所示:

头文件:

.h

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



 

cpp文件
#include "LoadingScene.h"  

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




 

二加载Plist

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

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



 

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

因为我们在加载plist文件时,addSpriteFramesWithFile方法里会帮我们创建plist对应Png图的Texture2D,并将其加载进缓存中。可是这里就遇到了一个OpenGl规范的问题:不能在新开的线程中,创建texture,texture必须在主线程创建.通俗点,就是所有的opengl api都必须在主线程中调用;其它的操作,比如文件,内存,plist等,可以在新线程中做,这个不是cocos2d不支持,是opengl的标准,不管你是在android,还是windows上使用opengl,都是这个原理。

所以不能在新线程中创建Texture2D,导致纹理都不显示,那么该怎么办?让我们看看CCSpriteFrameCache源码,发现CCSpriteFrameCache::addSpriteFramesWithFile(constchar *pszPlist, CCTexture2D*pobTexture)方法,是可以传入Texture2D参数的。是的,我们找到了解决方法:

相关代码如下:

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



 

这样解决,就不违背OpenGl规范,没有在新线程中创建Texture2D。

【Cocos2d-x】 Cocos2d-x 3.X 异步加载plist图片资源

1、异步加载plist cocos2dx-x本身帮我们封装了一个名为addImageAsync的函数帮我们实现图片的异步加载。 /** Returns a Texture2D object gi...
  • Xiejingfa
  • Xiejingfa
  • 2015年07月17日 20:03
  • 2662

将xml代码或文件转为plist文件(xcode)

刚刚无意间发现了一个小窍门,可以轻松的将xml转为plist文件,哈哈,好开心 ------需要转换的代码 "1.0" encoding="UTF-8"?> "-//Apple//DTD PLI...
  • tutuzhuz
  • tutuzhuz
  • 2016年08月01日 17:26
  • 2463

【iOS】Plist-XML-JSON数据解析

网络上传输数据通用的有XML,JSON等,iOS中也可以用Plist。 要进行数据传输,就要首先进行序列化: 1.序列化. * 对象转换成二进制流.(这个一句话就行) 2.反序列化. * 二进制流转...
  • xn4545945
  • xn4545945
  • 2014年07月13日 01:51
  • 9281

171,.plist文件中字典数据转成程序模型

AppData.h: #import @interface AppData : NSObject @property(nonatomic,cop...
  • dreamljs
  • dreamljs
  • 2016年01月04日 13:35
  • 321

json文件转为plist文件输出

从xx.json文件中读取JSON数据,写入到xx.plist文件中,实现代码如下: NSString *path = @"/Users/apple/Desktop/testJtoP/test...
  • mscinsidious
  • mscinsidious
  • 2017年07月20日 18:33
  • 279

cocos2d-x 使用plist创建精灵并执行动画

素材图: 然后使用Texture Packer放到一张图片上,并生成plist文件 接下来直接上代码 [cpp] view plaincopy ...
  • Liar0606
  • Liar0606
  • 2014年01月20日 22:11
  • 1610

如何把txt文档导入到plist文件中

有时候我们需要很多数据,这些数据是改动较少的,或者是根本就不需要改动的数据,同时,我们又不想要直接联网获取的时候,比如省市地区这些本身改动不大的数据,大多数的应用都会直接封装在应用里面,直接写成一个数...
  • kivenhehaoyu
  • kivenhehaoyu
  • 2015年03月31日 20:17
  • 984

(二)plist的使用和序列帧动画

六.plist的使用方法: iOS的程序在安装在手机上以后会把全部资源文件集成在一个文件夹中,这种文件集合称为bundle,对于一般的工程,只有一个bundle,即mainbundle,因此可以通过b...
  • xyt8023y
  • xyt8023y
  • 2015年02月04日 21:03
  • 1020

cocos2d-x使用TexturePacker打包图片及使用生成的plist文件创建精灵动画

在使用TexturePacker打包工具之前先对动画的每一帧图片命名,我这里选取的cocos2d-x实例程序里面的图片,为了方便只提取了前面4帧的图片 然后打开安装好的TexturePa...
  • carzyer
  • carzyer
  • 2014年10月21日 16:33
  • 1273

iOS UI篇 - plist文件字典转模型

plist文件字典转模型 1.首先定义一个成员变量,存放所需的数据. 即:NSArray *apps #pragma mark - 重写apps的getter方法 -(NSArray *)apps{ ...
  • jeikerxiao
  • jeikerxiao
  • 2016年09月09日 09:56
  • 446
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:cocos2d-x多线程 plist(转)
举报原因:
原因补充:

(最多只允许输入30个字)