對應 iOS NSUserDefaults,提供鍵值對持久化儲存,底層以 XML 檔案落地。API 極簡,支援 Bool/Integer/Float/Double/String 五種型別:
// 讀取 (含預設值)
bool getBoolForKey(const char* key, bool defaultValue = false);
int getIntegerForKey(const char* key, int defaultValue = 0);
float getFloatForKey(const char* key, float defaultValue = 0.0f);
double getDoubleForKey(const char* key, double defaultValue = 0.0);
std::string getStringForKey(const char* key, const std::string& defaultValue = "");
// 寫入
void setBoolForKey(const char* key, bool value);
void setIntegerForKey(const char* key, int value);
void setFloatForKey(const char* key, float value);
void setDoubleForKey(const char* key, double value);
void setStringForKey(const char* key, const std::string& value);
CCUserDefault* save = CCUserDefault::sharedUserDefault();
save->setBoolForKey("music_on", true);
save->setIntegerForKey("high_score", 9999);
save->setStringForKey("player_name", "Hero");
// 讀取
bool music = save->getBoolForKey("music_on");
int score = save->getIntegerForKey("high_score");
| 缺陷 | 影響 | 緩解方案 |
|---|---|---|
| 無「檔案/表」概念 | 多存檔 (多角色、多槽位) 需自行管理 Key 前綴,易衝突、難維護 | 簡單遊戲可用;複雜遊戲改用 SQLite |
| 無型別安全 | 以 getIntegerForKey 讀寫過 setBoolForKey 的 Key 不報錯,回傳 0/1 導致邏輯錯誤 | 建立封裝層統一 Key 常數與存取函數 |
| 明文 XML、無完整性驗證 | 玩家可直接修改存檔作弊 (金幣、等級、道具) | 自行加簽名驗證 (CRC32/MD5/HMAC),或改用加密 SQLite |

// 偽代碼
if (!storageFileExists()) {
// 首次執行:寫入預設值
save->setBoolForKey("is_first_run", false);
save->setIntegerForKey("gold", 100);
// ... 其他預設值
}
// 統一讀取並初始化遊戲狀態
bool music = save->getBoolForKey("music_on");
int gold = save->getIntegerForKey("gold");
// ...
注意:不要依賴 getXXXForKey 的預設值參數判斷「是否為首次執行」,因為 getXMLFilePath() 若檔案不存在會自動建立空檔,導致後續判斷失效。建議用專用 Flag Key (如 is_initialized) 明確標記。
下一篇將介紹 SQLite 整合,解決結構化儲存與防篡改需求。