Implement preferences overlay
This commit is contained in:
parent
1e840ae7c2
commit
9fb009c8f7
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "minesweeper",
|
||||
"version": "0.81.0",
|
||||
"version": "0.81.1",
|
||||
"description": "Just Minesweeper!",
|
||||
"author": "Felix W. Dekker",
|
||||
"browser": "dist/bundle.js",
|
||||
|
|
|
@ -27,6 +27,19 @@
|
|||
|
||||
<section class="container" id="mainContainer">
|
||||
<!-- Controls -->
|
||||
<div class="row controls">
|
||||
<div class="column">
|
||||
<!-- Preferences -->
|
||||
<form id="preferencesOpenForm">
|
||||
<button><i class="fa fa-cogs"></i> Preferences</button>
|
||||
</form>
|
||||
|
||||
<!-- Statistics -->
|
||||
<form id="statisticsOpenForm">
|
||||
<button><i class="fa fa-tachometer"></i> Statistics</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row controls">
|
||||
<div class="column">
|
||||
<!-- Difficulty -->
|
||||
|
@ -49,11 +62,6 @@
|
|||
<form id="seedOpenForm">
|
||||
<button><i class="fa fa-tree"></i> Enter seed</button>
|
||||
</form>
|
||||
|
||||
<!-- Statistics -->
|
||||
<form id="statisticsOpenForm">
|
||||
<button><i class="fa fa-tachometer"></i> Statistics</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row controls">
|
||||
|
@ -134,6 +142,21 @@
|
|||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Preferences overlay -->
|
||||
<div class="overlayWrapper" id="preferencesOverlay">
|
||||
<div class="overlay">
|
||||
<form id="preferencesForm">
|
||||
<label for="preferencesEnableMarks">Enable question marks</label>
|
||||
<input type="checkbox" id="preferencesEnableMarks" />
|
||||
<br /><br />
|
||||
|
||||
<button>Save</button>
|
||||
</form>
|
||||
<form id="preferencesCancelForm">
|
||||
<button class="cancel">Cancel</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Statistics overlay -->
|
||||
<div class="overlayWrapper" id="statisticsOverlay">
|
||||
<div class="overlay">
|
||||
|
|
|
@ -34,6 +34,9 @@ export class Game {
|
|||
private readonly heightInput: HTMLInputElement;
|
||||
private readonly minesInput: HTMLInputElement;
|
||||
private readonly solvableInput: HTMLInputElement;
|
||||
private readonly preferencesOverlay: Overlay;
|
||||
private readonly enableMarksInput: HTMLInputElement;
|
||||
private readonly preferencesOpenForm: HTMLFormElement;
|
||||
private readonly statisticsOverlay: Overlay;
|
||||
private readonly statisticsDiv: HTMLDivElement;
|
||||
private readonly statisticsResetForm: HTMLFormElement;
|
||||
|
@ -52,9 +55,10 @@ export class Game {
|
|||
/**
|
||||
* Constructs and starts a new game of Minesweeper.
|
||||
*
|
||||
* @param preferences the preferences to play the game under; may be changed during gameplay
|
||||
* @param withForkAwesome whether ForkAwesome can be used
|
||||
*/
|
||||
constructor(withForkAwesome: boolean = true) {
|
||||
constructor(preferences: Preferences, withForkAwesome: boolean = true) {
|
||||
this.canvas = $("#canvas");
|
||||
|
||||
this.field = null; // Placeholder until `initNewField`
|
||||
|
@ -227,6 +231,25 @@ export class Game {
|
|||
}
|
||||
);
|
||||
|
||||
// Preferences
|
||||
this.enableMarksInput = $("#preferencesEnableMarks");
|
||||
this.preferencesOpenForm = $("#preferencesOpenForm");
|
||||
this.preferencesOpenForm.addEventListener(
|
||||
"submit",
|
||||
event => {
|
||||
event.preventDefault();
|
||||
|
||||
this.enableMarksInput.checked = preferences.marksEnabled;
|
||||
this.preferencesOverlay.show();
|
||||
}
|
||||
);
|
||||
this.preferencesOverlay = new Overlay(
|
||||
$("#preferencesOverlay"),
|
||||
$("#preferencesForm"),
|
||||
$("#preferencesCancelForm"),
|
||||
() => preferences.marksEnabled = this.enableMarksInput.checked
|
||||
);
|
||||
|
||||
// Statistics
|
||||
this.statisticsDiv = $("#statisticsDiv");
|
||||
this.statisticsOpenForm = $("#statisticsOpenForm");
|
||||
|
@ -298,7 +321,8 @@ export class Game {
|
|||
if (square !== undefined) {
|
||||
if (square.hasFlag) {
|
||||
this.field.toggleFlag(coords);
|
||||
this.field.toggleMark(coords);
|
||||
if (preferences.marksEnabled)
|
||||
this.field.toggleMark(coords);
|
||||
} else if (square.hasMark) {
|
||||
this.field.toggleMark(coords);
|
||||
} else {
|
||||
|
@ -415,3 +439,41 @@ export class Game {
|
|||
}, 1000);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The player's preferences.
|
||||
*/
|
||||
export class Preferences {
|
||||
private static readonly storageKey = "/tools/minesweeper//preferences";
|
||||
|
||||
/**
|
||||
* Reads the object stored in local storage.
|
||||
*
|
||||
* @return the object stored in local storage, or an empty object if there is nothing in the local storage
|
||||
* @private
|
||||
*/
|
||||
private read(): { [key: string]: string } {
|
||||
return JSON.parse(localStorage.getItem(Preferences.storageKey) ?? "{}");
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the given object to local storage.
|
||||
*
|
||||
* @param statistics the object to write to local storage
|
||||
* @private
|
||||
*/
|
||||
private write(statistics: { [key: string]: string }): void {
|
||||
localStorage.setItem(Preferences.storageKey, JSON.stringify(statistics));
|
||||
}
|
||||
|
||||
|
||||
get marksEnabled(): boolean {
|
||||
return (this.read()["marksEnabled"] ?? "true") === "true";
|
||||
}
|
||||
|
||||
set marksEnabled(value: boolean) {
|
||||
const preferences = this.read();
|
||||
preferences["marksEnabled"] = "" + value;
|
||||
this.write(preferences);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ import "../css/main.css";
|
|||
// @ts-ignore
|
||||
import {$, doAfterLoad, footer, header, nav} from "@fwdekker/template";
|
||||
import {waitForForkAwesome} from "./Common";
|
||||
import {Game} from "./Game";
|
||||
import {Game, Preferences} from "./Game";
|
||||
|
||||
|
||||
doAfterLoad(() => {
|
||||
|
@ -24,10 +24,10 @@ doAfterLoad(() => {
|
|||
|
||||
// Start game
|
||||
waitForForkAwesome(
|
||||
() => new Game(),
|
||||
() => new Game(new Preferences()),
|
||||
() => {
|
||||
alert("External font could not be loaded. Using fallback font. Is a browser extension blocking fonts?");
|
||||
new Game(false);
|
||||
new Game(new Preferences(), false);
|
||||
},
|
||||
3000
|
||||
);
|
||||
|
|
Loading…
Reference in New Issue