Cocos2d-x之Vector<T>
| 版权声明:本文为博主原创文章,未经博主允许不得转载。
Vector<T>是Cocos2d-x 3.x中推出的列表容器,在cocos2d-x3.0之前的版本是Array,因此它所能容纳的是Ref及子类所创建的对象指针,其中T是一个模板(也就是c++中的模板),表示能够放入到容器中的类型,在Cocos2d-x 3.x中T表示Ref类,其实Vector<T>就是模仿c++中的std::vector<T>模板类而来;Vector<T>的最大优点是可以自动的增大容器的大小,这比Array更好。cocos2d::Vector是一个封装好的能动态增长顺序的访问容器,cocos2d::Vector中的元素是按顺序存取的,它的底层实现数据结构是标准模板库中的标准顺序容器std::Vector中的元素是按顺序存取的,它的底层实现数据结构是标准模板库中的标准顺序容器std.
创建Vector对象的函数:
/** Constructor. 默认的构造函数Vector()*/
Vector<T>()
: _data()
{
static_assert(std::is_convertible<T, Ref*>::value, "Invalid Type for cocos2d::Vector<T>!");
}
/** Constructor with a capacity.param capacity Capacity of the Vector.创建Vector对象,并设置容量*/
explicit Vector<T>(ssize_t capacity)
: _data()
{
static_assert(std::is_convertible<T, Ref*>::value, "Invalid Type for cocos2d::Vector<T>!");
CCLOGINFO("In the default constructor with capacity of Vector.");
reserve(capacity);
} /** Copy constructor.用一个已经存在的Vector对象来创建另一个Vector对象,其中&other是左值引用参数传递 */
Vector<T>(const Vector<T>& other)
{
static_assert(std::is_convertible<T, Ref*>::value, "Invalid Type for cocos2d::Vector<T>!");
CCLOGINFO("In the copy constructor!");
_data = other._data;
addRefForAllObjects();
}
/** Constructor with std::move semantic.用一个已经存在的Vector对象创建另一个Vector对象,其中&&other是右值引用参数传递*/
Vector<T>(Vector<T>&& other)
{
static_assert(std::is_convertible<T, Ref*>::value, "Invalid Type for cocos2d::Vector<T>!");
CCLOGINFO("In the move constructor of Vector!");
_data = std::move(other._data);
}
添加元素的函数:
在Vector对象中添加元素都必须是Ref对象的指针类型。 /** Adds a new element at the end of the Vector. 添加一个元素,T表示Ref对象指针类型*/
void pushBack(T object)
{
CCASSERT(object != nullptr, "The object should not be nullptr");
_data.push_back( object );
object->retain();
}
/** Push all elements of an existing Vector to the end of current Vector. 把一个Vector对象中所有元素添加到当前的Vector对象中*/
void pushBack(const Vector<T>& other)
{
for(const auto &obj : other) {
_data.push_back(obj);
obj->retain();
}
}
/** Insert an object at certain index. @param index The index to be inserted at.@param object The object to be inserted.在指定的位置插入元素*/
void insert(ssize_t index, T object)
{
CCASSERT(index >= && index <= size(), "Invalid index!");
CCASSERT(object != nullptr, "The object should not be nullptr");
_data.insert((std::begin(_data) + index), object);
object->retain();
}
移除元素常用的函数:
/** Removes the last element in the Vector. 移除最后一个元素*/
void popBack()
{
CCASSERT(!_data.empty(), "no objects added");
auto last = _data.back();
_data.pop_back();
last->release();
} /** Remove a certain object in Vector.param object The object to be removed.param removeAll Whether to remove all elements with the same value.If its value is 'false', it will just erase the first occurrence. 移除某个元素*/
void eraseObject(T object, bool removeAll = false)
{
CCASSERT(object != nullptr, "The object should not be nullptr"); if (removeAll)
{
for (auto iter = _data.begin(); iter != _data.end();)
{
if ((*iter) == object)
{
iter = _data.erase(iter);
object->release();
}
else
{
++iter;
}
}
}
else
{
auto iter = std::find(_data.begin(), _data.end(), object);
if (iter != _data.end())
{
_data.erase(iter);
object->release();
}
}
} /** brief Removes from the vector with an iterator.param position Iterator pointing to a single element to be removed from the Vector.return An iterator pointing to the new location of the element that followed the last element erased by the function call.This is the container end if the operation erased the last element in the sequence.指定位置移除对象,参数是迭代器,而返回值是下一个迭代器*/
iterator erase(iterator position)
{
CCASSERT(position >= _data.begin() && position < _data.end(), "Invalid position!");
(*position)->release();
return _data.erase(position);
}
/** brief Removes from the Vector with a range of elements ( [first, last) ).param first The beginning of the range.param last The end of the range, the 'last' will not be removed, it's only for indicating the end of range.return An iterator pointing to the new location of the element that followed the last element erased by the function call.This is the container end if the operation erased the last element in the sequence.指定移除对象范围(first~last),参数是迭代器,而返回值是下一个迭代器*/
iterator erase(iterator first, iterator last)
{
for (auto iter = first; iter != last; ++iter)
{
(*iter)->release();
}
return _data.erase(first, last);
}
/** brief Removes from the Vector by index.param index The index of the element to be removed from the Vector.return An iterator pointing to the successor of Vector[index].移除一个值得索引的元素,参数是int类型,而返回值下一个迭代器*/
iterator erase(ssize_t index)
{
CCASSERT(!_data.empty() && index >= && index < size(), "Invalid index!");
auto it = std::next( begin(), index );
(*it)->release();
return _data.erase(it);
}
/** brief Removes all elements from the Vector (which are destroyed), leaving the container with a size of 0.note All the elements in the Vector will be released (reference count will be decreased).移除所有元素*/
void clear()
{
for( auto it = std::begin(_data); it != std::end(_data); ++it ) {
(*it)->release();
}
_data.clear();
}
替换和交换元素的函数:
/** Swap the values object1 and object2. 交换两个元素*/
void swap(T object1, T object2)
{
ssize_t idx1 = getIndex(object1);
ssize_t idx2 = getIndex(object2); CCASSERT(idx1>= && idx2>=, "invalid object index"); std::swap( _data[idx1], _data[idx2] );
}
/** Swap two elements by indexes. 交换两个指定位置的元素*/
void swap(ssize_t index1, ssize_t index2)
{
CCASSERT(index1 >= && index1 < size() && index2 >= && index2 < size(), "Invalid indices"); std::swap( _data[index1], _data[index2] );
}
/** Replace value at index with given object. 用一个对象替代指定位置的元素*/
void replace(ssize_t index, T object)
{
CCASSERT(index >= && index < size(), "Invalid index!");
CCASSERT(object != nullptr, "The object should not be nullptr"); _data[index]->release();
_data[index] = object;
object->retain();
}
查找操作函数:
/** brief Find the object in the Vector.param object The object to find.return Returns an iterator which refers to the element that its value is equals to object.Returns Vector::end() if not found.查找Vector容器中的对象,返回值迭代器*/
const_iterator find(T object) const
{
return std::find(_data.begin(), _data.end(), object);
}
/** brief Find the object in the Vector.param object The object to find.return Returns an iterator which refers to the element that its value is equals to object.Returns Vector::end() if not found.查找Vector容器中的对象,返回值迭代器*/
iterator find(T object)
{
return std::find(_data.begin(), _data.end(), object);
}
/** Returns the element at position 'index' in the Vector. 根据索引位置返回Vector容器中的元素*/
T at(ssize_t index) const
{
CCASSERT( index >= && index < size(), "index out of range in getObjectAtIndex()");
return _data[index];
}
/** Returns the first element in the Vector. 返回第一个元素*/
T front() const
{
return _data.front();
}
/** Returns the last element of the Vector. 返回最后一个元素*/
T back() const
{
return _data.back();
}
/** Returns a random element of the Vector. 返回随机的元素*/
T getRandomObject() const
{
if (!_data.empty())
{
ssize_t randIdx = rand() % _data.size();
return *(_data.begin() + randIdx);
}
return nullptr;
}
/**Checks whether an object is in the container.param object The object to be checked.return True if the object is in the container, false if not.返回某个元素是否存在于容器中*/
bool contains(T object) const
{
return( std::find(_data.begin(), _data.end(), object) != _data.end() );
}
其他操作函数:
/** Reverses the Vector. 反转Vector容器*/
void reverse()
{
std::reverse( std::begin(_data), std::end(_data) );
}
/** Requests the container to reduce its capacity to fit its size. 减少其以适应其容量大小*/
void shrinkToFit()
{
_data.shrink_to_fit();
}
/** Requests that the vector capacity be at least enough to contain n elements.param capacity Minimum capacity requested of the Vector.*/
void reserve(ssize_t n)
{
_data.reserve(n);
}
/** brief Returns the size of the storage space currently allocated for the Vector, expressed in terms of elements.note This capacity is not necessarily equal to the Vector size.It can be equal or greater, with the extra space allowing to accommodate for growth without the need to reallocate on each insertion.return The size of the currently allocated storage capacity in the Vector, measured in terms of the number elements it can hold.返回容量的大小*/
ssize_t capacity() const
{
return _data.capacity();
}
/** brief Returns the number of elements in the Vector.note This is the number of actual objects held in the Vector, which is not necessarily equal to its storage capacity.return The number of elements in the Vector.返回元素的个数*/
ssize_t size() const
{
return _data.size();
}
/** @brief Returns whether the Vector is empty (i.e. whether its size is 0).note This function does not modify the container in any way. To clear the content of a vector, see Vector<T>::clear.判断容器是否为空*/
bool empty() const
{
return _data.empty();
}
/** Returns the maximum number of elements that the Vector can hold.容器的最大容量*/
ssize_t max_size() const
{
return _data.max_size();
}
/** Returns index of a certain object, return UINT_MAX if doesn't contain the object,通过给定的下标返回容器中对应的值 */
ssize_t getIndex(T object) const
{
auto iter = std::find(_data.begin(), _data.end(), object);
if (iter != _data.end())
return iter - _data.begin();
return -;
}
实例:
.h files #ifndef _VECTORTEST_SCENE_H_
#define _VECTORTEST_SCENE_H_
#include "cocos2d.h"
class vectorTest : public cocos2d::Layer
{
private:
public:
static cocos2d::Scene* createScene();
virtual bool init();
void testVector();
CREATE_FUNC(vectorTest);
};
#endif // _VECTORTEST_SCENE_H_ .cpp files #include "VectorTest.h"
USING_NS_CC;
Scene* vectorTest::createScene()
{
// 'scene' is an autorelease object
auto scene = Scene::create();
// 'layer' is an autorelease object
auto layer = vectorTest::create();
// add layer as a child to scene
scene->addChild(layer);
// return the scene
return scene;
}
bool vectorTest::init()
{
if (!Layer::init())
{
return false;
}
testVector();
return true;
}
void vectorTest::testVector()
{
//首先创建一个精灵
auto sp1 = Sprite::create();
sp1->setTag(1);
std::shared_ptr<Vector<Sprite*>> vec1 = std::make_shared<Vector<Sprite*>>();
vec1->pushBack(sp1); auto sp2 = Sprite::create();
sp2->setTag(2); //初始化一个大小为5的Vector容器
Vector<Sprite*> vec2(5);
vec2.insert(0, sp2);
//将vec1中的内容追加到Vec2的末尾
vec2.pushBack(*vec1); //遍历
for (auto sp : vec2)
{
log("sprite tag = %d", sp->getTag());
} //用另外的一个Vector来初始化一个Vector
Vector<Sprite*> vec3(*vec1);
//判断这两个Vec是否相等
if (vec1->equals(vec2))
{
log("pVec1 is equal to pVec2");
}
//判断是否为空
if (!vec2.empty())
{
//capacity();函数是取得对应Vector对象的热量大小
if (vec2.capacity() == vec2.size())
{
log("pVec2->capacity()==pVec2->size()");
}
else
{
vec2.shrinkToFit();
log("pVec2->capacity()==%zd; pVec2->aize()==%zd", vec2.capacity(), vec2.size());
} vec2.swap(vec2.front(), vec2.back());
if (vec3.contains(sp1))
{
log("The index of sp1 in pVec3 is %zd", vec3.getIndex(sp1));
} vec2.erase(vec2.find(sp1));
vec2.clear();
log("The size of pVac2 is %zd", vec2.size());
}
}

Cocos2d-x之Vector<T>的更多相关文章
- cocos2dx的模板容器简单使用(Vector,Map,Value)
在cocos2dxv3.0beta之前存在顺序性容器cocos2d::CCArray,和cocos2d::CCDictionary.可是在新版本号之后这两个容器都将被cocos2d::Vector&l ...
- cocos2dx 2.x实现闪电效果(贴画版)
cocos2dx 2.x实现闪电效果(非画线版) 在网上搜索到一个直接用opengl画线实现的版本,但放在游戏中效果不太搭,要求用贴图的.我这个版本用的也是画线版的算法. 闪动的时候效果还可以,每段衔 ...
- cocos2dx 3.x(实现帧动画(人物动画,跑马灯效果)的几种方法)
//创建一个跑酷的精灵 auto sprite = Sprite::create("1.png"); //设置精灵的坐标 sprite->setPosition(Ve ...
- cocos2dx A*算法
头文件和源文件拷贝到项目中就能用了! have fun 使用cocos2dx 3.2 原理都一样 淡蓝色的点是地图 深蓝色的点是障碍物 绿色的点是路径 暗绿色的点是搜寻过的点 红色的点是按路径行走的点 ...
- cocos2dx A* + tiledMap
本文转自:http://blog.csdn.net/w18767104183/article/category/1757765 前面一章讲了cocos2dx 中使用A星算法 这章中讲 A*结合tile ...
- 1.cocos2dx存储卡的游戏代码、而游戏移植到“华为荣耀”电话、问题的总结移植
1记忆卡片游戏代码 CardItem.h #pragmaonce #ifndef__CardItem_H__ #define__CardItem_H__ #include"cocos2 ...
- 笔记:利用 Cocos2dx 3.2 与 Box2D制作一个跑酷游戏(上)
最近写lua写得没有力气了,所以想让脑袋放松一下,刚好看到有人在用swift做游戏: Swift游戏实战-跑酷熊猫 于是脑子一短路,就想到了利用这些素材来做一个游戏. 本来不想记笔记的,但是由于选择物 ...
- cocos2dx帧动画
//帧动画的创建 //方式一,通过多张图片来创建 auto sprite1 = Sprite::create("grossini_dance_05.png"); sprite1-& ...
- cocos2d-x CSV文件读取 (Excel生成csv文件)
实现类 CCSVParse.h #ifndef __C_CSV_PARSE__ #define __C_CSV_PARSE__ #include "cocos2d.h" #incl ...
- [cocos2dx utils] cocos2dx读取,解析csv文件
在我们的游戏中,经常需要将策划的数值配置成csv文件,所以解析csv文件就是一个很common的logic, 例如如下csv文件: 下面是一个基于cocos2dx 2.2.4的实现类: #ifndef ...
随机推荐
- luoguP1505 [国家集训队]旅游(真的毒瘤)
luogu P1505 [国家集训队]旅游 题目 #include<iostream> #include<cstdio> #include<cstdlib> #in ...
- Day7-----Python的序列类(有子类:元组类,列表类)
序列类型 1.基本介绍: 序列类型是一种基类类型 ,既然被称为那就肯定是有道理的,关于序列 它有 正向 和 反向 两种序号,正向序号从零开始,反向序号从负一开始 a = '例如这个字符串' ...
- Python自学第一天
Python #-*- coding:utf8 -*-(Python文件开头添加)用来解决中文编码问题 注:Python3以上文件不用加 一.变量:变量有数字.字母和下划线组成 1.不能以数字开头 2 ...
- go 学习之io/ioutil包
// Discard 是一个 io.Writer 接口,调用它的 Write 方法将不做任何事情// 并且始终成功返回.var Discard io.Writer = devNull(0) // Re ...
- XSS——跨站脚本攻击
跨站点脚本攻击:通过对网页注入恶意脚本,成功地被浏览器执行,来达到攻击的目的. 一.XSS攻击类型与原理1. 反射型XSS攻击非持久性攻击,黑客使用社交性的交互技巧诱导用户点击访问目标服务器的链接,但 ...
- struts2 基础学习
Struts 2是在WebWork2基础发展而来的. 注意:struts 2和struts 1在代码风格上几乎不一样. Struts 2 相比Struts 1的优点: 1.在软件设计上Struts ...
- 如何判断元素是否在可视区域内--getBoundingClientRect
介绍 Element.getBoundingClientRect()方法返回元素的大小及其相对于视口的位置. 根据MDN文档 getBoundingClientRect 方法返回的是一个DOMRect ...
- Java JNA (二)—— dll回调函数实现
java调用dll文件需要使用回调函数作为公开函数的参数时,用以下方法实现: 首先,看c++中定义的dll公开函数: typedef void (*ccback)(char *name ,int le ...
- linux性能分析工具Swap
- 环境管理 pipenv 的 使用
安装 pip3 install pipenv 配置 配置 环境变量 WORKON_HOME , 表示 生成的虚拟环境 文件 的 存放位置 创建虚拟环境 方式一 pipenv --python 3.7 ...