cocos游戏中有的数据记录不在服务器,而在设备中,比如上次登录的角色,首次使用某个功能(红点),设置的选项,界面的布局信息等内容。这些数据通常使用文件记录保存在设备中,可以以字符串或者Lua中表的形式保存,下文以Quick-cocos为例,描述实现步骤。
本人做过的大型cocos项目中遇到过2种本地存储方式:
一.使用Lua API io.writefile和io.readfile
1.读写字符串文件
local function btn1CB()
local path = "D:/QuickRoot/mygame/writeFiles/testFile1"
io.writefile(path, "abc")
end
cc.ui.UIPushButton.new({ normal = "btn110.png", pressed = "btn111.png" }):onButtonClicked(btn1CB):pos(200, 200):addTo(bg)
local function btn2CB()
local path = "D:/QuickRoot/mygame/writeFiles/testFile1"
local data = io.readfile(path)
print(data)
end
cc.ui.UIPushButton.new({ normal = "btn110.png", pressed = "btn111.png" }):onButtonClicked(btn2CB):pos(300, 200):addTo(bg)
举例来看,例子中创建两个按钮,第一个写文件:使用的quick内函数io.writefile,第一个参数为文件路径和文件名,注意需保证路径正确,不能找不到文件夹;第二个参数为写入文件的内容,必须为字符串类型。
第二个按钮读文件,使用的quick内函数io.readfile,仅需一个路径参数,返回读取到的字符串。
2.读写表格文件
local function btn1CB()
local path = "D:/QuickRoot/mygame/writeFiles/testFile1"
local t1 = {["openedA"] = true, ["openedB"] = false}
io.writefile(path,json.encode(t1))
end
cc.ui.UIPushButton.new({ normal = "btn110.png", pressed = "btn111.png" }):onButtonClicked(btn1CB):pos(200, 200):addTo(bg)
local function btn2CB()
local path = "D:/QuickRoot/mygame/writeFiles/testFile1"
local strData = io.readfile(path)
local tData = json.decode(strData)
print(tData.openedA)
print(tData.openedB)
end
cc.ui.UIPushButton.new({ normal = "btn110.png", pressed = "btn111.png" }):onButtonClicked(btn2CB):pos(300, 200):addTo(bg)
和之前写字符串相比,表格在写之前需要调用json.encode把表转化为字符串,因为io.writefile的第二个参数类型必须为字符串。
读文件时,io.readfile依然返回的是字符串,转化为表类型需要用json.decode。
将表写入文件和写字符串相比,可以让一个文件功能多样化,保存键值关系的数据。
二.使用引擎的UserDefault类
通过UserDefault类记录数据会生成一个xml文件:UserDefault.xml,先看一个例子:
local keyInt = "keyInt"
cc.UserDefault:getInstance():setIntegerForKey(keyInt, 200)
local value = cc.UserDefault:getInstance():getIntegerForKey(keyInt)
local valueNOExist = cc.UserDefault:getInstance():getIntegerForKey("keyNoExist", 20)
local path = cc.FileUtils:getInstance():getWritablePath()
print("*******************", keyInt, value, valueNOExist, path)
local keyString = "keyString"
cc.UserDefault:getInstance():setStringForKey(keyString, "abc")
local value = cc.UserDefault:getInstance():getStringForKey(keyString)
print("*******************", keyString, value)
local keyBool = "keyBool"
cc.UserDefault:getInstance():setBoolForKey(keyBool, true)
local value = cc.UserDefault:getInstance():getBoolForKey(keyBool)
print("*******************", keyBool, value)
local keyFloat = "keyFloat"
cc.UserDefault:getInstance():setFloatForKey(keyFloat, "1.1")
local value = cc.UserDefault:getInstance():getFloatForKey(keyFloat)
print("*******************", keyFloat, value)
local keyDouble = "keyDouble"
cc.UserDefault:getInstance():setDoubleForKey(keyDouble, "2.2")
local value = cc.UserDefault:getInstance():getDoubleForKey(keyDouble)
print("*******************", keyDouble, value)
例子非常简单,通过键值对存储几种类型的数据,并且读取打印出来,同时把写文件的路径打印出来
值得注意的是get***ForKey的第二个参数是当key不存在时获取的默认值
接下来去这个路径下找到UserDefault.xml并打开,可以看到存储了正确的键值对
需要修改UserDefault.xml位置的话可参考下面写法
cc.FileUtils:getInstance():setWritablePath("D:/QuickCocos/game2/config/")
如果setStringForKey后,getStringForKey获取得值不对,原因是UserDefault.xml文件已经损坏,这时候把UserDefault.xml删除,下次调用setStringForKey会重新生成UserDefault.xml