首先在開始的MyApp中添加
GameState=require(cc.PACKAGE_NAME .. ".cc.utils.GameState")
或者GameState = require("framework.cc.utils.GameState")
--全局變量
GameData={}
function MyApp:ctor()
MyApp.super.ctor(self)
GameState.init(function (param)
local returnValue = nil
if param.errorCode then
print("GameState Error")
else
print("GameState Right")
if param.name == "save" then
local str = json.encode(param.values)
str = crypto.encryptXXTEA(str, "abcd")
returnValue = {data = str}
elseif param.name == "load" then
local str = crypto.decryptXXTEA(param.values.data, "abcd")
returnValue = json.decode(str)
end
end
return returnValue
end,"data.txt","1234")
if io.exists(GameState.getGameStatePath()) then
print("dddddddd",GameState.getGameStatePath())
GameData = GameState.load()
end
--存儲數據
GameData.aaa="bbbmmmmmmmmmmmm"
GameState.save(GameData)
--取出數據直接用就OK
print(GameData.aaa)
end
注意:初始化的GameState.init和加載GameState.load()只需在構造裏面調用一次即可
-----------------------------------------------------------------------------------詳細說明------------------------------------------------------------------------------------------
GameState是Quick-Cocos2d-x中特有的一個用戶信息存儲類,相對於CCUserDefault而言,它增加了數據校驗的功能,當數據被人爲的改變之後,會被檢測出來,下面介紹它的主要用法。
一、初始化
因爲GameState並沒有在framework中加載,所以我們要在開始的代碼中去加載,如在MyApp.lua的開頭位置加載
1
|
GameState=require(cc.PACKAGE_NAME ..".cc.utils.GameState") |
二、提供的方法
1、GameState.init(eventListener_, stateFilename_, secretKey_)
這個方法是初始化GameState,在場景初始化之前調用一次即可,如在MyApp.lua的MyApp:ctor()中調用。
eventListener_是載入或保存時調用的函數,可以寫個匿名函數,後面會重點介紹;
stateFilename_是保存的文件名,如果留空或非字符串(string)則是默認的state.txt,該文件會被保存到device.writablePath下;
secretKey_是 校驗文件時所用到的密鑰,GameState保存的數據格式爲{h = hash, s = s},s是我們要保存的數據(一個table),h則是要校驗的一個md5碼。如果secretKey_留空或爲非字符串(string)則不加校驗碼, 直接保存數據,跟CCUserDefault一樣了。
2、GameState.load()
載入並返回數據,一般此方法只調用一些就行,在遊戲加載前調用並保存到一個全局變量GameData。
3、GameState.save(newValues)
保存數據,newValues是一個table。GameState.init對應於保存一個文件,此文件的內容就是newValues,所以我們需要更新數據的時候應該改變上面的GameData,然後保存GameData。
4、GameState.getGameStatePath()
保存的文件的完整路徑。
三、eventListener(value)
此函數就是GameState.init中的第一個參數,value爲一個table,此函數在載入或保存時都會被調用,相當於一個監聽器。不同的情況下value的值會不一樣。
注意:eventListener一定要有返回值。
1、GameState.load()中用到的eventListener
1) 如果在這個函數中載入數據時有異常發生,value值爲{name = “load”, errorCode = errorCode},name有兩種值,”load”和”save”,分別對應載入和保存;errorCode分爲三種:
1
2
3
|
GameState.ERROR_INVALID_FILE_CONTENTS //不合法的文件內容,即取出來的內容不是一個table GameState.ERROR_HASH_MISS_MATCH //文件被人爲更改過 GameState.ERROR_STATE_FILE_NOT_FOUND //文件不存在 |
這個時候eventListener可返回nil。
2) 如果載入的數據是正確的,value值爲
1
2
3
4
5
6
|
{ name = "load" , values = values, encode = encode, time = os. time () } |
values就是取出的數據;encode數據是否加密過;time當前取出的時間。這個時候eventListener返回value.values即可。
2、GameState.save(newValues)中用到的eventListener
這時value值爲
1
2
3
4
5
|
{ name = "save" , values = newValues, encode = type(secretKey) == "string" } |
values就是要保存的數據;encode數據是否要加密。這個時候eventListener返回value.values即可。
當然,以上的情況你都可以做一些其它的事,如彈出錯誤的窗口,或打印出已加載或已保存的數據。
四、加密數據
GameState保存的還是明文數據,只是加了校驗碼,如果我們不想被用戶知道保存了什麼信息,可加密了再保存,這個在eventListener中“過濾”一下就行了。
五、示例
下面是一個完整的加載、初始化、載入,保存及加解密的過程代碼:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
|
//MyApp.lua(加載、初始化、載入,加解密) ... require( "framework.cc.init" ) GameState=require(cc.PACKAGE_NAME .. ".cc.utils.GameState"
) -- global var GameData={} ... function MyApp:ctor() -- init GameState GameState.init(function(param) local returnValue=nil if param.errorCode then CCLuaLog( "error" ) else -- crypto if param.name== "save" then local str=json.encode(param.values) str=crypto.encryptXXTEA(str, "abcd" ) returnValue={data=str} elseif param.name== "load" then local str=crypto.decryptXXTEA(param.values.data, "abcd" ) returnValue=json.decode(str) end -- returnValue=param.values end return returnValue end, "data.txt" , "1234" ) if io.exists(GameState.getGameStatePath()) then GameData=GameState.load() end ..... end .... //保存的時候 GameData.aaa= "bbb" GameState.save(GameData) |