cocos creator 中数据储存的坑。。。

本文探讨了CocosCreator中使用cc.sys.localStorage进行数据存储时遇到的问题,特别是关于布尔值的存储与读取,并提供了相应的解决方案。

我们都知道,开发一个游戏,一个重要的环节就是存储用户数据,对于大的数据当然数据库最好,但是一下小的数据再用数据库就有点小题大做了,对于cocos creator ,系统提供给我们一个简单的键值对的存取格式:

    cc.sys.localStorage.setItem(key, value); //存储数据

其中 key 是要存储的数据的名字,读取数据时要用到这个键, value 的该数据的值;

    cc.sys.localStorage.getItem(key); //读取数据

其中 key 就是我们存数据时候输入的数据名字,这些都很好理解,但是有件事就不好理解了,如下:

        cc.sys.localStorage.setItem("isPlay", false);

        var isPlay = cc.sys.localStorage.getItem("isPlay"); 
        if(isPlay){
            console.log("isPaly is true");
        }else{
            console.log("isPlay is false");
        }

按道理来说,我们存储的 isPlay 的值为 false ,输出的日志应该为 “isPlay is false”,然而。。。。。。

这里写图片描述

没错,这个就是运行的结果,说实话,我刚开始发现结果并不是我想要的,然后就开始调试,然后惊讶的发现了if(!isPlay)的语句直接跳过,然后我看着控制台显示

这里写图片描述

我当时就懵了,这是什么情况,难道JS存在bug?竟然让我发现了!然后就是各种不相信,就一遍一遍的试,一遍一遍的崩溃,最后终于让我找到了,我试着把

cc.sys.localStorage.setItem("isPlay", false);

这段代码中的 false 随便改了一个字符串,发现输出的log没有发生改变,到了这里,可能大家都想到了,在这个地方,我们存储的 isPlay 的内容实际上是一个字符串,而不是一个 false 的 bool 类型,
所以当我们对 isPlay 的值进行判断的时候,if(isPlay) 这个条件才会通过,发现了这个,接下来就简单了,可以用 0 和 1 来代替 false 和 true ,在条件语句中直接判断 isPlay 的值就可以了。希望可以帮助遇到同样问题的你。

PS:给大家分享一个优惠券网站,券券猫-领券购买更省钱(www.qquanmao.cn)

<think>我们正在讨论Cocos Creator中使用localStorage存储节点数据。根据引用,我们可以知道: 1. localStorage用于本地存储(引用[1]) 2. 存储数据使用`cc.sys.localStorage.setItem(key, value)` 3. 读取数据使用`cc.sys.localStorage.getItem(key)` 4. 节点数据通常不能直接存储,因为localStorage只能存储字符串。所以我们需要将节点数据转换为字符串(如JSON)再存储。 步骤: 1. 将节点数据转换为可存储的格式(通常是JSON)。 2. 使用`setItem`存储。 3. 读取时使用`getItem`获取字符串,再解析为JSON,然后应用到节点上。 示例: 假设我们有一个节点,需要存储它的位置(position)、旋转(rotation)和缩放(scale)等属性。 存储节点数据: ```javascript // 假设node是要存储的节点 let nodeData = { position: {x: node.x, y: node.y}, rotation: node.rotation, scale: {x: node.scaleX, y: node.scaleY} }; // 转换为字符串 let jsonString = JSON.stringify(nodeData); // 存储 cc.sys.localStorage.setItem('nodeData', jsonString); ``` 读取并应用到节点: ```javascript let jsonString = cc.sys.localStorage.getItem('nodeData'); if (jsonString) { let nodeData = JSON.parse(jsonString); node.x = nodeData.position.x; node.y = nodeData.position.y; node.rotation = nodeData.rotation; node.scaleX = nodeData.scale.x; node.scaleY = nodeData.scale.y; } ``` 注意: 1. 如果节点有多个,需要设计好存储结构,比如使用数组或为每个节点指定唯一key。 2. 如果节点有自定义组件,需要存储组件的状态,则需要在转换时包含这些状态,并在读取时恢复。 引用[2]中展示了在onLoad时从localStorage读取数据并设置到label上,引用[3]展示了使用try-catch处理异常。 因此,我们可以这样写: ```javascript // 存储节点数据函数 function saveNodeData(node, key) { let nodeData = { position: {x: node.x, y: node.y}, rotation: node.rotation, scale: {x: node.scaleX, y: node.scaleY} // 可以添加其他需要保存的属性 }; try { let jsonString = JSON.stringify(nodeData); cc.sys.localStorage.setItem(key, jsonString); } catch (error) { cc.error('保存节点数据失败:', error); } } // 加载节点数据函数 function loadNodeData(node, key) { try { let jsonString = cc.sys.localStorage.getItem(key); if (jsonString) { let nodeData = JSON.parse(jsonString); node.x = nodeData.position.x; node.y = nodeData.position.y; node.rotation = nodeData.rotation; node.scaleX = nodeData.scale.x; node.scaleY = nodeData.scale.y; // 其他属性恢复 } } catch (error) { cc.error('加载节点数据失败:', error); } } ``` 在需要保存的时候调用`saveNodeData`,在节点初始化时(如onLoad)调用`loadNodeData`。 注意事项: 1. 如果节点有动态添加的组件或者特殊状态,需要自行扩展nodeData的结构。 2. 对于节点树(多个节点),可以存储一个节点数组,每个节点用一个唯一标识(如name或uuid)来存储和恢复。 例如,存储多个节点: ```javascript let nodesData = []; // 假设nodes是一个节点数组 nodes.forEach(node => { nodesData.push({ uuid: node.uuid, // 使用uuid作为标识 data: { position: {x: node.x, y: node.y}, // ... 其他属性 } }); }); // 存储 cc.sys.localStorage.setItem('nodesData', JSON.stringify(nodesData)); ``` 恢复时,根据uuid找到对应的节点,然后应用数据。 但是注意:节点的uuid在每次运行时可能不同(尤其是动态生成的节点),所以这种方法适合保存场景中固定的节点。对于动态生成的节点,可能需要使用其他标识(如自定义id)或按顺序存储。 总结:Cocos Creator中使用localStorage存储节点数据的关键是将节点数据序列化为字符串,然后存储读取时再反序列化并应用到节点上。 相关问题: 1. 如何存储和恢复节点的自定义组件状态? 2. 如何存储整个节点树(包括子节点)? 3. 使用localStorage存储大量节点数据时需要注意什么?</think>### Cocos Creator localStorage 存储节点数据使用方法 在 Cocos Creator 中,使用 `localStorage` 存储节点数据需要将节点属性转换为可序列化的 JSON 数据。以下是详细步骤和示例代码: #### 一、核心步骤 1. **数据序列化**:将节点属性(位置、旋转、缩放等)转换为 JSON 字符串 2. **存储数据**:使用 `cc.sys.localStorage.setItem()` 存储 3. **读取数据**:使用 `cc.sys.localStorage.getItem()` 读取 4. **数据反序列化**:将 JSON 字符串解析并应用到节点 #### 二、完整示例代码 ```javascript // NodeStorage.js cc.Class({ extends: cc.Component, properties: { targetNode: cc.Node, // 需要存储的节点 saveKey: "nodeData" // 存储键名 }, onLoad() { // 尝试加载已存储的节点数据 this.loadNodeData(); }, // 保存节点数据到localStorage saveNodeData() { const nodeData = { position: { x: this.targetNode.x, y: this.targetNode.y }, rotation: this.targetNode.rotation, scale: { x: this.targetNode.scaleX, y: this.targetNode.scaleY }, active: this.targetNode.active }; try { const jsonString = JSON.stringify(nodeData); cc.sys.localStorage.setItem(this.saveKey, jsonString); cc.log("节点数据保存成功"); } catch (error) { cc.error("保存失败:", error.message); } }, // 从localStorage加载节点数据 loadNodeData() { try { const jsonString = cc.sys.localStorage.getItem(this.saveKey); if (!jsonString) return; const nodeData = JSON.parse(jsonString); this.targetNode.x = nodeData.position.x; this.targetNode.y = nodeData.position.y; this.targetNode.rotation = nodeData.rotation; this.targetNode.scaleX = nodeData.scale.x; this.targetNode.scaleY = nodeData.scale.y; this.targetNode.active = nodeData.active; cc.log("节点数据加载成功"); } catch (error) { cc.error("加载失败:", error.message); } }, // 清空存储数据(可选) clearStorage() { cc.sys.localStorage.removeItem(this.saveKey); } }); ``` #### 三、使用方法 1. **挂载组件**: - 创建空节点并添加 `NodeStorage` 组件 - 将需要存储的节点拖拽到 `targetNode` 属性 - 设置 `saveKey`(默认 "nodeData") 2. **调用存储**: ```javascript // 在按钮点击事件或其他逻辑中调用 this.getComponent(NodeStorage).saveNodeData(); ``` 3. **自动加载**: - 组件在 `onLoad()` 时会自动尝试加载数据 - 手动调用 `loadNodeData()` 可重新加载 #### 四、注意事项 1. **数据类型限制**: - 只能存储基本类型(字符串、数字、布尔) - 组件实例、纹理等复杂对象需特殊处理 - 使用 `JSON.stringify()` 时忽略函数和未定义属性 2. **存储容量**: - 浏览器通常限制 5MB - 超大数据需分块存储或使用 IndexedDB 3. **异常处理**: - 使用 `try-catch` 防止无效 JSON 导致崩溃 - 读取前检查数据是否存在(引用[3]) 4. **跨平台兼容**: - Web 端:直接使用浏览器 localStorage - 原生平台:自动转为文件存储(引用[1]) #### 五、高级用法 1. **存储多个节点**: ```javascript const nodesData = nodes.map(node => ({ uuid: node.uuid, position: { x: node.x, y: node.y }, // ...其他属性 })); cc.sys.localStorage.setItem("allNodes", JSON.stringify(nodesData)); ``` 2. **存储组件状态**: ```javascript const compData = this.getComponent(MyComponent).exportData(); nodeData.components = { [compName]: compData }; ``` 3. **自动保存**: ```javascript cc.director.on(cc.Director.EVENT_BEFORE_SCENE_LOADING, () => { this.saveNodeData(); }); ``` > **关键点**:节点数据存储本质是存储序列化的属性集合,恢复时重建节点状态而非节点实例本身(引用[2])。 --- ### 相关问题 1. 如何存储和恢复节点的自定义组件数据? 2. 当场景中有多个动态生成的节点时,如何高效存储所有节点数据? 3. 使用 localStorage 存储大量节点数据时有哪些性能优化方案? 4. 如何实现节点数据的版本兼容性(新旧版本数据格式不同)? 5. 在原生平台(iOS/Android)上使用 localStorage 存储节点数据有什么特殊注意事项?
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值