zoukankan      html  css  js  c++  java
  • 关于Cocos2d-x中数组的使用

    1.定义和背景

    cocos2d::Vector<T> 是一个封装了动态大小的数组的顺序型容器。

    它的元素是连续存储的,cocos2d::Vector<T> 的存储是自动处理的。其内部的数据结构实现实际上是STL标准的顺序型容器 std::vector。

    在 Cocos2d-x v3.0 beta 之前,存在另一个顺序性容器 cocos2d::CCArray,这将会被弃用。

    官方很细致地设计了 cocos2d::Vector<T> 容器作为 cocos2d::CCArray 的替代品,所以我们要使用 cocos2d::Vector<T> 代替 cocos2d::CCArray。这种数组的插入数据的方式和删除数据的方法有很多,而且也很灵活,既可以当表,也可以当栈

    2.数据类型

    T - 元素类型.
    -T 必须是一个指向 cocos2d::Object 子类对象的指针。不能是其他数据类型或者原生类型,因为Cocos2d-x 的内存管理模型已经集成到 cocos2d::Vector<T> 中(从 v3.0 beta 开始)。

    3.创建和释放

    _data 的内存管理是由编译器自动处理的。如果你在栈上声明了一个 cocos2d::Vector<T> 对象,那就不需要关心内存释放问题。

    如果你调用了 new 操作符来分配一块 cocos2d::Vector<T> 的动态内存,那就需要在使用完后调用 delete 操作符来释放内存。这同样适用于 new[] 和 delete[]。

    注意:在新 C++ 中,它倾向于本地存储对象而不是堆存储对象。所以,请不要调用 new 操作符来分配 cocos2d::Vector<T> 的堆对象,而是使用栈对象来代替它。
     
     
     

    4.具体用法

    //用一个容量初始化一个 vector 

    Vector<Sprite*>  vec1(5); 

    //定义一个数组要在HelloWorld类的属性中定义,语法是Vector<某个对象的类名*> 数组名;

    Vector<GameController*> gcs;

    //在一个确定的位置插入一个确定的对象(这里是在位置0插入一个Sprite类型的sp1变量指针)

    vec1.insert(0, sp1); 

    //我们也可以加入一整个 vector 

    vec1.pushBack(*vec0); 

    //从 vector 中移除元素 

    1.vec1.erase(vec1.find(sp0));  //sp0是一个对象实例,可以是节点,精灵或者其他一些数据类型

    2.pVec1->erase(1); //下标为1的变量

    3.pVec1->eraseObject(sp0,true);  //sp0是一个对象实例,可以是节点,精灵或者其他一些数据类型,这个方法在移除一个元素后,其他元素的位置就会发生变化,比如

       auto it = lifes.begin();

    (*it)->removeFromParent();

    lifes.eraseObject((*it), true);

    移除后,原来在1号位的变量就变成0号位了,也就是lifes.begin();用这个方法可以做一个血量减少,爱心从右往左减少的效果

    4.pVec1->popBack(); 

    5.vec1.clear(); //移除所有元素 

    //其他用法

    //如果两个vector 相同的话返回真 

    if (vec0->equals(vec2)) { 

        log("pVec0 is equal to pVec2"); 

    //判断vector是否为空 

    if (!vec1.empty()) { 

        //获取 vector 的 capacity 和 size,要注意的是 capacity 并不一定等于 size 

        if (vec1.capacity() == vec1.size()) { 

            log("pVec1->capacity()==pVec1->size()"); 

        }else{ 

            vec1.shrinkToFit();   //收缩 vector 以便内存对应上元素的数量 

            log("pVec1->capacity()==%zd; pVec1->size()==%zd",vec1.capacity(),vec1.size()); 

        } 

        //pVec1->swap(0, 1);  //通过索引交换 vector 中的两个元素 

        vec1.swap(vec1.front(), vec1.back());  //通过值交换 vector 中的两个元素  

            if (vec2.contains(sp0)) {  //返回一个布尔值,用于指示该对象是否存在于 vector 中 

            log("The index of sp0 in pVec2 is %zd",vec2.getIndex(sp0)); 

        } 

    }

    5.遍历

    如果要遍历某个数组,要用到数组对象的begin()方法和end()方法,再定义一个指向各个具体对象的指针,这个指针值加1的时候,所指向的实例对象会后移一个,初始时让它指向第一个实例

    for (auto it = gcs.begin(); it != gcs.end(); it++) {
      (*it)->onUpdate();

    }

    注意:如果我们在插入数据的时候是每个都在0的位置插入的话

    pic.insert(0, pic1);

    pic.insert(0, pic2);

    pic.insert(0, pic3);

    pic.insert(0, pic4);

    那么各个变量在数组中的顺序是

    pic4--pic3---pic2---pic1

    所以遍历起来的话是pic4为pic.begin(),产生了一个倒序的效果,并不是因为数组是什么先进后出,那是错误的思维,这个数组的遍历还是老老实实按照从左往右从0下标位开始的顺序的。

    6.详解(*it)=sprite

    如果定义了auto sprite=Sprite::create();之类的精灵节点,那么在

    for (auto it = gcs.begin(); it != gcs.end(); it++) {
      (*it)->onUpdate();

    }

    中,(*it)=sprite,而不是it=sprite,所以it是一个指向精灵节点指针的指针

    1.     //从 vector 中移除元素 
    2.     vec1.erase(vec1.find(sp0)); 
    3.     //pVec1->erase(1); 
    4.     //pVec1->eraseObject(sp0,true); 
    5.     //pVec1->popBack(); 
    6.   
    7.     vec1.clear(); //移除所有元素 
  • 相关阅读:
    [JLOI2015]有意义的字符串
    二阶常系数线性齐次递推式的特征方程
    CH1812 生日礼物
    CH1809 匹配统计
    CH1808 Milking Grid
    BZOJ4025 二分图
    BZOJ3514 GERALD07加强版
    NOI2014 魔法森林
    WC2006 水管局长数据加强版
    LG3690 【模板】Link Cut Tree 和 SDOI2008 洞穴勘测
  • 原文地址:https://www.cnblogs.com/HangZhe/p/5701860.html
Copyright © 2011-2022 走看看