zpack使用
来源:互联网 发布:怎么在淘宝上传图片 编辑:程序博客网 时间:2024/06/03 05:30
一、相关说明
在使用cocos2dx开发时,资源需要打包,这里我们使用一个开源项目:zpack项目。
zpack可以把所有资源打成一个包,然后在运行时解析包内的资源即可。
二、资源打包
- 1.下载zpack项目,用VS打开工程,然后编译项目生成zpEditorD.exe程序。
- 2.打开zpEditorD创建一个项目,这里我取名叫做data.zpk。
- 3.然后把Cocos2dx工程下Resources里的资源放到新建的文件夹data目录下。
- 4.再打开zpEditorD工具栏Edit中的Add Folder添加data文件夹即可。
三、添加库文件
1.把zpack下相关文件资源拷贝到项目的cocos2d\external\下,并且创建了PackManager管理类文件。
2.在cocos2d\cocos下的Android.mk文件里的LOCAL_SRC_FILES下添加zpack路径,如下:
../external/zpack/PackManager.cpp \../external/zpack/zpack.cpp \../external/zpack/zpCompressedFile.cpp \../external/zpack/zpFile.cpp \../external/zpack/zpPackage.cpp \../external/zpack/zpWriteFile.cpp \../external/zpack/WriteCompressFile.cpp \
上面是为了Android工程编译时找到库文件,同时在proj.android\jni下的Android.mk导入目录,如:
$(call import-add-path,$(LOCAL_PATH)/../../cocos2d/external/zpack)LOCAL_C_INCLUDES := $(LOCAL_PATH)/../../Classes \ $(LOCAL_PATH)/../../cocos2d/external \ $(LOCAL_PATH)/../../cocos2d/external/zpack \
3.然后打开VS工程,在libcocos2d中的external文件夹,添加筛选器zpack,在导入zpack中的所有文件。
四、zpack使用
1.问题处理:
目前zpack文件只能在windows下使用,还需要把一些Android下没有的函数做一些更改,才能在Android下使用。比如_fseeki64函数更改为fseek函数,
void File::seekInPackage(){#if defined(WIN32) && defined(_WINDOWS) _fseeki64(m_package->m_stream, m_offset + m_readPos, SEEK_SET); m_package->m_lastSeekFile = this;#else fseek(m_package->m_stream, m_offset + m_readPos, SEEK_SET); m_package->m_lastSeekFile = this;#endif}
除此之外,注意zpack定义了宽字符和普通字符,这里我们使用普通字符,即屏蔽掉宽字符,在zpack.h中关闭ZP_USE_WCHAR就行了。
#if defined (_MSC_VER) && defined (UNICODE)// #define ZP_USE_WCHAR#endif
2.PackManager类编写
PackManager类是我们用来管理zpack的类,
PackManager.h
#ifndef __CPACKMANAGER_H__#define __CPACKMANAGER_H__#include <cocos2d.h>#include "iostream"#include "zpPackage.h"#include "zpack.h"#include "zpFile.h"using namespace std;USING_NS_CC;namespace zp{ class IPackage;}class CPackManager{public: CPackManager(); ~CPackManager(); bool Open(const std::string& filename, const zp::String& path, bool readonly = false); unsigned char* getFileData(const std::string& Path, ssize_t &size);private: void clear(); void copy();private: zp::IPackage* m_pack; std::string m_zpkFileName;};CPackManager& PackManager();#endif
PackManager.cpp文件如下:
#include "PackManager.h"#include <fstream>CPackManager& PackManager(){ static CPackManager s; return s;}CPackManager::CPackManager() :m_pack(nullptr), m_zpkFileName(""){}CPackManager::~CPackManager(){}void CPackManager::clear(){ if (m_pack != NULL) { zp::close(m_pack); m_pack = NULL; }}bool CPackManager::Open(const std::string& filename ,const zp::String& path, bool readonly){ clear(); m_zpkFileName = filename; copy(); std::string writePath = cocos2d::FileUtils::getInstance()->getWritablePath() ; writePath += m_zpkFileName; // 这里很奇怪,在Android下就可以 string 直接转化为 wstring,难道是linux的原因 // 其实在这里可以关闭到宽字符,避免麻烦#if CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID const zp::String newpath(writePath);#else zp::String newpath = path;#endif m_pack = zp::open(newpath.c_str(), readonly ? zp::OPEN_READONLY : 0); if (m_pack == NULL) { return false; } return true;}void CPackManager::copy(){ ssize_t len = 0; std::string filepath = cocos2d::FileUtils::getInstance()->fullPathForFilename(m_zpkFileName); unsigned char * data = cocos2d::FileUtils::getInstance()->getFileData(filepath, "r+b", &len); std::string writePath = cocos2d::FileUtils::getInstance()->getWritablePath(); writePath += m_zpkFileName; FILE* fp = fopen(writePath.c_str(), "w+"); if (fp == nullptr) { return; } fwrite(data, sizeof(unsigned char), len, fp); fclose(fp); if (len > 0 && data) { delete[] data; data = nullptr; }}/* * getFileData函数需要在 CCFileUtilsAndroid类中使用 */unsigned char* CPackManager::getFileData(const std::string& Path, ssize_t &size){ std::stringstream ss; ss << "data/"; ss << Path; zp::IReadFile* file = nullptr;#if CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID file = m_pack->openFile(ss.str().c_str());#endif if (file == NULL) { return nullptr; } unsigned char* buffer = new unsigned char[file->size() + 1]; size = file->read((zp::u8*)buffer, file->size()); buffer[file->size()] = '\0'; return buffer;}
3.修改CCFileUtilsAndroid类
在Android平台下,使用资源如添加精灵都要经过CCFileUtilsAndroid类,所以需要 通过CCFileUtilsAndroid读取data.zpk文件中的内容。
CCFileUtilsAndroid中有两个函数需要修改一下:
Data FileUtilsAndroid::getData(const std::string& filename, bool forString)unsigned char* FileUtilsAndroid::getFileData(const std::string& filename, const char* mode, ssize_t * size)
在getData函数中需要修改的部分是,当找到assets/data.zpk时,即调用CPackManager::getFileData函数,返回读取的数据
if (fullPath[0] != '/') { if (fullPath.find("assets/") == std::string::npos && filename.find("data.zpk") == std::string::npos) { data = PackManager().getFileData(filename, size); } else { ......
getFileData函数修改同上:
if (fullPath[0] != '/') { if(filename.find("data.zpk") == std::string::npos && fullPath.find("assets/") == std::string::npos) { data = PackManager().getFileData(filename, *size); } else { ......
最后在AppDelegate.cpp添加查找路径
std::string writePath = cocos2d::FileUtils::getInstance()->getWritablePath(); std::vector<std::string> searchPaths;#if CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID searchPaths.push_back("data"); searchPaths.push_back(writePath);#else searchPaths.push_back(writePath); searchPaths.push_back("../../Resources"); searchPaths.push_back(writePath + "/Resources");#endif CCFileUtils::getInstance()->setSearchPaths(searchPaths);
在第一个使用的场景中使用即可
zp::String filename = _T("data.zpk"); PackManager().Open("data.zpk" , filename );
五、总结
使用zpack库有利于打包,最好对文件进行加密,加密的内容之后再写。
- zpack使用
- Zpack (开源)
- 游戏资源管理之zpack开源项目
- cocos2dx资源进行打包的工具和代码实zpack
- cocos2dx资源进行打包的工具和代码实现zpack
- 使用
- 使用
- 使用
- 使用
- 使用
- 使用
- 使用++,--
- 使用$@ $!
- 使用
- SoftICE使用(指令使用)
- 使用GraphEdit使用
- 使用HtmlParser使用心得
- 时钟使用使用
- 求1000到10000中的一个数的九倍是他自身的反序的数
- NumberUtils源码分析和使用
- 设计模式——适配器模式及jdk中的应用
- 取上整函数和取下正整函数
- PHP中解压缩的一个BUG
- zpack使用
- Eclipse下Android应用程序签名打包
- Jquery的基本选择器_二级联动_全选反选_左右移动_AJAX
- Java之IO(三)
- 关于漏洞:Memcached
- list
- 第一个只出现一次的字符
- spring-retry
- Python ConfigParser使用