parent
c2544c520c
commit
6fbdc17bce
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "minesweeper",
|
"name": "minesweeper",
|
||||||
"version": "0.73.1",
|
"version": "0.74.0",
|
||||||
"description": "Just Minesweeper!",
|
"description": "Just Minesweeper!",
|
||||||
"author": "Felix W. Dekker",
|
"author": "Felix W. Dekker",
|
||||||
"browser": "dist/bundle.js",
|
"browser": "dist/bundle.js",
|
||||||
|
|
|
@ -46,7 +46,7 @@
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<!-- Seed -->
|
<!-- Seed -->
|
||||||
<form id="seedForm">
|
<form id="seedOpenForm">
|
||||||
<button>Enter seed</button>
|
<button>Enter seed</button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
@ -105,6 +105,20 @@
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<!-- Seed input overlay -->
|
||||||
|
<div class="overlayWrapper" id="seedOverlay">
|
||||||
|
<div class="overlay">
|
||||||
|
<form id="seedForm">
|
||||||
|
<label for="seed">Seed</label>
|
||||||
|
<input id="seed" />
|
||||||
|
|
||||||
|
<button>New game</button>
|
||||||
|
</form>
|
||||||
|
<form id="seedCancelForm">
|
||||||
|
<button>Cancel</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@ import {customDifficulty, defaultDifficulty, difficulties} from "./Difficulty";
|
||||||
import {Display} from "./Display";
|
import {Display} from "./Display";
|
||||||
import {Field} from "./Field";
|
import {Field} from "./Field";
|
||||||
import {Solver} from "./Solver";
|
import {Solver} from "./Solver";
|
||||||
|
import {Overlay} from "./UI";
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -15,14 +16,14 @@ import {Solver} from "./Solver";
|
||||||
export class Game {
|
export class Game {
|
||||||
private readonly canvas: HTMLCanvasElement;
|
private readonly canvas: HTMLCanvasElement;
|
||||||
private readonly difficultySelect: HTMLSelectElement;
|
private readonly difficultySelect: HTMLSelectElement;
|
||||||
private readonly customDifficultyOverlay: HTMLDivElement;
|
|
||||||
private readonly customDifficultyForm: HTMLFormElement;
|
|
||||||
private readonly customDifficultyCancelForm: HTMLFormElement;
|
|
||||||
private readonly newGameForm: HTMLFormElement;
|
private readonly newGameForm: HTMLFormElement;
|
||||||
private readonly restartForm: HTMLFormElement;
|
private readonly restartForm: HTMLFormElement;
|
||||||
private readonly seedForm: HTMLFormElement;
|
private readonly seedOverlay: Overlay;
|
||||||
|
private readonly seedOpenForm: HTMLFormElement;
|
||||||
|
private readonly seedInput: HTMLFormElement;
|
||||||
private readonly undoForm: HTMLFormElement;
|
private readonly undoForm: HTMLFormElement;
|
||||||
private readonly solveForm: HTMLFormElement;
|
private readonly solveForm: HTMLFormElement;
|
||||||
|
private readonly customDifficultyOverlay: Overlay;
|
||||||
private readonly widthInput: HTMLInputElement;
|
private readonly widthInput: HTMLInputElement;
|
||||||
private readonly heightInput: HTMLInputElement;
|
private readonly heightInput: HTMLInputElement;
|
||||||
private readonly minesInput: HTMLInputElement;
|
private readonly minesInput: HTMLInputElement;
|
||||||
|
@ -81,7 +82,7 @@ export class Game {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.customDifficultyOverlay.style.visibility = "unset";
|
this.customDifficultyOverlay.show();
|
||||||
this.widthInput.value = "" + (this.field?.width ?? defaultDifficulty.width);
|
this.widthInput.value = "" + (this.field?.width ?? defaultDifficulty.width);
|
||||||
this.heightInput.value = "" + (this.field?.height ?? defaultDifficulty.height);
|
this.heightInput.value = "" + (this.field?.height ?? defaultDifficulty.height);
|
||||||
this.minesInput.value = "" + (this.field?.mineCount ?? defaultDifficulty.mineCount);
|
this.minesInput.value = "" + (this.field?.mineCount ?? defaultDifficulty.mineCount);
|
||||||
|
@ -92,28 +93,11 @@ export class Game {
|
||||||
);
|
);
|
||||||
|
|
||||||
// Custom difficulty
|
// Custom difficulty
|
||||||
this.customDifficultyOverlay = $("#customDifficultyOverlay");
|
this.customDifficultyOverlay = new Overlay(
|
||||||
this.customDifficultyOverlay.addEventListener(
|
$("#customDifficultyOverlay"),
|
||||||
"mousedown",
|
$("#customDifficultyForm"),
|
||||||
event => {
|
$("#customDifficultyCancelForm"),
|
||||||
if (event.target === this.customDifficultyOverlay)
|
() => {
|
||||||
this.customDifficultyOverlay.style.visibility = "hidden";
|
|
||||||
}
|
|
||||||
);
|
|
||||||
this.customDifficultyOverlay.addEventListener(
|
|
||||||
"keydown",
|
|
||||||
event => {
|
|
||||||
if (event.key === "Escape")
|
|
||||||
this.customDifficultyOverlay.style.visibility = "hidden";
|
|
||||||
}
|
|
||||||
);
|
|
||||||
this.customDifficultyForm = $("#customDifficultyForm");
|
|
||||||
this.customDifficultyForm.addEventListener(
|
|
||||||
"submit",
|
|
||||||
event => {
|
|
||||||
event.preventDefault();
|
|
||||||
|
|
||||||
this.customDifficultyOverlay.style.visibility = "hidden";
|
|
||||||
this.initNewField(
|
this.initNewField(
|
||||||
+this.widthInput.value,
|
+this.widthInput.value,
|
||||||
+this.heightInput.value,
|
+this.heightInput.value,
|
||||||
|
@ -122,15 +106,6 @@ export class Game {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
this.customDifficultyCancelForm = $("#customDifficultyCancelForm");
|
|
||||||
this.customDifficultyCancelForm.addEventListener(
|
|
||||||
"submit",
|
|
||||||
event => {
|
|
||||||
event.preventDefault();
|
|
||||||
|
|
||||||
this.customDifficultyOverlay.style.visibility = "hidden";
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
this.widthInput = $("#settingsWidth");
|
this.widthInput = $("#settingsWidth");
|
||||||
this.widthInput.addEventListener("change", _ => this.setMineLimit());
|
this.widthInput.addEventListener("change", _ => this.setMineLimit());
|
||||||
|
@ -162,21 +137,30 @@ export class Game {
|
||||||
);
|
);
|
||||||
|
|
||||||
// Seed
|
// Seed
|
||||||
this.seedForm = $("#seedForm");
|
this.seedInput = $("#seed");
|
||||||
this.seedForm.addEventListener(
|
this.seedOpenForm = $("#seedOpenForm");
|
||||||
|
this.seedOpenForm.addEventListener(
|
||||||
"submit",
|
"submit",
|
||||||
event => {
|
event => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
|
||||||
const input = window.prompt("Enter seed", "" + this.seed);
|
this.seedOverlay.show();
|
||||||
if (input !== null)
|
this.seedInput.value = this.seed;
|
||||||
this.initNewField(
|
this.seedInput.focus();
|
||||||
this.field?.width,
|
}
|
||||||
this.field?.height,
|
);
|
||||||
this.field?.mineCount,
|
this.seedOverlay = new Overlay(
|
||||||
this.field?.solvable,
|
$("#seedOverlay"),
|
||||||
input
|
$("#seedForm"),
|
||||||
);
|
$("#seedCancelForm"),
|
||||||
|
() => {
|
||||||
|
this.initNewField(
|
||||||
|
this.field?.width,
|
||||||
|
this.field?.height,
|
||||||
|
this.field?.mineCount,
|
||||||
|
this.field?.solvable,
|
||||||
|
this.seedInput.value
|
||||||
|
);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,76 @@
|
||||||
|
/**
|
||||||
|
* An overlay displayed in HTML.
|
||||||
|
*/
|
||||||
|
export class Overlay {
|
||||||
|
private readonly overlay: HTMLDivElement;
|
||||||
|
private readonly submitForm: HTMLFormElement;
|
||||||
|
private readonly cancelForm: HTMLFormElement;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new overlay.
|
||||||
|
*
|
||||||
|
* @param overlay the overlay element to show and hide
|
||||||
|
* @param submitForm the form that invokes `onSubmit` and closes the overlay when submitted
|
||||||
|
* @param cancelForm the form that closes the overlay when submitted
|
||||||
|
* @param onSubmit the callback to invoke when the form is submit
|
||||||
|
*/
|
||||||
|
constructor(
|
||||||
|
overlay: HTMLDivElement,
|
||||||
|
submitForm: HTMLFormElement,
|
||||||
|
cancelForm: HTMLFormElement,
|
||||||
|
onSubmit: () => void
|
||||||
|
) {
|
||||||
|
this.overlay = overlay;
|
||||||
|
overlay.addEventListener(
|
||||||
|
"mousedown",
|
||||||
|
event => {
|
||||||
|
if (event.target === overlay)
|
||||||
|
this.hide();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
overlay.addEventListener(
|
||||||
|
"keydown",
|
||||||
|
event => {
|
||||||
|
if (event.key === "Escape")
|
||||||
|
this.hide();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
this.submitForm = submitForm;
|
||||||
|
submitForm.addEventListener(
|
||||||
|
"submit",
|
||||||
|
event => {
|
||||||
|
event.preventDefault();
|
||||||
|
|
||||||
|
this.hide();
|
||||||
|
onSubmit();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
this.cancelForm = cancelForm;
|
||||||
|
cancelForm.addEventListener(
|
||||||
|
"submit",
|
||||||
|
event => {
|
||||||
|
event.preventDefault();
|
||||||
|
|
||||||
|
this.hide();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shows the overlay.
|
||||||
|
*/
|
||||||
|
show(): void {
|
||||||
|
this.overlay.style.visibility = "unset";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hides the overlay.
|
||||||
|
*/
|
||||||
|
hide(): void {
|
||||||
|
this.overlay.style.visibility = "hidden";
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue