• quick-cocos2d-x数据存储 UserDefault GameState io


    看了quick-cocos2d-x 的framework,发现里面有一个GameState,查了下,是数据存储的类,于是稍稍总结下我用到过的数据存储方式吧。

    一共是三种方法:

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

    优缺点:

      前两个使用起来更方便,因为是系统已经定义好的了。但缺点是不能在lua层面随便更改文件名和路径。

      所以在使用时,根据不同的需求,可选择第一或者第三,第二个不太建议使用,太麻烦了。

      普通的应用信息,比如各种开关,使用cc.UserDefault保存,可随应用的删除,自动删除文件。

      用户的账号信息,使用io存储,保存在sd卡中,这样用户在重装应用后,依然能顺利进入。

    第一种是使用cc.UserDefault类。这是系统提供的,产生的文件名为 UserDefault.xml, 文件名在lua层面是无法修改的,如果想修改,需要修改C++代码。

    两个方法,存 和 读取, 主要注意的是 不同的数据类型 调用的方法不同,如下面的例子 

     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开头加载。

     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+") 

  • 相关阅读:
    pch文件
    Info.plist常见的设置
    通知机制
    UITextField
    通过代码自定义cell(cell的高度不一致)
    Cell的重用原理
    UITableViewCell的contentView
    2019备考[嵌入式系统设计师]之“接口技术(上)”
    shell输入输出重定向问题
    [无私分享]最新网盘资源搜索站点
  • 原文地址:https://www.cnblogs.com/lan0725/p/4863936.html
Copyright © 2020-2023  润新知