第四章数据结构-Array

Cocos2d-x学习笔记


Cocos2-x中的数据结构

在cocos中有很多数据结构,归纳后分为两大数据结构:列表字典

  • 列表结构包括:_Array、Vector和ValueVector
  • 字典结构包括:_Dictionary、Map

Cocos2d-x中的两大类——Ref和Value

在cocos中创造了两大类:RefValue,Cocos2d-x中除了C++以外的几乎所有类都派生自它们。

Cocos2d-x的基类——Ref

Ref在内存管理上类似于Objective-C中的跟类NSObject,都使用内存引用计数器,相关API也是类似。
Ref是大部分Cocos2d-x对象的基类,它们可以采用静态函数create函数来构造。

包装类Value

Value类被称为“包装类”,它可以将int、float、double、bool、unsigned char和char *等基本数据类型,也可以包装一些C++标准类,例如是std::string、std::vector、std::unordered_map

void HelloWorld::menuCloseCallback(Ref * pSender)
{
    Value v1;
    CCASSERT(v1.isNull(), "");

    Value v2(100);
    log("The description of the integer value: % s", v2.getDescription().c_str());
    log("v2.asByte() = % c", v2.asByte());

    Value v3(101.4f);
    log("The description of the float value:% s", v3.getDescription().c_str());

    Value v4(106.1);
    log(:The description of the double value:% s", v4.getDescription().c_str())
    log("v4.asInt() = % d", v4.asInt());

    unsigned char byte = 50;
    Value v5(byte);
    log("The description of the byte value:% s", v5.getDescription().c_str());

    Value v6(true);
    log("The description of the boolen value:% s", v6.getDescription().c_str());

    Value v7("123);
    log("The descripton of the string value:% s", v7.getDescription().c_str());
    log("v7.asInt() =  % d", v7.asInt());

}

Ref列表数据结构

列表数据结构是一种线性数据结构。列表中的元素是有序的,可以通过下表来访问,能够容纳Ref类型的列表数据结构包括_ArrayVector

_Array数据结构

_Array类是模仿Objective-C中的NSArray类而设计的,通过引用计数管理内存。_Array继承于Ref类,因此它所能容纳的是Ref及其子类所创建的对象指针

1.创建_Array对象
  • static _Array * create():创建_Array.
  • static _Array * create(Ref * object, ...):使用一系列Ref创建_Array。
  • static _Array * createWithObject(Ref * object):使用一个Ref创建_Array。
  • static _Array * createWithCapacity(unsigned int capacity):创建_Array,并设置容量。
  • static _Array * createWihtArray(_Array * other_Array):用一个已经存在的_Array创建另一个 _Array。
  • static _Array * createWithContentsOfFile(const std::string &pFileName):从属性列表文件创建_Array
2.添加元素

向_Array对象中添加元素都必须是Ref和其子类的对象指针类型。

  • void addObject(Ref * object):添加一个元素。
  • void addObjectFromArray(_Array * otherArray):把一个_Array对象中所有的元素添加到当前的_Array对象中。
  • void insertObject(Ref * object, ssize_t index):在指定位置插入元素,ssize_t是int的别称
3.移除元素
  • void removeLastObject()):移除最后一个元素。
  • void removeObject(Ref * object):移除某个元素。
  • void removeObjectAtIndex(ssize_t index):移除一个指定位置的元素。
  • void removeObjectInArray(_Array * otherArray):移除某个数组_Array对象。
  • void removeAllObject()移除所有元素。
  • void fastRemoveObeject(Ref * object):快速移除某个元素,把数组的最后一个元素(数值的最后一个元素是NULL)复制给要删除的元素,不过这会改变原有元素的顺序。
  • void fastRemoveObjectAtIndex(ssize_t index):快速移除某个指定位置的元素,于上个函数类似。
4.替换和交换元素
  • void exchangeObject(Ref * object1, Ref * object2):交换两个元素。
  • void exchangeObjectAtIndex(ssize_t index1, ssize_t index2):交换两个指定位置元素。
  • void replaceObjectAtIndex(ssize_t uIndex, Ref * object):用一个对象替换指定位置的元素。
5.其他操作函数
  • ssize_t count():返回元素个数。
  • ssize_t capacity():返回_Array的容量。
  • ssize_t indexOfObject(Ref * object):返回指定Ref对象指针的位置。
  • Ref * objectAtIndex(ssize_t index):返回指定位置的Ref对象指针。
  • Ref * lastObject():返回最后一个元素的Ref对象指正。
  • Ref * randomObject():返回随机元素。
  • bool containsObject(Ref * object):返回某个元素是否存在于_Array数据结构中。
  • bool isEqualToArray(_Array * pOtherArray):判断_Array对象是否相等。
  • void reverseObjects():翻转_Array数据结构。
6. 实例

HelloWorld.h文件

#ifndef __HELLOWORLD_SCENE_H__
#define __HELLOWORLD_SCENE_H__

#include "cocos2d.h"

#define MAX_COUNT 100

class HelloWorld : public cocos2d::Layer
{
    cocos2d::__Array * list;
public:
    ~HelloWorld();
    static cocos2d::Scene* createScene();

    virtual bool init();

    // a selector callback
    void menuCloseCallback(cocos2d::Ref* pSender);

    // implement the "static create()" method manually
    CREATE_FUNC(HelloWorld);
};

#endif // __HELLOWORLD_SCENE_H__

HelloWorld.cpp文件

#include "HelloWorldScene.h"

USING_NS_CC;

Scene* HelloWorld::createScene()
{
    // 'scene' is an autorelease object
    auto scene = Scene::create();

    // 'layer' is an autorelease object
    auto layer = HelloWorld::create();

    // add layer as a child to scene
    scene->addChild(layer);

    // return the scene
    return scene;
}

// on "init" you need to initialize your instance
bool HelloWorld::init()
{
    //////////////////////////////
    // 1. super init first
    if ( !Layer::init() )
    {
        return false;
    }

    Size visibleSize = Director::getInstance()->getVisibleSize();
    Vec2 origin = Director::getInstance()->getVisibleOrigin();

    /////////////////////////////
    //形成一个按钮
    auto goItem = MenuItemImage::create("CloseNormal.png",
    "CloseSelected.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->list = __Array::createWithCapacity(MAX_COUNT);
    this->list->retain();//由于list采用的是静态函数create创建的,当init结束的时候,list数据结构对象会自动释放,所以必须加1计数

    //循环创建精灵对象并添加到list数组中
    for (int i = 0; i < MAX_COUNT; i++)
    {
    Sprite * sprite = Sprite::create("Cherry.png");
    this->list->addObject(sprite);
    }

    return true;
}


void HelloWorld::menuCloseCallback(Ref* pSender)
{
    /*Director::getInstance()->end();

#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
    exit(0);
#endif*/
    log("list->count() = % d", this->list->count());
    Size visibleSize = Director::getInstance()->getVisibleSize();

    Ref * obj = nullptr;

    // CCARRAY_FOREACH是宏,循环遍历list数据结构中的数据
    CCARRAY_FOREACH(this->list, obj) {

    Sprite * sprite = (Sprite *)obj;

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

HelloWorld::~HelloWorld()
{
    this->list->removeAllObjects();

    // 安全释放list对象,现将list对象释放,再赋予nullptr
    CC_SAFE_RELEASE_NULL(this->list);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值