Cocos2d-x(js)のlocalStorageに配列を保存する場合の注意点

2016年10月25日(更新: 2016年10月25日)

Cocos2d-x(Cocos2d-js)で簡易的にアプリの状態を保存する場合は cc.sys.localStorage を使用します。

localStorage の使い方は以下の通りです。

// 値の保存
cc.sys.localStorage.setItem(キー, 値);

// 保存した値の読み込み
cc.sys.localStorage.getItem(キー);

数値や文字列などの保存ができる大変便利な機能ですが、配列を保存しようとした時に変わった挙動をします

今回はその現象についてとその対処法についてです。

確認した Cocos2d-x のバージョンは 3.13.1 です。

配列は繋がった文字列として保存される

例えば、数値や文字列、Boolean値をいくつか格納した各配列を用意し、それを localStorage に保存した後、すぐに読み込む以下のようなプログラムがあるとします。

// 数値を格納した配列を保存
cc.sys.localStorage.setItem("numbers", [1, 2, 10, 23]);
cc.log(cc.sys.localStorage.getItem("numbers"));

// 文字列を格納した配列を保存
cc.sys.localStorage.setItem("strings", ["Cocos2d-x", "Cocos2d-js", "javascript", "テストです"]);
cc.log(cc.sys.localStorage.getItem("strings"));

// Boolean値を格納した配列を保存
cc.sys.localStorage.setItem("bools", [false, true, true, false]);
cc.log(cc.sys.localStorage.getItem("bools"));

これを実行すると、出力は以下のようになります。

1,2,10,23

Cocos2d-x,Cocos2d-js,javascript,テストです

false,true,true,false

これは配列としてではなく、要素の間にカンマを挿入した一つの繋がった文字列として読み込まれています。

なので、例えば数値を格納した配列を読み込んで、以下のように配列の要素を出力させるプログラムを実行したとしましょう。

// 数値を格納した配列を保存
cc.sys.localStorage.setItem("test", [1, 2, 10, 23]);

// 数値を格納した配列を読み込んで、その要素を出力する(と考えた)処理
var numbers = cc.sys.localStorage.getItem("test");
for (var i = 0; i < numbers.length; i++) {
    cc.log(i + ": " + numbers[i]);
}

出力は以下のようになると期待したプログラムです。

0: 1
1: 2
2: 10
3: 23

しかし、実際は文字列となって読み込まれてしまうため、以下のような出力になります。

0: 1
1: ,
2: 2
3: ,
4: 1
5: 0
6: ,
7: 2
8: 3

文字列やBoolean値の場合も同じようにバラバラとなって1文字ずつ出力されてしまいます。

配列に直して読み込む方法

関数 split を使用して、読み込まれた文字列をカンマで区切り、配列に格納します。

// 配列を保存
cc.sys.localStorage.setItem("test", [1, 2, 10, 23]);

// 文字列として読み込み
var string = cc.sys.localStorage.getItem("test");

// カンマで文字列を分割
var results = string.split(",");

// 結果出力
cc.log(results);

実行すると、配列で出力されていることが確認できます。

localStorageで保存した配列を復元するサンプルコード

Boolean値の場合は、以下のような判定が必要になります。

var results = [];

var string = cc.sys.localStorage.getItem("test");
var array = string.split(",");

for (var i = 0; i < array.length; i++) {
    results[i] = (array[i] === "true"); // 文字列化した true と false を Boolean に戻す
}

cc.log(results);

以上で、localStorage で配列として保存したデータを配列として扱うことができます。

コメントを残す

メールアドレスが公開されることはありません。