added automatic saving and loading

This commit is contained in:
Rudis Muiznieks 2021-08-22 09:02:12 -05:00
parent be3b8e7917
commit 4e1386225f
5 changed files with 67 additions and 8 deletions

View file

@ -1,7 +1,3 @@
- save/restore state in local storage
- need to save all not-computed resource properties that can change
- resource.value
- resource.cost
- second click functionality (for selling)
- more infrastructure
- more follower storage space

View file

@ -19,6 +19,11 @@ function gameLoop (state: GameState, renderer: IRenderer): void {
gameLoop(state, renderer), cycleLength);
}
function startGame (state: GameState, renderer: IRenderer): void {
state.load(); // load saved game if one exists
gameLoop(state, renderer); // start the main loop
}
// run with default config at startup
((): void => {
const config: GameConfig = new GameConfig();
@ -39,7 +44,7 @@ function gameLoop (state: GameState, renderer: IRenderer): void {
}
});
if (document.readyState !== 'loading') gameLoop(state, renderer);
if (document.readyState !== 'loading') startGame(state, renderer);
else document.addEventListener('DOMContentLoaded', (): void =>
gameLoop(state, renderer));
startGame(state, renderer));
})();

View file

@ -1,4 +1,10 @@
class GameState {
private _versionMaj: number = 0;
private _versionMin: number = 1;
private _timeSinceSave: number = 0;
private readonly _timeBetweenSaves: number = 10000;
private _resources: Record<string, IResource> = { };
private _resourceKeys: string[] = [];
@ -16,6 +22,12 @@ class GameState {
public advance (time: number): void {
this.now = (new Date()).getTime();
this._timeSinceSave += time;
if (this._timeSinceSave >= this._timeBetweenSaves) {
this.save();
this._timeSinceSave = 0;
}
// advance each resource
for (const rkey of this._resourceKeys) {
if (this._resources[rkey].isUnlocked(this)
@ -109,4 +121,50 @@ class GameState {
this.logger.msg(text);
}
}
public save (): void {
const saveObj: { [key: string]: any } = { };
saveObj.version = {
maj: this._versionMaj,
min: this._versionMin
};
for (const rkey of this._resourceKeys) {
saveObj[rkey] = {
value: this._resources[rkey].value,
cost: this._resources[rkey].cost
};
}
const saveStr: string = btoa(JSON.stringify(saveObj));
localStorage.setItem('savegame', saveStr);
}
public load (): void {
const saveStr: string = localStorage.getItem('savegame');
if (saveStr !== null) {
try {
const saveObj: { [key: string]: any } =
JSON.parse(atob(saveStr));
if (this._versionMaj === saveObj.version.maj) {
for (const rkey of this._resourceKeys) {
if (saveObj[rkey] !== undefined
&& saveObj[rkey].value !== undefined
&& saveObj[rkey].cost !== undefined) {
this._resources[rkey].value = saveObj[rkey].value;
this._resources[rkey].cost = saveObj[rkey].cost;
}
}
} else {
// tslint:disable-next-line
console.log('The saved game is too old to load.');
}
} catch (e) {
// tslint:disable-next-line
console.log('There was an error loading the saved game.');
console.log(e); // tslint:disable-line
}
} else {
// tslint:disable-next-line
console.log('No save game was found.');
}
}
}

View file

@ -45,7 +45,7 @@ class Money extends Purchasable {
protected _purchaseLog (amount: number, state: GameState): string {
const followers: number = state.getResource('plorg').value;
return `You collected $${amount} from ${followers} followers.`;
return `You collected $${state.formatNumber(amount)} from ${state.formatNumber(followers)} followers.`;
}
public max (state: GameState): number | null {

View file

@ -14,7 +14,7 @@
true, {
"limit": 75,
"check-strings": true,
"ignore-pattern": "(^\\s+state\\.log\\(|^\\s+['\"`])"
"ignore-pattern": "(^\\s+state\\.log\\(|^\\s+(return )?['\"`])"
}
],
"whitespace": [