Cocos2d-x 3.0正式版中的數組改爲容器

轉自: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

頭文件中看下它的聲明:

  1. 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)配置文件。如下:

  1. 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類型 

  1. 提取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,就寫到這裏吧。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章