Cocos2d-x中__Dictionary容器以及執行個體介紹,cocos2d執行個體

來源:互聯網
上載者:User

Cocos2d-x中__Dictionary容器以及執行個體介紹,cocos2d執行個體
__Dictionary類在Cocos2d-x 2.x時代它就是CCDictionary類,它是模仿Objective-C中的NSDictionary類而設計的,通過引用計數管理記憶體。__Dictionary繼承於Ref類,因此它所能容納的是Ref及子類所建立的對象指標。

 

1、建立__Dictionary對象

建立__Dictionary對象有很多函數,下面是總結常用的函數:

static __Dictionary* create()。建立__ Dictionary。

 static __Dictionary* createWithDictionary(__Dictionary* srcDict)。用一個已存在的__Dictionary來建立一個新的__Dictionary。

 static __Dictionary* createWithContentsOfFile(const char *pFileName)。從屬性列表檔案建立__Dictionary。  

 

2、添加元素

向__Dictionary對象中添加元素都必須是“鍵-值”對,“鍵”可以是字串(std::string)類型或整數(signed int)類型,而“值”必須是Ref和其子類的對象指標類型。下面是總結常用的函數:

 void setObject(Ref* pObject, const std::string& key)。插入一個“鍵-值”對,其中pObject是“值”,key是“鍵”。如果是第一次調用,__Dictionary的“鍵”類型是字串型,之後就不能插入整型“鍵”。如果已存在該“鍵”,則舊“鍵-值”對會被釋放和移除,被新的替代。

 void setObject(Ref* pObject, intptr_t key)。插入一個“鍵-值”對,其中pObject是“值”,key是“鍵”, intptr_t類型是signed int類型的別名,為整型。如果是第一次調用,__Dictionary的“鍵”類型是整型,之後就不能插入字串型“鍵”,如果已存在該“鍵”,則舊“鍵-值”對會被釋放和移除,被新的替代。

 

3、移除元素

下面是總結常用的移除__Dictionary容器中元素的函數:

 void removeObjectForKey(const std::string& key)。通過指定鍵移除元素。

 void removeObjectForKey(intptr_t key)。通過指定鍵移除元素。 

 void removeObjectsForKeys(__Array* pKeyArray)。通過一個__Array中鍵集合移除元素。  

 void removeObjectForElememt(DictElement* pElement)。通過指定元素來移除。

 void removeAllObjects()。移除所有的元素。

 

4、尋找元素

我們還可以通過下面函數對__Dictionary容器中元素尋找:

 Ref* objectForKey(const std::string& key)。返回指定字串類型“鍵”的“值”。

 Ref* objectForKey(intptr_t key)。返回指定整型“鍵”的“值”。

 const __String* valueForKey(const std::string& key)。返回指定字串類型“鍵”的“值”,傳回值是__String指標類型,這裡假定“值”是__String指標型,如果不是或者未找到,則返回空串。 

 const __String* valueForKey(intptr_t key)。返回指定整型“鍵”的“值”,傳回值是__String指標類型,這裡假定“值”是__String指標,如果不是或者未找到,則返回空串。

 

5、其它操作函數

此外還有很多操作__Dictionary對象函數,下面是總結常用的函數:

 __Array* allKeys()。返回一個包含所有“鍵”的“值”的__Array容器。

 unsigned int count()。返回元素個數。 

 bool writeToFile(const char *fullPath)。把__Dictionary寫到一個屬性列表檔案中,寫入的“值”要求是字串型。 

 

6、遍曆__Dictionary容器

Cocos2d-x提供了兩個遍曆__Dictionary容器的宏:

 CCDICT_FOREACH。遍曆__Dictionary容器。

 

執行個體:__Dictionary容器

下面我們通過一個執行個體介紹__Dictionary字典容器中的相關函數。所示情境,點擊右下角的Go按鈕,在情境中添加100個Ball精靈和100個icon精靈。 

 

 __Dictionary字典容器執行個體

 

為了學習__Dictionary類的使用,我們在程式中分別建立100個Ball精靈和100個icon精靈,並把它們分別添加到不同的__Dictionary容器中。 

下面我們看看代碼部分,HelloWorldScene.h代碼如下: 

#ifndef __HELLOWORLD_SCENE_H__#define __HELLOWORLD_SCENE_H__ #include "cocos2d.h" #define MAX_COUNT 100① class HelloWorld : public cocos2d::Layer{cocos2d::__Dictionary* dict1; ②cocos2d::__Dictionary* dict2; ③ public: ~HelloWorld();④    static cocos2d::Scene* createScene();    virtual bool init();          void menuCloseCallback(cocos2d::Ref* pSender);        CREATE_FUNC(HelloWorld);}; #endif // __HELLOWORLD_SCENE_H__

上述代碼第①行代碼#define MAX_COUNT 100定義宏MAX_COUNT,MAX_COUNT定義了一次產生的精靈數。第②和③行代碼聲明__Dictionary*的成員變數dict1和dict2。第④行代碼是聲明解構函式,我們需要在解構函式中釋放成員變數dict1和dict2。

HelloWorldScene.cpp中的init函數代碼如下:

bool HelloWorld::init(){if ( !Layer::init() ){return false;} Size visibleSize = Director::getInstance()->getVisibleSize();Vec2 origin = Director::getInstance()->getVisibleOrigin(); auto goItem = MenuItemImage::create("go-down.png","go-up.png",CC_CALLBACK_1(HelloWorld::menuCloseCallback, this)); goItem->setPosition(Vec2(origin.x + visibleSize.width - goItem->getContentSize().width/2 ,origin.y + goItem->getContentSize().height/2)); auto menu = Menu::create(goItem, NULL);menu->setPosition(Vec2::ZERO);this->addChild(menu, 1); this->dict1  = __Dictionary::create();①this->dict1->retain();②this->dict2  = __Dictionary::create();this->dict2->retain(); for(int i = 0;i < MAX_COUNT; ++i){ ③ auto sprite1 = Sprite::create("Ball.png");④this->dict1->setObject(sprite1, i);⑤ auto sprite2 = Sprite::create("icon.png");⑥__String *key = __String::createWithFormat("key%d",i);⑦this->dict2->setObject(sprite2, key->getCString());⑧}return true;}

init是初始化情境的函數,我們在該函數中建立了200個精靈,並把它們分別放到__Dictionary*類型的dict1 和dict2成員變數中。其中第①行代碼是建立__Dictionary*類型的dict1成員變數,使用create函數。第②行代碼this->dict1->retain()非常重要,retain是保持dict1對象在一個遊戲迴圈事件後記憶體不會自動釋放,這涉及到Ref記憶體管理問題,我們將在第19章給大家詳細介紹。如果this->dict1->retain()語句,dict1對象會被釋放,在其它函數dict1容器物件就會出錯。

第③行代碼是迴圈建立精靈對象。第④行代碼是建立Ball精靈對象,第⑤行代碼this->dict1->setObject(sprite1, i)是使用迴圈變數i作為鍵,把Ball精靈對象添加到dict1容器物件中。第⑥行代碼是建立icon精靈對象。第⑦行代碼是根據迴圈變數i,建立字串,如:key0、key1等形式。第⑧行代碼把icon精靈對象添加到dict2容器物件中。

需要注意的是這些精靈對象還沒有被添加到情境中,因此,情境顯示的時候它們是不出現的。

HelloWorldScene.cpp中的menuCloseCallback函數代碼如下:

void HelloWorld::menuCloseCallback(Ref* pSender){ Size visibleSize = Director::getInstance()->getVisibleSize(); DictElement* pElement; ① log("Dict1 key-value count = %d",this->dict1->count());CCDICT_FOREACH(dict1, pElement)  ②{int key = pElement->getIntKey();  ③log("Add Sprite %d", key); Sprite* sprite = (Sprite*)pElement->getObject();④ int x = CCRANDOM_0_1() * visibleSize.width;int y = CCRANDOM_0_1() * visibleSize.height; sprite->setPosition( Vec2(x, y) );this->removeChild(sprite);this->addChild(sprite);}  log("Dict2 key-value count = %d",this->dict2->count());CCDICT_FOREACH(dict2, pElement)  ⑤{const char *key = pElement->getStrKey();  ⑥log("Add Sprite %s", key); Sprite* sprite = (Sprite*)pElement->getObject(); int x = CCRANDOM_0_1() * visibleSize.width;int y = CCRANDOM_0_1() * visibleSize.height; sprite->setPosition( Vec2(x, y) );this->removeChild(sprite);this->addChild(sprite);} }

該函數是在玩家觸摸Go按鈕之後調用的函數,其中第①行代碼DictElement* pElement是__Dictionary元素(DictElement)指標,它將在迴圈遍曆中使用。DictElement類的主要函數如下:

const char* getStrKey ()。獲得元素的字串鍵。 

intptr_t getIntKey ()。獲得元素的整型鍵。 

 Ref * getObject ()。獲得元素中的值。

第②行代碼CCDICT_FOREACH(dict1, pElement)是使用CCDICT_FOREACH宏對__Dictionary容器進行遍曆的,宏的第一個參數dict1是__Dictionary 對象指標,第二個元素pElement是前面聲明的__Dictionary元素(DictElement)指標。第③行代碼int key = pElement->getIntKey()獲得元素的整型鍵。第④行代碼Sprite* sprite = (Sprite*)pElement->getObject()獲得元素中的值。

第⑤行代碼CCDICT_FOREACH(dict2, pElement) )是遍曆dict2對象。與dict1不同的是dict2使用的鍵是字串類型,通過第⑥行代碼const char *key = pElement->getStrKey()可以獲得鍵。

HelloWorldScene.cpp中的解構函式代碼如下:

HelloWorld::~HelloWorld(){this->dict1->removeAllObjects();CC_SAFE_RELEASE_NULL(this->dict1); this->dict2->removeAllObjects();CC_SAFE_RELEASE_NULL(this->dict2);}

在解構函式中要釋放一些資源,首先要移除容器中的所有元素,然後再通過CC_SAFE_RELEASE_NULL宏將容器物件先釋放。

更多內容請關注國內第一本Cocos2d-x 3.2版本圖書《Cocos2d-x實戰:C++卷》本書交流討論網站:http://www.cocoagame.net
更多精彩視頻課程請關注智捷課堂Cocos課程:http://v.51work6.com
歡迎加入Cocos2d-x技術討論群:257760386歡迎關注智捷iOS課堂公用平台



cocos2d-x的3D情境中滑鼠拾取方法

一樣想知道解答..

[解決]
使用color picking object 的方法

[思路]
在按鈕下面貼一張純色的圖 (不要隱藏它) 把z 設定低一點. 把所需點擊的東西畫到一張畫布上, 然後用glReadPixels 讀取像素點.

// Draw into the RenderTexture
[_rtbeginWithClear:0g:0b:0a:0];

// Render both sprites: first one in RED and second one in GREEN
// [_redvisit];
// [_greenvisit];
// 這裡繪製所有想擷取點擊事件的純色圖片.

glColorMask(1,1,1,1);

// Get color values of intersection area
// 讀取一個像素
ccColor4B*buffer=(ccColor4B*)malloc(sizeof(ccColor4B)*numPixels);
glReadPixels(x,y,w,h,GL_RGBA,GL_UNSIGNED_BYTE,buffer);

[_rtend];

[完整代碼]
github.com/ascetic85/objectPick.git
 
勁樂團行?

我覺得挺好的!
 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.