Cocos2d-x学习笔记
Cocos2-x中的数据结构
在cocos中有很多数据结构,归纳后分为两大数据结构:列表和字典
- 列表结构包括:_Array、Vector和ValueVector
- 字典结构包括:_Dictionary、Map
Cocos2d-x中的两大类——Ref和Value
在cocos中创造了两大类:Ref和Value,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类型的列表数据结构包括_Array和Vector。
_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);
}