本文是以cocos2d-x对PNG图片资源进行加密为基础进行的修改,原文方法对Cocos Studio生成的项目并没有支持,Studio生成的csb文件是二进制文件,也就是说我们无法提前修改它里面要加载的图片资源扩展名,所以只能从引擎源代码下手。
首先按照原文所说下载加密解密的算法和工具,将提供的6个文件导入到源代码项目中,然后在CCDecryptImage.h和CCDecryptImage.cpp中添加一个函数:
void ChangeExtensionToEPNG(std::string &file_path) { std::string::size_type pos = file_path.rfind('.'); std::string extstr; if (std::string::npos != pos) { extstr = file_path.substr(pos); if (extstr == ".png") { file_path = file_path.substr(0,pos); file_path.append(".epng"); } } }很简单,就是给传入的png图片路径改一个后缀名,改成epng
然后修改CCImage.cpp中的initWithImageFile和initWithImageFileThreadSafe函数:
bool Image::initWithImageFile(const std::string& path) { std::string epngpath = path; if (splitext(epngpath)[1] == ".png") { ChangeExtensionToEPNG(epngpath); } bool ret = false; _filePath = FileUtils::getInstance()->fullPathForFilename(epngpath); Data data = FileUtils::getInstance()->getDataFromFile(_filePath); if (!data.isNull()) { // 图片文件解密 if (splitext(epngpath)[1] == ".epng") { auto image_data = DecryptImage(epngpath,data); ret = initWithImageData(&image_data[0],image_data.size()); } else { ret = initWithImageData(data.getBytes(),data.getSize()); } } return ret; } bool Image::initWithImageFileThreadSafe(const std::string& fullpath) { std::string epngpath = fullpath; if (splitext(epngpath)[1] == ".png") { ChangeExtensionToEPNG(epngpath); } bool ret = false; _filePath = epngpath; Data data = FileUtils::getInstance()->getDataFromFile(epngpath); if (!data.isNull()) { // 图片文件解密 if (splitext(epngpath)[1] == ".epng") { auto image_data = DecryptImage(epngpath,data.getSize()); } } return ret; }特别解释一下:_filePath是CCImage类的成员变量,它将会添加到一个内存列表中,用于判断内存是否已经加载了这个图片资源,所以它的值也必须是.epng的后缀,否则引擎会无法识别是否已经加载了某个图片资源。getDataFromFile同样也要传入epng路径,因为我们打包游戏的时候不可能也把png图片打包进去,所以如果不用epng路径,它返回的值将永远是NULL。
这样就大功告成了,重新编译项目即可。
需要注意的是,由于通常我们不会单独加载某张图片,一般都是做成合图然后加载合图资源,所以合图应该这样加载和使用:
cc.SpriteFrameCache:getInstance():addSpriteFrames("plisttest.plist","plisttest.epng") self:getResourceNode():getChildByName("img"):loadTexture("aboutBtn_normal.png",1)为什么加载的时候要用epng而使用的时候用png呢?
因为epng路径是告诉引擎,你应该加载这个文件并且记住你已经加载了它,而引擎解析plist后,由于plist中记录的是png路径,所以引擎会将拆分出来的Texture用png路径标识,所以要使用Texture还是得用png路径。