Files
tankwar_proj/js/managers/StorageManager.js
2026-04-10 22:59:39 +08:00

250 lines
5.8 KiB
JavaScript

/**
* StorageManager.js
* Handles local data persistence using wx.setStorageSync/getStorageSync.
* Manages game save data, settings, and high scores.
*/
class StorageManager {
constructor() {
this._prefix = 'tankwar_';
}
// ============================================================
// Generic Storage
// ============================================================
/**
* Save a value to local storage.
* @param {string} key
* @param {*} value - Will be JSON-serialized.
*/
set(key, value) {
try {
wx.setStorageSync(this._prefix + key, JSON.stringify(value));
} catch (e) {
console.warn(`[StorageManager] Failed to save "${key}":`, e);
}
}
/**
* Load a value from local storage.
* @param {string} key
* @param {*} [defaultValue=null]
* @returns {*} Parsed value, or defaultValue if not found.
*/
get(key, defaultValue = null) {
try {
const raw = wx.getStorageSync(this._prefix + key);
if (raw === '' || raw === undefined || raw === null) return defaultValue;
return JSON.parse(raw);
} catch (e) {
console.warn(`[StorageManager] Failed to load "${key}":`, e);
return defaultValue;
}
}
/**
* Remove a value from local storage.
* @param {string} key
*/
remove(key) {
try {
wx.removeStorageSync(this._prefix + key);
} catch (e) {}
}
// ============================================================
// Game Progress
// ============================================================
/**
* Save game progress.
* @param {object} progress
* @param {number} progress.currentLevel
* @param {number} progress.lives
* @param {number} progress.fireLevel
* @param {string} progress.mode
*/
saveProgress(progress) {
this.set('progress', progress);
}
/**
* Load game progress.
* @returns {object|null}
*/
loadProgress() {
return this.get('progress', null);
}
/**
* Clear saved progress.
*/
clearProgress() {
this.remove('progress');
}
// ============================================================
// High Scores
// ============================================================
/**
* Get the high score for a mode.
* @param {string} mode - Game mode.
* @returns {number}
*/
getHighScore(mode) {
const scores = this.get('highscores', {});
return scores[mode] || 0;
}
/**
* Update high score if the new score is higher.
* @param {string} mode
* @param {number} score
* @returns {boolean} Whether a new high score was set.
*/
updateHighScore(mode, score) {
const scores = this.get('highscores', {});
if (score > (scores[mode] || 0)) {
scores[mode] = score;
this.set('highscores', scores);
return true;
}
return false;
}
/**
* Get the highest level reached.
* @returns {number}
*/
getHighestLevel() {
return this.get('highest_level', 0);
}
/**
* Update highest level if new level is higher.
* @param {number} level
*/
updateHighestLevel(level) {
const current = this.getHighestLevel();
if (level > current) {
this.set('highest_level', level);
}
}
// ============================================================
// Settings
// ============================================================
/**
* Save game settings.
* @param {object} settings
*/
saveSettings(settings) {
this.set('settings', settings);
}
/**
* Load game settings.
* @returns {object}
*/
loadSettings() {
return this.get('settings', {
soundEnabled: true,
musicEnabled: true,
vibrationEnabled: true,
});
}
// ============================================================
// Purchases & Unlocks
// ============================================================
/**
* Record a purchase.
* @param {string} itemId
*/
recordPurchase(itemId) {
const purchases = this.get('purchases', []);
if (!purchases.includes(itemId)) {
purchases.push(itemId);
this.set('purchases', purchases);
}
}
/**
* Check if an item has been purchased.
* @param {string} itemId
* @returns {boolean}
*/
hasPurchased(itemId) {
const purchases = this.get('purchases', []);
return purchases.includes(itemId);
}
// ============================================================
// First-time flags
// ============================================================
/**
* Check if this is the first time playing.
* @returns {boolean}
*/
isFirstPlay() {
return !this.get('has_played', false);
}
/**
* Mark that the player has played.
*/
markPlayed() {
this.set('has_played', true);
}
// ============================================================
// Cloud Sync Helpers
// ============================================================
/**
* Get data to sync to cloud.
* @returns {object}
*/
getCloudSyncData() {
return {
highscores: this.get('highscores', {}),
highest_level: this.getHighestLevel(),
purchases: this.get('purchases', []),
};
}
/**
* Restore data from cloud.
* @param {object} cloudData
*/
restoreFromCloud(cloudData) {
if (cloudData.highscores) {
const local = this.get('highscores', {});
// Merge: keep the higher score
for (const [mode, score] of Object.entries(cloudData.highscores)) {
if (score > (local[mode] || 0)) {
local[mode] = score;
}
}
this.set('highscores', local);
}
if (cloudData.highest_level) {
this.updateHighestLevel(cloudData.highest_level);
}
if (cloudData.purchases) {
const local = this.get('purchases', []);
const merged = [...new Set([...local, ...cloudData.purchases])];
this.set('purchases', merged);
}
}
}
module.exports = StorageManager;