Add Statistics Panel feature
- Recreated full game foundation from previous session
- Added Statistics tab with detailed game metrics:
* Total Stardust Earned
* Current Production Rate (✨/sec)
* Total Clicks
* Click Power
* Time Played (auto-formatted)
* Buildings Owned
* Upgrades Purchased
* Achievements Unlocked
* Game Progress bar
- Fixed global production bonus calculation in game.js
- Added responsive CSS for stats panel
Files added: js/stats.js, dev-journal.md, README.md, JOURNAL.md
This commit is contained in:
@@ -0,0 +1,104 @@
|
||||
/**
|
||||
* Cosmic Garden - Save System
|
||||
* Handles localStorage persistence and export/import
|
||||
*/
|
||||
|
||||
const SaveSystem = {
|
||||
SAVE_KEY: 'cosmicGardenSave',
|
||||
|
||||
/**
|
||||
* Save game to localStorage
|
||||
*/
|
||||
save() {
|
||||
const data = JSON.stringify(Game.state);
|
||||
localStorage.setItem(this.SAVE_KEY, data);
|
||||
console.log('💾 Game saved');
|
||||
},
|
||||
|
||||
/**
|
||||
* Load game from localStorage
|
||||
*/
|
||||
load() {
|
||||
const data = localStorage.getItem(this.SAVE_KEY);
|
||||
if (data) {
|
||||
try {
|
||||
return JSON.parse(data);
|
||||
} catch (e) {
|
||||
console.error('Failed to parse save:', e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Export save as base64 string
|
||||
*/
|
||||
exportSave() {
|
||||
const data = btoa(JSON.stringify(Game.state));
|
||||
navigator.clipboard.writeText(data).then(() => {
|
||||
UI.showNotification('Save copied to clipboard!', 'success');
|
||||
}).catch(() => {
|
||||
// Fallback for older browsers
|
||||
const textarea = document.createElement('textarea');
|
||||
textarea.value = data;
|
||||
document.body.appendChild(textarea);
|
||||
textarea.select();
|
||||
document.execCommand('copy');
|
||||
document.body.removeChild(textarea);
|
||||
UI.showNotification('Save copied to clipboard!', 'success');
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Import save from base64 string
|
||||
*/
|
||||
importSave(data) {
|
||||
try {
|
||||
const parsed = JSON.parse(atob(data));
|
||||
|
||||
// Validate save data
|
||||
if (!parsed.stardust || !parsed.buildings) {
|
||||
throw new Error('Invalid save format');
|
||||
}
|
||||
|
||||
// Merge with existing state
|
||||
Game.state = { ...Game.state, ...parsed };
|
||||
Game.state.lastSaveTime = Date.now();
|
||||
|
||||
UI.update();
|
||||
return true;
|
||||
} catch (e) {
|
||||
console.error('Failed to import save:', e);
|
||||
UI.showNotification('Invalid save data!', 'warning');
|
||||
return false;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Clear save data
|
||||
*/
|
||||
clear() {
|
||||
localStorage.removeItem(this.SAVE_KEY);
|
||||
},
|
||||
|
||||
/**
|
||||
* Get last save time
|
||||
*/
|
||||
getLastSaveTime() {
|
||||
const data = this.load();
|
||||
if (data && data.lastSaveTime) {
|
||||
return new Date(data.lastSaveTime);
|
||||
}
|
||||
return null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Check if auto-save is available
|
||||
*/
|
||||
hasAutoSave() {
|
||||
return !!localStorage.getItem(this.SAVE_KEY);
|
||||
}
|
||||
};
|
||||
|
||||
window.SaveSystem = SaveSystem;
|
||||
Reference in New Issue
Block a user