cocos2dx 文件操作

2015年01月13日 10:45 0 点赞 0 评论 更新于 2025-11-21 14:13

在游戏开发中,通常不需要复杂的文件读写操作,但一些基本的 Cocos2d-x 文件操作仍有必要了解。本文将详细介绍 Cocos2d-x 中 FileUtils 类的文件操作功能。

FileUtils 类概述

FileUtils 类的主要功能是设置加载和保存文件的所在路径。该类是一个单例类,可以通过 getInstance() 方法获取单例对象。以下是相关方法:

// 获得单例对象
static FileUtils* getInstance();
// 释放单例对象资源
static void destroyInstance();
// 清理文件查找缓存
virtual void purgeCachedEntries();

文件操作功能详解

1. 文件读取

FileUtils 类提供了多种读取文件的方法:

// 读取文件内容,返回 Data 类型的数据
virtual Data getDataFromFile(const std::string& filename);
// 读取文件内容,返回字符串类型的数据
virtual std::string getStringFromFile(const std::string& filename);
// 读取 zip 中某资源文件的内容
// [in] zip 文件路径 , 相对 zip 的文件路径
// [out] size. 若文件读取成功,这个值为数据大小,否则为零
// 如果成功,则返回数据指针,否则返回 nullptr
virtual unsigned char* getFileDataFromZip(const std::string& zipFilePath, const std::string& filename, ssize_t *size);

2. 文件查找

2.1 设置文件查找路径

  • 文件字典(Dictionary):相当于给文件起别名。
  • 搜索路径(SearchPaths):可以是绝对路径或相对路径。
  • 子区分路径(SearchResolutionsOrder):用于进一步细分查找路径。

相关方法如下:

// 设置文件词典,相当于给文件起别名,如 map["sprite.png"] = "sp.png"
virtual void setFilenameLookupDictionary(const ValueMap& filenameLookupDict);
// 从 plist 文件加载文件词典
virtual void loadFilenameLookupDictionaryFromFile(const std::string &filename);
// 设置搜索路径(可以是绝对路径、相对路径),清除之前 add 的全部搜索路径(除了默认路径 "Resources")
virtual void setSearchPaths(const std::vector<std::string>& searchPaths);
// 添加搜索路径
void addSearchPath(const std::string & path, const bool front=false);
// 获取搜索路径
virtual const std::vector<std::string>& getSearchPaths() const;
// 设置子区分路径,清除之前 add 的全部子区分路径
virtual void setSearchResolutionsOrder(const std::vector<std::string>& searchResolutionsOrder);
// 添加子区分路径
virtual void addSearchResolutionsOrder(const std::string &order,const bool front=false);
// 获取子区分路径
virtual const std::vector<std::string>& getSearchResolutionsOrder();

2.2 查找文件

  • fullPathForFilename:获取文件的完整路径(绝对路径),注意查找的是文件,而不是文件夹。
  • fullPathFromRelativeFile:路径拼接。
// 获取文件的完整路径(绝对路径)
virtual std::string fullPathForFilename(const std::string &filename);
// 路径拼接,relativeFile.substr(0, relativeFile.rfind('/')+1) + getNewFilename(filename)
virtual std::string fullPathFromRelativeFile(const std::string &filename, const std::string &relativeFile);

fullPathFromRelativeFile 的用法说明:

  1. 保留 relativeFile 最后一个 '/' 前面的路径(如:"xyz/123")。
  2. 通过文件字典替换 filename(如:"sprite.png" -> "sp.png")。
  3. 路径拼接:"xyz/sp.png"
  4. relativeFile = "xyz/123/",则路径拼接为:"xyz/123/sp.png"

2.3 举例

// 设置文件字典
std::map<std::string, std::string> map;
map["sprite.png"] = "bg.png";
setFilenameLookupDictionary(map);
// 设置搜索路径
std::vector<std::string> searchPaths = {"C:/Res/xyz", "xyz"};
setSearchPaths(searchPaths);
// 设置子区分路径
std::vector<std::string> resolutionsOrder = {"1", "2"};
setSearchResolutionsOrder(resolutionsOrder);
// 获取完整路径
std::string fullPath = fullPathForFilename("sprite.png");

查找过程如下:

  1. 先根据字典替换别名 "sprite.png" --> "bg.png"
  2. 然后查找 "bg.png"(若无字典,直接查找 "sprite.png")。
  3. 按以下顺序查找,并返回 "sprite.png" 的完整路径(如 "C:/Res/xyz/bg.png"):
    • C:/Res/xyz/1/bg.png
    • C:/Res/xyz/2/bg.png
    • C:/Res/xyz/bg.png
    • C:/projects/MyGame/Resources/xyz/1/bg.png
    • C:/projects/MyGame/Resources/xyz/2/bg.png
    • C:/projects/MyGame/Resources/xyz/bg.png
    • C:/projects/MyGame/Resources/1/bg.png
    • C:/projects/MyGame/Resources/2/bg.png
    • C:/projects/MyGame/Resources/bg.png
  4. 若未找到,返回 "sprite.png"

注意:若找不到 "bg.png",即使 "C:/Res/xyz/" 路径下存在 "sprite.png",也显示找不到。

3. 文件判断

// 检查文件是否存在(相对路径、绝对路径都可以)
virtual bool isFileExist(const std::string& filename) const;
// 检查路径是不是绝对路径,在 Android 平台上,若 path 是相对于 "assets/",该方法会把它当成绝对路径 true
virtual bool isAbsolutePath(const std::string& path) const;
// 设置图片加载失败时,是否弹出消息框
virtual void setPopupNotify(bool notify);
virtual bool isPopupNotify();

4. 文件写入

4.1 获取写入路径

写入路径一般无法修改,不同平台的文件写入路径不同:

// 获取写入路径
virtual std::string getWritablePath() const = 0;
  • Win32:在 exe 文件所在的目录(如 "proj.win32/Debug.win32/")。
  • Android"/data/data" 目录。
  • iOS"document folder" 目录。

4.2 写入文件的方法

可以通过以下两个类来保存游戏的数据:

  • UserDefault:用于保存游戏中的用户数据。
  • RenderTexture:用于保存游戏中创建的图片数据。

具体操作,请学习 UserDefaultRenderTexture 两个类。

5. 文件查找的应用(精灵的创建)

精灵的创建需要一张图片资源,创建过程中会调用 fullPathForFilename("sprite.png") 来查找图片所在路径,然后根据图片创建精灵。

如果不设置文件查找的路径,Win32 项目默认会在 "Resources" 中查找图片,而 Android 项目默认会在 "assets" 中查找资源图片。

以下是通过前面例子的分析:

// 设置文件字典
std::map<std::string, std::string> map;
map["sprite.png"] = "bg.png";
setFilenameLookupDictionary(map);
// 设置搜索路径
std::vector<std::string> searchPaths = {"C:/Res/xyz", "xyz"};
setSearchPaths(searchPaths);
// 设置子区分路径
std::vector<std::string> resolutionsOrder = {"1", "2"};
setSearchResolutionsOrder(resolutionsOrder);
// 创建精灵
Sprite* sp = Sprite::create("sprite.png");

查找过程如下:

  1. 调用 fullPathForFilename("sprite.png"),查找图片所在路径。
  2. 先根据字典替换别名 "sprite.png" --> "bg.png"
  3. 然后查找 "bg.png"(若无字典,直接查找 "sprite.png")。
  4. 按以下顺序查找,并返回 "sprite.png" 的完整路径(如 "C:/Res/xyz/bg.png"):
    • C:/Res/xyz/1/bg.png
    • C:/Res/xyz/2/bg.png
    • C:/Res/xyz/bg.png
    • C:/projects/MyGame/Resources/xyz/1/bg.png
    • C:/projects/MyGame/Resources/xyz/2/bg.png
    • C:/projects/MyGame/Resources/xyz/bg.png
    • C:/projects/MyGame/Resources/1/bg.png
    • C:/projects/MyGame/Resources/2/bg.png
    • C:/projects/MyGame/Resources/bg.png
  5. 若未找到 "bg.png",继续查找 "sprite.png"
  6. 若依旧未找到 "sprite.png",则报错。
  7. 若找到图片所在路径,则用该图片创建精灵。

注意:如果 "C:/Res/xyz/" 路径同时存在 "bg.png""sprite.png",那么创建的精灵所使用的资源图片为 "bg.png",而不是 "sprite.png"

作者信息

feifeila

feifeila

共发布了 3994 篇文章