打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
quick
       首先介绍下quick-cocos2d-x这款引擎,quick-cocos2d-x 是在官方 cocos2d-x + Lua 版本的基础上修改起来的增强版(目前的稳定版基于 cocos2d-x 2.2)。在底层 API 上,quick 和 cocos2d-x 保持一致,而 quick 扩展的 API 主要分为两个部分:
	1. quick 里提供了一个 Lua framework,封装了大部分的 C++ API,简化了使用。在大多数情况下,只需要熟悉 quick 的 API 就可以完成开发工作。
	2. quick 中包含了不少游戏开发中必须的扩展,这些扩展也具有相应的 API。
       在使用Lua开发移动网络游戏的时候,通常一些图片资源需要在线下载然后缓存下来使用,为了节约存储空间,需要制定一个策略来对缓存图片资源进行回收处理。       对于下载的图片资源我们需要设定好存储路径,quick中使用全局变量device.writablePath即可获取到设备的可读写路径,它实际上就是调用cocos2d-x的CCFileUtils::sharedFileUtils()->getWritablePath()函数。当然我们也可以在这个路径下新建立一个cache目录。在游戏项目的入口lua文件可以添加CCFileUtils:sharedFileUtils():addSearchPath(device.writablePath .. "cache/")这句话,这样在加载资源的时候,会搜索该目录下的资源文件。当然cache目录是要预先创建的,否则在Android平台下可能报无法找到该路径的错误。       接下来需要写一个管理器来下载资源图片以及用一个表来对缓存资源进行维护,代码如下:
  1 --[[  2     下载图片的缓存管理器  3     @author xujh  4 ]]  5   6 ImageCacheManager = {}  7   8 local gameState = require(cc.PACKAGE_NAME .. ".api.GameState")  9  10 -- 图片缓存信息表,包括下载图片URL对应的md5值和最后更新时间 11 local cacheData = {} 12  13 -- 初始化GameState,存储缓存图片相关信息 14 function ImageCacheManager:init() 15     gameState.init(function(param) 16         -- local returnValue = nil 17         if param.errorCode then 18             print("error") 19         else 20             if param.name == "save" then 21  22             elseif param.name == "load" then 23  24             end 25         end 26         return param.values 27     end, "image_cache.txt", nil) 28     if io.exists(gameState.getGameStatePath()) then 29         cacheData = gameState.load() 30     end 31 end 32  33 --[[ 34     根据图片的md5值判断是否存在在缓存表中 35     @param 图片的md5值 36     @return 存在:true以及所在的位置,不存在:false 37 ]] 38 function ImageCacheManager:exist(md5) 39     for i = 1, #cacheData do 40         if cacheData[i].md5 == md5 then 41             return true, i 42         end 43     end 44     return false 45 end 46  47 --[[ 48     修改图片在缓存表中的最后更新时间 49     @param md5:图片的md5值, position:图片在缓存表中的位置 50 ]] 51 function ImageCacheManager:updateCacheTime(md5, position) 52     if cacheData[position].md5 == md5 then 53         table.remove(cacheData, position) 54         self:insertCacheData(md5) 55         -- dump(cacheData, "update") 56     else 57         print("ImageCacheManager updateCacheTime ERROR!") 58     end 59 end 60  61 --[[ 62     根据缓存目录里的图片来创建精灵 63     @param url 缓存图片的URL地址 64            x:精灵横向坐标值,y:精灵纵向坐标值 65     @return 若缓存表中存在对应的md5值,返回创建的精灵对象 66 ]] 67 function ImageCacheManager:newCacheSprite(url, x, y) 68     local md5 = crypto.md5(url, false) 69     local isExist, position = self:exist(md5) 70     if isExist then 71         self:updateCacheTime(md5, position) 72         local filename = md5 .. ".png" 73         return display.newSprite(filename, x, y) 74     end 75 end 76  77 --[[ 78     向图片缓存表中插入数据 79     @param 图片的md5值 80 ]] 81 function ImageCacheManager:insertCacheData(md5) 82     local data = {} 83     data.time = getCurrentMillis() 84     data.md5 = md5 85     if table.nums(cacheData) > 100 then 86         -- 超过缓存上限,清除第一个元素(通常最久未更新时间戳) 87         table.remove(cacheData, 1) 88     end 89     table.insert(cacheData, data) 90     gameState.save(cacheData) 91 end 92  93 --[[ 94     下载缓存图片 95     @param url 下载图片的URL地址 96            callback 调用下载处的回调函数地址 97 ]] 98 function ImageCacheManager:downloadImage(url, callback) 99     local md5 = crypto.md5(url, false)100     if not self:exist(md5) then101         local request = network.createHTTPRequest(function (event)102             local ok = (event.name == "completed")103             local request = event.request104             if not ok then105                 print(request:getErrorCode(), request:getErrorMessage())106                 return107             end108             local code = request:getResponseStatusCode()109             if code ~= 200 then110                 -- 请求结束,但没有返回 200 响应代码111                 print(code)112                 return113             end114             local filename = md5 .. ".png"115             request:saveResponseData(device.writablePath .. "cache/" .. filename)116             local item = {}117             item.time = getCurrentMillis()118             item.md5 = md5119             table.insert(cacheData, item)120             gameState.save(cacheData)121             if callback then callback(url) end122         end, url, "GET")123         request:start()124     else125         echoInfo("The %s has downloaded.", url)126     end127 end128 129 130 --[[131     根据需要删除缓存图片,释放存储空间132 ]]133 function ImageCacheManager:gcCache()134     for i = #cacheData, 1, -1 do135         local recordTime = cacheData[i].time136         local currentTime = getCurrentMillis()137         if currentTime - recordTime > 7*24*3600 then138             local cmd139             if (device.platform == "windows") then140                 cmd = "DEL /Q " .. device.writablePath .. "cache\\" .. cacheData[i].md5 .. ".png"141             else142                 cmd = "rm -r " .. device.writablePath .. "cache/" .. cacheData[i].md5 .. ".png"143             end144             os.execute(cmd)145             table.remove(cacheData, i)146         end147     end148     gameState.save(cacheData)149 end
       下面来详细说明下代码的具体作用,首先需要一个配置文件来管理缓存目录下图片资源的一些信息,这里并没有使用cocos2d-x的CCUserDefault,而是采用了quick-cocos2d-x提供的GameState(具体用法参见http://www.kankanews.com/ICkengine/archives/69049.shtml)。使用GameState需要先进行初始化,分别传入回调函数地址、文件名称和密匙,在回调函数中我们可以根据需要对要save或是load的数据进行加密解密操作。如果已经存在配置文件,我们则将里面的内容赋给表cacheData。在cacheData表中,线性存放了每张缓存图片相关信息的表集合,主要是下载URL对应的md5值和最后更新时间。       
       ImageCacheManager:newCacheSprite函数中,会根据传入的url转换成对应的md5值(crypto.md5为quick封装好的函数),然后遍历查找cacheData表中是否存在该md5值,存在则更新该图片在cacheData表中的最后更新时间,然后调用quick-cocos2d-x中的display.newSprite来创建精灵并返回(缓存在存储空间中的图片名称即“md5值.png”),不存在即返回nil。       
       ImageCacheManager:downloadImage函数中,会根据传入的url通过CCHTTPRequest来进行下载操作。下载的图片以“md5值.png”的文件名存储在cache目录下,并获取当前时间戳连同md5值一同插入cacheData表的尾端,记得要调用GameState的sava函数进行保存操作。       
       ImageCacheManager:gcCache函数中,会倒序遍历cacheData表,当发现与当前时间戳之差超过7天时,则删除该文件,并在cacheData中remove该图片的信息。       
       在代码中获取当前时间的接口函数getCurretMillis是通过C++实现的,通过tolua++绑定到lua中,使之可以在lua代码中直接调用,具体实现代码如下:
#ifdef WIN32#include <time.h>#else#include <sys/time.h>#endiflong getCurrentMillis(){    long cur_time = 0;#ifdef WIN32    time_t now;    time(&now);    cur_time = now*1000;#else    struct timeval tv;    gettimeofday(&tv, NULL);    cur_time = tv.tv_sec*1000 + tv.tv_usec/1000;#endif    return cur_time;}

 

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
三步搞定android应用图片缓存
java动态缓存技术:WEB缓存应用
Nginx+PHP FastCgi大幅度优化提速
解决淘宝TOP API频率过高,页面空白,调用不到数据
Django中如何使用Redis进行缓存详细教程(含Windows系统下安装redis)
OSCache做页面级缓存
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服