Node类是Cocos2dx的基类,像游戏中的 场景类、精灵类、文本类、菜单类、层类 等都是继承自Node。
Node类的定义文件目录:Cocos2dx根目录\cocos2d\cocos\2d\CCNode.cpp
Node类的文件声明目录:Cocos2dx根目录\cocos2d\cocos\2d\CCNode.h
Vector<Node *> _children; ///< 存放子元素的数组
int _tag; //元素标识,使用一个 int 来标识这个Node
std::string _name; //元素名称,使用一个 string 来标识这个Node
size_t _hashOfName; //_name的哈希值,用于提升getChildByName的查找速度
Size _contentSize; //元素的大小
Vec2 _position; //元素的位置
float _positionZ; // OpenGL渲染该元素的先后顺序
Vec2 _anchorPoint; //元素的锚点
float _rotationX; ///< 沿x轴旋转
float _rotationY; ///< 沿y轴旋转
// 旋转Z被分解为两部分来模拟动画的倾斜
float _rotationZ_X; ///< x部分
float _rotationZ_Y; ///< y部分
//缩放
float _scaleX; ///< scaling factor on x-axis
float _scaleY; ///< scaling factor on y-axis
float _scaleZ; ///< scaling factor on z-axis
bool _visible; //元素是否被显示
Cocos2dx 对c++的内存机制进行了封装,不使用 new 关键字来创建对象,而是使用 Node::create() 方法。
auto node = Node:create();//创建Node对象
就简单写几个,基本上所有属性都能够通过方法去设置,更多的就看文档或者直接看源码。
node->setTag();
node->setName();
node->setPosition();
该宏用来为一个类似CCLayer类的特定的类增加一个create函数。
那create函数里做了什么呢?
它执行了类的构造函数,执行了init()初始化函数。
最后又设置创建出的对象为自动释放内存。
这样其他人在使用这个类的时候,只要是用create()函数创建出来的对象就不用费心去管理释放内存了,它封装了c++的内存管理机制。
该宏所在的文件路径:
项目根目录\cocos2d\cocos\platform\CCPlatformMacros.h
该宏的代码:
/** @def CREATE_FUNC(__TYPE__)
* Define a create function for a specific type, such as Layer.
*
* @param __TYPE__ class type to add create(), such as Layer.
*/
#define CREATE_FUNC(__TYPE__) \
static __TYPE__* create() \
{ \
__TYPE__ *pRet = new(std::nothrow) __TYPE__(); \
if (pRet && pRet->init()) \
{ \
pRet->autorelease(); \
return pRet; \
} \
else \
{ \
delete pRet; \
pRet = nullptr; \
return nullptr; \
} \
}
比如我们创建一个场景类时,我们在声明的时候就需要用到这个宏定义来为类添加一个create方法。
FileUtils 是cocos2dx的一个用来处理文件操作的一个工具类,提供了整个引擎资源文件的默认搜索路径。
该类的源代码文件目录:
//声明文件
E:\DevelopmentTools\cocos2d-x-4.0\cocos\platform\CCFileUtils.h
//定义文件
E:\DevelopmentTools\cocos2d-x-4.0\cocos\platform\win32\CCFileUtils-win32.cpp
该类和导演类一样,采用单例设计模式。
获取FileUtils实例方法的声明:
static FileUtils* getInstance();
获取FileUtils实例:
auto fileUtils = FileUtils::getInstance();
ValueMap FileUtils::getValueMapFromFile(const std::string& filename) const
{
const std::string fullPath = fullPathForFilename(filename);
DictMaker tMaker;
return tMaker.dictionaryWithContentsOfFile(fullPath);
}
ValueMap FileUtils::getValueMapFromData(const char* filedata, int filesize) const
{
DictMaker tMaker;
return tMaker.dictionaryWithDataOfFile(filedata, filesize);
}
每一种cocos数据类型都有相对应的读取方法(从文件、数据或者压缩包),例如Vector、String等,这里不写太多,可以自己翻源码或者文档。
bool FileUtils::writeValueMapToFile(const ValueMap& dict, const std::string& fullPath) const
{
tinyxml2::XMLDocument *doc = new (std::nothrow)tinyxml2::XMLDocument();
if (nullptr == doc)
return false;
tinyxml2::XMLDeclaration *declaration = doc->NewDeclaration("xml version=\"1.0\" encoding=\"UTF-8\"");
if (nullptr == declaration)
{
delete doc;
return false;
}
doc->LinkEndChild(declaration);
tinyxml2::XMLElement *docType = doc->NewElement("!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\"");
doc->LinkEndChild(docType);
tinyxml2::XMLElement *rootEle = doc->NewElement("plist");
if (nullptr == rootEle)
{
delete doc;
return false;
}
rootEle->SetAttribute("version", "1.0");
doc->LinkEndChild(rootEle);
tinyxml2::XMLElement *innerDict = generateElementForDict(dict, doc);
if (nullptr == innerDict)
{
delete doc;
return false;
}
rootEle->LinkEndChild(innerDict);
bool ret = tinyxml2::XML_SUCCESS == doc->SaveFile(getSuitableFOpen(fullPath).c_str());
delete doc;
return ret;
}
同读取一样,每个cocos数据类型都有对应的写入操作,这里就放一个,其他的翻阅源码或者文档。
void FileUtils::setFilenameLookupDictionary(const ValueMap& filenameLookupDict)
{
DECLARE_GUARD;
_fullPathCache.clear();
_fullPathCacheDir.clear();
_filenameLookupDict = filenameLookupDict;
}
void FileUtils::loadFilenameLookupDictionaryFromFile(const std::string &filename)
{
const std::string fullPath = fullPathForFilename(filename);
if (!fullPath.empty())
{
ValueMap dict = FileUtils::getInstance()->getValueMapFromFile(fullPath);
if (!dict.empty())
{
ValueMap& metadata = dict["metadata"].asValueMap();
int version = metadata["version"].asInt();
if (version != 1)
{
CCLOG("cocos2d: ERROR: Invalid filenameLookup dictionary version: %d. Filename: %s", version, filename.c_str());
return;
}
setFilenameLookupDictionary( dict["filenames"].asValueMap());
}
}
}
void FileUtils::setSearchPaths(const std::vector<std::string>& searchPaths)
{
DECLARE_GUARD;
bool existDefaultRootPath = false;
_originalSearchPaths = searchPaths;
_fullPathCache.clear();
_fullPathCacheDir.clear();
_searchPathArray.clear();
for (const auto& path : _originalSearchPaths)
{
std::string prefix;
std::string fullPath;
if (!isAbsolutePath(path))
{
// Not an absolute path
prefix = _defaultResRootPath;
}
fullPath = prefix + path;
if (!path.empty() && path[path.length()-1] != '/')
{
fullPath += "/";
}
if (!existDefaultRootPath && path == _defaultResRootPath)
{
existDefaultRootPath = true;
}
_searchPathArray.push_back(fullPath);
}
if (!existDefaultRootPath)
{
//CCLOG("Default root path doesn't exist, adding it.");
_searchPathArray.push_back(_defaultResRootPath);
}
}
void FileUtils::addSearchPath(const std::string &searchpath,const bool front)
{
DECLARE_GUARD;
std::string prefix;
if (!isAbsolutePath(searchpath))
prefix = _defaultResRootPath;
std::string path = prefix + searchpath;
if (!path.empty() && path[path.length()-1] != '/')
{
path += "/";
}
if (front) {
_originalSearchPaths.insert(_originalSearchPaths.begin(), searchpath);
_searchPathArray.insert(_searchPathArray.begin(), path);
} else {
_originalSearchPaths.push_back(searchpath);
_searchPathArray.push_back(path);
}
}