zoukankan      html  css  js  c++  java
  • Cocos2d-x中__Dictionary容器以及实例介绍

    __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字典容器中的相关函数。如图所看到的场景,点击右下角的Gobutton,在场景中加入100Ball精灵和100icon精灵。 

     

     __Dictionary字典容器实例

     

    为了学习__Dictionary类的使用,我们在程序中分别创建100Ball精灵和100icon精灵,并把它们分别加入到不同的__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_COUNTMAX_COUNT定义了一次生成的精灵数。

    第②和③行代码声明__Dictionary*的成员变量dict1dict2

    第④行代码是声明析构函数。我们须要在析构函数中释放成员变量dict1dict2

    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);
    }
     
    }

    该函数是在玩家触摸Gobutton之后调用的函数。当中第①行代码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宏将容器对象先释放。

    很多其它内容请关注最新Cocos图书《Cocos2d-x实战 C++卷》
    本书交流讨论站点:http://www.cocoagame.net
    很多其它精彩视频课程请关注智捷课堂Cocos课程:http://v.51work6.com
    欢迎增加Cocos2d-x技术讨论群:257760386


    《Cocos2d-x实战 C++卷》现已上线。各大商店均已开售:

    京东:http://item.jd.com/11584534.html

    亚马逊:http://www.amazon.cn/Cocos2d-x%E5%AE%9E%E6%88%98-C-%E5%8D%B7-%E5%85%B3%E4%B8%9C%E5%8D%87/dp/B00PTYWTLU

    当当:http://product.dangdang.com/23606265.html

    互动出版网:http://product.china-pub.com/3770734

    《Cocos2d-x实战 C++卷》源代码及样章下载地址:

    源代码下载地址:http://51work6.com/forum.php?mod=viewthread&tid=1155&extra=page%3D1 

    样章下载地址:http://51work6.com/forum.php?mod=viewthread&tid=1157&extra=page%3D1

    欢迎关注智捷iOS课堂微信公共平台


  • 相关阅读:
    6-Python爬虫-分布式爬虫/Redis
    ES 查询时 排序报错(fielddata is disabled on text fileds by default ... )解决方法
    Intellij Idea webstorm 激活
    Intellij Idea 配置jdk
    java 获取(格式化)日期格式
    js 跳转 XSS漏洞 预防
    CSS去掉背景颜色
    js对象无法当成参数传递 解决方法
    Elasticsearch java api
    java多条件查询SQL语句拼接的小技巧
  • 原文地址:https://www.cnblogs.com/yxysuanfa/p/6738065.html
Copyright © 2011-2022 走看看