quick-cocos2d-x數據存儲 UserDefault GameState io

看了quick-cocos2d-x 的framework,發現裏面有一個GameState,查了下,是數據存儲的類,因而稍稍總結下我用到過的數據存儲方式吧。json

一共是三種方法:函數

  1. cc.UserDefault
  2. cc.utils.State
  3. io

 

優缺點:工具

  前兩個使用起來更方便,由於是系統已經定義好的了。但缺點是不能在lua層面隨便更改文件名和路徑。ui

  因此在使用時,根據不一樣的需求,可選擇第一或者第三,第二個不太建議使用,太麻煩了。加密

 

  普通的應用信息,好比各類開關,使用cc.UserDefault保存,可隨應用的刪除,自動刪除文件。lua

  用戶的帳號信息,使用io存儲,保存在sd卡中,這樣用戶在重裝應用後,依然能順利進入。spa

 

第一種是使用cc.UserDefault類。這是系統提供的,產生的文件名爲 UserDefault.xml, 文件名在lua層面是沒法修改的,若是想修改,須要修改C++代碼。.net

兩個方法,存 和 讀取, 主要注意的是 不一樣的數據類型 調用的方法不一樣,以下面的例子 code

 1 local ParamType =
 2 {
 3     Integer = "int",
 4     String = "string",
 5     Float = "float",
 6     Bool = "bool",
 7     Double = "double",
 8 }
 9 
10 -- 保存
11 function NativeData:saveValeForKey(val, key, type)
12     if type == ParamType.String then
13         cc.UserDefault:getInstance():setStringForKey(key, val)
14     elseif type == ParamType.Integer then
15         cc.UserDefault:getInstance():setIntegerForKey(key, val)
16     elseif type == ParamType.Float then
17         cc.UserDefault:getInstance():setFloatForKey(key, val)
18     elseif type == ParamType.Double then
19         cc.UserDefault:getInstance():setDoubleForKey(key, val)
20     elseif type == ParamType.Bool then
21         cc.UserDefault:getInstance():setBoolForKey(key, val)
22     end
23 end
24 
25 -- 讀取
26 function NativeData:getValeForKey( key, type, default)
27     local vale = nil
28     if type == ParamType.String then
29         vale = cc.UserDefault:getInstance():getStringForKey(key, default)
30     elseif type == ParamType.Integer then
31         vale = cc.UserDefault:getInstance():getIntegerForKey(key, default)
32     elseif type == ParamType.Float then
33         vale = cc.UserDefault:getInstance():getFloatForKey(key, default)
34     elseif type == ParamType.Double then
35         vale = cc.UserDefault:getInstance():getDoubleForKey(key, default)
36     elseif type == ParamType.Bool then
37         vale = cc.UserDefault:getInstance():getBoolForKey(key, default)
38     end
39 
40     return vale
41 
42 end

 

第二種是使用cc.utils.State類。文件位置在framework/cc/utils/GameState.lua。默認framework並無加載,若是咱們要用到,須要手動加載。通常在myApp開頭加載。xml

 1 require("framework.cc.utils.GameState") 

加載完成後,須要初始化,cc.utils.State.init(eventListener_, stateFilename_, secretKey_)

在場景初始化以前調用一次便可,如在MyApp.lua的MyApp:ctor()中調用。


eventListener_是載入或保存時的回調函數

stateFilename_是保存的文件名,若是留空或非字符串(string)則是默認的state.txt,該文件會被保存到device.writablePath下

secretKey_是 校驗文件時所用到的密鑰,GameState保存的數據格式爲{h = hash, s = s},s是咱們要保存的數據(一個table),h則是要校驗的一個md5碼。若是secretKey_留空或爲非字符串(string)則不加校驗碼, 直接保存數據,跟CCUserDefault同樣了。

加載完成後,就是正常的使用。load 和save 方法都會 回調 init中的第一個參數。

 1 -- 這個方法通常只需調用一次,將本地文件load到內存中
 2 function GameState.load()
 3 end
 4 
 5 -- newValues是新的值,其實就是加載到內存中後保存的對象麼。
 6 function GameState.save(newValues)
 7 end
 8 
 9 -- 返回完整路徑
10 function GameState.getGameStatePath()
11 end

 關於eventListener_,能夠看一下 http://my.oschina.net/lonewolf/blog/173063 寫的,很詳細。

 

第三種是使用io 直接讀寫文件。這個最靈活。能夠根據本身的須要設定存儲目錄,文件名,是否須要加密。須要注意讀取以前須要判斷是否存在目錄 不存在則要建立。

一個簡單的文件工具類

module("MakeFileUtils", package.seeall)

local lfs, os, io = require"lfs", os, io

function readFile(path)
    local file = assert(io.open(path, "rb"))
    if file then
        local content = file:read("*all")
        io.close(file)
        return content
    end
    return nil
end

function writeFile(filename, data, rt)
    local f = assert(io.open(filename, rt))
    f:write(data)
    f:close()
end


function checkDirOK( path )
    local prepath = lfs.currentdir()

    if lfs.chdir(path) then
        lfs.chdir(prepath)
        return true
    end

    if lfs.mkdir(path) then
        return true
    end
end

 

 

-- 讀取

if not io.exists(fn) then
        return
    end

    local cnt = MakeFileUtils.readFile(fn)

    if cnt ~= nil and cnt ~= "" then
        return json.decode(cnt)
    end

 

 

-- 寫入

 1 MakeFileUtils.writeFile(fn, json.encode(cnt), "w+") 

相關文章
相關標籤/搜索