Cocos2d-x 3.0正式版中的数组改为容器
2016-07-20 01:56
295 查看
转自:http://blog.sina.com.cn/s/blog_4522f0b80102vgdw.html
Cocos2dx3.0,会遇到对象的值与对象的存储问题,即与ValueVectorVector(Map)。
在Cocos2dx 2.0版本,我们要存储一个int型数据,应该放到哪里?没错,放到CCArray中,如下:
int i=10;
CCArray _array=CCArray::create();//创建一个CCArray数组
_array->addObject(CCInteger::create(i));//将int型数据放入数组中
如果要存储一个CCObject对象,又是用什么存呢?是的,又是CCArray:
CCSprite*sp=CCSprite::create("star.png");//创建一个精灵
...
_array->addObject(sp);//将精灵放入到数组中
在Cocos2dx3.0版本,
我们都知道该版本的CCArray已经被甩了(实际上用__Array也还是可以替用一下),那么要存储一个Ref(3.0后CCObject改名为Ref)对象应该如何操作?机智的我马上想到了CCArray的替代者:Vector,示例代码如下:
autosp=Sprite::create("star.png");
...
Vector sp_vec;//创建一个Sprite*类型的容器
sp_vec.pushBack(sp);//将精灵放入到容器中
如果对Vector的操作不是很熟悉,可以看之前的博客:http://blog.csdn.net/star530/article/details/19170853
接下来问题来了,如果要存储一个数据类型,如int型数据,那么用Vector
可以实现吗?答案是否定的,在Vector的官方说明文档里有这么一句话:
cocos2d::Vector 中的T必须是一个指向cocos2d::Ref
子类对象的指针。不能是其他数据类型或者原生类型,因为我们已经将 Cocos2d-x
的内存管理模型集成到cocos2d::Vector 中。
有句话叫什么来着:上帝为你关上了一扇门,一定会为你打开一扇窗...此处不留爷,自有留爷处...
既然Vector容不下数据类型的元素,那么肯定有可以替代它的东西存在。没错,ValueVector登上了历史舞台。
第一次看到ValueVector时我就愣住了,这货又是什么碗糕?几秒后我反应过来,这货肯定是Value与Vector的私生子,我实在太特么机智了,这么抽象的命名都能让我快速想到答案,心中不禁暗自得意。先到CCValue.h
头文件中看下它的声明:
typedefstd::vectorValueVector;
可以看出,ValueVector
实际上就是一个存放Value类型元素的std::vector容器,这里和我之前的猜测有些出入。下面将几个int型数据存储到ValueVector中。
int a=10;
int b=20;
ValueVector val_vec;
val_vec.push_back(Value(a));
val_vec.push_back(Value(b));
上面代码就是创建两个int型的变量,然后放入ValueVector中,其中要注意的是:因为ValueVector中只能存放Value类型的元素,所以int型的a、b变量必须转换成Value类型后才能放入到ValueVector中。
关于Value
的一些用法,可以看之前的博客:http://blog.csdn.net/star530/article/details/21651751
说到ValueVector
,那就顺便提下它的一些简单操作:
1、读取Plist
(xml)配置文件。如下:
ValueVectorstar_val=FileUtils::getInstance()->getValueVectorFromFile("star.plist");
不过用ValueVector读取的plist文件只局限于是该plist的格式的以array数组类型开头的,例如下面这种:
name
star
isCool
yes
如果是以dict
字典类型开头的文件,则要换用ValueMap,这是下一篇的内容,先跳过。
2、往ValueVector
中插入一个元素。上面有提到过,ValueVector实际上就是一个存放Value类型的vector顺序容器,所以它的插入元素方式可以直接使用vector顺序容器的操作。示例如下:
int
a=10;
std::stringb="starissocool";
ValueVector star_val;
star_val.push_back(Value(a));
star_val.push_back(Value(b));//
放入ValueVector
前都要先将类型转成Value类型
提取ValueVector中的元素。这里我接上面的例子来用:
int
a1=star_val.at(0).asInt();
std::stringb1=star_val.at(1).asString();
CCLOG("a1=%d,b1=%s",a1,b1);
上面的代码比较容易理解,就是提取star_val
中放在0和1位置上的元素,然后分别转成int型和string型。asInt()与asString()是Value用来实现类型转换的函数。4、删除ValueVector中的元素。容器中比较常用的删除元素方式有三种:1)删除容器中最后一个元素,
star_val.pop_back();//
直接删除容器中最后一个元素
2)用erase删除容器中的某一个元素?为什么我要在前面加个问号呢?假设我要删除star_val中的 元素a,代码如下:
autostar_iter=std::find(star_val.begin(),star_val.end(),a);
star_val.erase(star_iter);
上面两行代码信息量还是比较大的,首先我们要知道erase 删除的是由一个迭代器指向的单个元素,而不是直接这样: star_val.erase(a);
这种操作是错误的。因为删除一个元素要用到迭代器,用到迭代器,就要用到find
函数,用到find函数,就要用到==运算符。但是cocos2d-x 3.0没用重载这个==运算符,所以这个方法行不通。
3)既然无法删除指定的元素,那我破罐子破摔,将全部元素都删除总可以吧?答案是肯定的:
star_val.clear();
好了,ValueVector
的用法说到这里,最后做下总结和补充:
1、Vector
只能用来存放Ref类型的元素,不能存放数据类型的元素;
2、ValueVector
只能用来存放Value类型的元素,因为Value说到底就是数据类型,所以也可以认为ValueVector只能用来存放数据类型,千万别将Ref类型的元素放进入,否则会很刺激。3、ValueVector中可以放ValueVector,前提是将ValueVector转成Value类型;而Vector中不能存放Vector类型的元素,如下:
ValueVector
star_val;
ValueVector
star_val2;
star_val.push_back(Value(star_val2));//正确
Vector> star_vec;//错误!
OK,就写到这里吧。
Cocos2dx3.0,会遇到对象的值与对象的存储问题,即与ValueVectorVector(Map)。
在Cocos2dx 2.0版本,我们要存储一个int型数据,应该放到哪里?没错,放到CCArray中,如下:
int i=10;
CCArray _array=CCArray::create();//创建一个CCArray数组
_array->addObject(CCInteger::create(i));//将int型数据放入数组中
如果要存储一个CCObject对象,又是用什么存呢?是的,又是CCArray:
CCSprite*sp=CCSprite::create("star.png");//创建一个精灵
...
_array->addObject(sp);//将精灵放入到数组中
在Cocos2dx3.0版本,
我们都知道该版本的CCArray已经被甩了(实际上用__Array也还是可以替用一下),那么要存储一个Ref(3.0后CCObject改名为Ref)对象应该如何操作?机智的我马上想到了CCArray的替代者:Vector,示例代码如下:
autosp=Sprite::create("star.png");
...
Vector sp_vec;//创建一个Sprite*类型的容器
sp_vec.pushBack(sp);//将精灵放入到容器中
如果对Vector的操作不是很熟悉,可以看之前的博客:http://blog.csdn.net/star530/article/details/19170853
接下来问题来了,如果要存储一个数据类型,如int型数据,那么用Vector
可以实现吗?答案是否定的,在Vector的官方说明文档里有这么一句话:
cocos2d::Vector 中的T必须是一个指向cocos2d::Ref
子类对象的指针。不能是其他数据类型或者原生类型,因为我们已经将 Cocos2d-x
的内存管理模型集成到cocos2d::Vector 中。
有句话叫什么来着:上帝为你关上了一扇门,一定会为你打开一扇窗...此处不留爷,自有留爷处...
既然Vector容不下数据类型的元素,那么肯定有可以替代它的东西存在。没错,ValueVector登上了历史舞台。
第一次看到ValueVector时我就愣住了,这货又是什么碗糕?几秒后我反应过来,这货肯定是Value与Vector的私生子,我实在太特么机智了,这么抽象的命名都能让我快速想到答案,心中不禁暗自得意。先到CCValue.h
头文件中看下它的声明:
typedefstd::vectorValueVector;
可以看出,ValueVector
实际上就是一个存放Value类型元素的std::vector容器,这里和我之前的猜测有些出入。下面将几个int型数据存储到ValueVector中。
int a=10;
int b=20;
ValueVector val_vec;
val_vec.push_back(Value(a));
val_vec.push_back(Value(b));
上面代码就是创建两个int型的变量,然后放入ValueVector中,其中要注意的是:因为ValueVector中只能存放Value类型的元素,所以int型的a、b变量必须转换成Value类型后才能放入到ValueVector中。
关于Value
的一些用法,可以看之前的博客:http://blog.csdn.net/star530/article/details/21651751
说到ValueVector
,那就顺便提下它的一些简单操作:
1、读取Plist
(xml)配置文件。如下:
ValueVectorstar_val=FileUtils::getInstance()->getValueVectorFromFile("star.plist");
不过用ValueVector读取的plist文件只局限于是该plist的格式的以array数组类型开头的,例如下面这种:
name
star
isCool
yes
如果是以dict
字典类型开头的文件,则要换用ValueMap,这是下一篇的内容,先跳过。
2、往ValueVector
中插入一个元素。上面有提到过,ValueVector实际上就是一个存放Value类型的vector顺序容器,所以它的插入元素方式可以直接使用vector顺序容器的操作。示例如下:
int
a=10;
std::stringb="starissocool";
ValueVector star_val;
star_val.push_back(Value(a));
star_val.push_back(Value(b));//
放入ValueVector
前都要先将类型转成Value类型
提取ValueVector中的元素。这里我接上面的例子来用:
int
a1=star_val.at(0).asInt();
std::stringb1=star_val.at(1).asString();
CCLOG("a1=%d,b1=%s",a1,b1);
上面的代码比较容易理解,就是提取star_val
中放在0和1位置上的元素,然后分别转成int型和string型。asInt()与asString()是Value用来实现类型转换的函数。4、删除ValueVector中的元素。容器中比较常用的删除元素方式有三种:1)删除容器中最后一个元素,
star_val.pop_back();//
直接删除容器中最后一个元素
2)用erase删除容器中的某一个元素?为什么我要在前面加个问号呢?假设我要删除star_val中的 元素a,代码如下:
autostar_iter=std::find(star_val.begin(),star_val.end(),a);
star_val.erase(star_iter);
上面两行代码信息量还是比较大的,首先我们要知道erase 删除的是由一个迭代器指向的单个元素,而不是直接这样: star_val.erase(a);
这种操作是错误的。因为删除一个元素要用到迭代器,用到迭代器,就要用到find
函数,用到find函数,就要用到==运算符。但是cocos2d-x 3.0没用重载这个==运算符,所以这个方法行不通。
3)既然无法删除指定的元素,那我破罐子破摔,将全部元素都删除总可以吧?答案是肯定的:
star_val.clear();
好了,ValueVector
的用法说到这里,最后做下总结和补充:
1、Vector
只能用来存放Ref类型的元素,不能存放数据类型的元素;
2、ValueVector
只能用来存放Value类型的元素,因为Value说到底就是数据类型,所以也可以认为ValueVector只能用来存放数据类型,千万别将Ref类型的元素放进入,否则会很刺激。3、ValueVector中可以放ValueVector,前提是将ValueVector转成Value类型;而Vector中不能存放Vector类型的元素,如下:
ValueVector
star_val;
ValueVector
star_val2;
star_val.push_back(Value(star_val2));//正确
Vector> star_vec;//错误!
OK,就写到这里吧。
相关文章推荐
- Cocos2dx 3.0 过渡篇(八)浅谈容器Vector
- Cocos2d-x3.0模版容器详解:cocos2d::Vector<T>
- cocos2d-x v3.0新特性及使用
- CocosCreator坐标代码
- CocosCreator快捷键
- CocosCreator中使玩家移动到点击位置
- CocosCreator获取某个节点
- Cocos2dx-3.x触摸事件之实现人机交互(三)
- CocosCreator运用(一)
- cocos2d-x 3.x sprite使用scale以后获取宽高
- 【Cocos】玩家输入事件
- 【Cocos】系统内置事件
- cocos -js 实现计算器功能
- Cocos Creator 加入CSV 文件
- Cocos 点击事件
- CocosCreator中使玩家移动到点击位置的代码
- native app 集成 cocos-2dx-js 3.11 (Android篇)
- 【转载】cocos2dx 3.x 声音播放、音量调节
- cocospod遇到的问题
- Expression: pSpriteFrame != 0