写任何的项目都少不了用容器存放东西吧,所以容器至关重要,3.0提供了新的容器,这些容器很接近c++中STL模板中的容器,底层的数据结构应该是相同的,不同的是分装了一下,提供了一些常用的API,如果不知道c++容器的童鞋还请看下这篇文章以后的四篇文章,顺序容器vector。容器的操作无非就是增删改查,下面看看API如何用吧。

bool HelloWorld::init()
{
    if ( !Layer::init() )
    {
        return false;
    }

	auto size = Director::getInstance()->getWinSize();

	auto sprite1 = Sprite::create("sprite.png");
	sprite1->setPosition(CCPoint(size.width/2,size.height/2));
	auto sprite2 = Sprite::create("sprite.png");
	sprite2->setPosition(CCPoint(size.width/3,size.height/3));

	//新建一个vector对象,尖括号代表的就是泛型,是c++中的模板,里边放你希望存放的数据类型,官方建议新建的时候使用
	//栈分配,而不是堆分配,如果使用的是堆分配,使用完记住delete,不能release,因为不是Ref的子类
	Vector<Sprite *> vector;
	/*
	以下分别说明对容器的增删改查
	*/

	//添加对象
	vector.pushBack(sprite1);
	vector.pushBack(sprite2);

	//遍历容器中的元素,以下的for循环是c++11新增加的特性,是不是很类似java的for啊
	//这个for循环的前边写容器中对象的类型,这个让它自动判断就好了,后边写上你要遍历的容器,这样就会自动从容器中
	//取出对象,然后赋给sprite了,是不是超级的方便啊
	for(auto sprite : vector)
	{
		this->addChild(sprite);
	}

	//插入元素,第一个参数是位置,第二个是要插入的对象
	vector.insert(0,sprite1);

	//查看是否包含某个元素
	bool b = vector.contains(sprite1);
	CCLOG("contains sprite1 is = %d",b);
	//获取元素在容器中的下标
	CCLOG("sprite1' index is = %d",vector.find(sprite1)-vector.begin());

	//size函数是获得vector的大小
	CCLOG("size = %d",vector.size());

	//删除元素
	vector.eraseObject(sprite1);
	//以下的erase函数有很多重载的版本,可以传入一个索引,因为vector底层是使用顺序表实现的,这点就不难理解了
	//也可以传入一个迭代器,还可以是一个范围,具体用的时候查就可以了
	//vector.erase();
	//清除所有的元素
	vector.clear();
	CCLOG("size = %d",vector.size());

    return true;
}

3.0容器Vector

以上是对vector的使用,vector底层的实现是顺序表,所以就有了下标,再来看看map,map是键值对,底层实现是二叉树。

auto size = Director::getInstance()->getWinSize();

	auto sprite1 = Sprite::create("sprite.png");
	sprite1->setPosition(CCPoint(size.width/2,size.height/2));
	auto sprite2 = Sprite::create("sprite.png");
	sprite2->setPosition(CCPoint(size.width/3,size.height/3));

	//创建容器
	Map<int,Sprite *> map;
	/*
	以下是增删改查的操作
	*/

	//添加元素,第一个是键,第二个是值
	map.insert(0,sprite1);
	map.insert(1,sprite2);
	//以下的添加无效,因为map是不允许键重复的
	//map.insert(1,sprite1);
	//值是可以重复的
	//map.insert(2,sprite1);

	CCLOG("size = %d",map.size());

	//采用以下的方法遍历容器,先获得键的集合,这个集合其实是vector,里边放的是键
	auto key = map.keys();
	for(auto i : key)
	{
		//通过函数at来获得对应的值,参数是键
		this->addChild(map.at(i));
	}

	//删除,里边传入的是键
	map.erase(0);
	CCLOG("size = %d",map.size());

用过c++中的容器的人都知道,这俩个容器和c++中的基本没有什么区别,不过是封装了一下,将存放在容器中的元素retain了一下,丰富了一下常用的API,vector取代了CCArray,map取代了CCDirectory。

面向对象的思想是一切皆对象,当我们在使用基本数据类型int、float等等的时候有时候需要把他们当做对象,例如在向容器中存放东西的时候就不能存放这些基本的数据类型,所以cocos2dx提供了value,这个东西就是将基本数据类型当做对象来用的,初始化的时候传入基本的数据类型就可以了,原来2.x版本的CCInteger这些东西就不要用了,用value吧。

bool HelloWorld::init()
{
    if ( !Layer::init() )
    {
        return false;
    }
    
	//创建栈上的对象value,在构造函数中传入你要初始化的值,传入的值的类型可以是
	/*
    BYTE,
    INTEGER,
    FLOAT,
    DOUBLE,
    BOOLEAN,
    STRING,
    VECTOR,
    MAP,
    INT_KEY_MAP
	*/
	Value val1(2.3);
	Value val2(false);

	//log的用法和CCLOG的相同
	log("val1' description is %s",val1.getDescription().c_str());
	//getDescription是获得描述信息,返回值是string
	log("val2' description is %s",val2.getDescription().c_str());
    
	Value val3("3");
	//as后边跟相应的数据类型可以转为相应的数据类型
	log("val3 = %d",val3.asInt());
    
    return true;
}

3.0容器