State saving, change timing system to something simpler (but less accurate)
This commit is contained in:
+1
-1
@@ -8,7 +8,7 @@
|
||||
<div id="top-bar">
|
||||
<div id="time-container">
|
||||
<span>Time</span>
|
||||
<span class="data" id="time">0:00</span>
|
||||
<span class="data" id="time">00:00</span>
|
||||
</div>
|
||||
<div id="level-container">
|
||||
<span>Level</span>
|
||||
|
||||
@@ -1,31 +1,81 @@
|
||||
var $ = document.querySelector.bind(document);
|
||||
var $$ = document.querySelectorAll.bind(document);
|
||||
var field_height = 16;
|
||||
var field_width = 8;
|
||||
var initial_mines_count = 10;
|
||||
var mines_placed = false;
|
||||
let cut_sound = new Audio("./res/scissor_cut.wav");
|
||||
let dig_sound = new Audio("./res/dig.wav");
|
||||
var t0; // When did the player click for the first time?
|
||||
let ui_timer;
|
||||
const $ = document.querySelector.bind(document);
|
||||
const $$ = document.querySelectorAll.bind(document);
|
||||
|
||||
minefield_initialize();
|
||||
let field_height = 4;
|
||||
let field_width = 8;
|
||||
let initial_mines_count = 3;
|
||||
let mines_placed = false;
|
||||
let game_finished = false;
|
||||
let ui_timer;
|
||||
let seconds_elapsed = 0;
|
||||
|
||||
let sound_reveal = new Audio("./res/reveal.wav");
|
||||
let sound_mark = new Audio("./res/mark.wav");
|
||||
|
||||
start_or_continue_game();
|
||||
window.addEventListener("beforeunload", function() {
|
||||
if (mines_placed && !game_finished) {
|
||||
save_game_state ();
|
||||
} else {
|
||||
localStorage.removeItem("minefield_html");
|
||||
}
|
||||
});
|
||||
|
||||
function save_game_state() {
|
||||
// We need to save: the minefield, the elapsed time from when the
|
||||
// player started playing till he quit.
|
||||
localStorage.setItem("minefield_html", $("#minefield").innerHTML);
|
||||
localStorage.setItem("seconds_elapsed", seconds_elapsed);
|
||||
}
|
||||
|
||||
function start_or_continue_game() {
|
||||
let minefield_html = localStorage.getItem("minefield_html");
|
||||
if (minefield_html == null) {
|
||||
minefield_initialize();
|
||||
} else {
|
||||
// If we have a minefield in localStorage, load it back into
|
||||
// the DOM.
|
||||
$("#minefield").innerHTML = minefield_html;
|
||||
// We need to re-add events to the cells.
|
||||
for (let y = 0; y < field_height; y++) {
|
||||
for (let x = 0; x < field_width; x++) {
|
||||
let cell = $("#c" + x + "-" + y);
|
||||
cell.onclick = cell_onclick.bind(cell);
|
||||
cell.oncontextmenu = cell_oncontextmenu.bind(cell);
|
||||
cell.x = x;
|
||||
cell.y = y;
|
||||
}
|
||||
}
|
||||
mines_placed = true;
|
||||
seconds_elapsed = parseInt(localStorage.getItem("seconds_elapsed"));
|
||||
$("#time").innerText = get_elapsed_readable();
|
||||
start_timing();
|
||||
}
|
||||
}
|
||||
|
||||
function get_elapsed_readable() {
|
||||
let date = new Date(null);
|
||||
date.setSeconds(seconds_elapsed);
|
||||
return date.toISOString().slice(14, 19);
|
||||
}
|
||||
|
||||
// Used for the displayed timer. It's more or less how much time you
|
||||
// took, but the final time is calculated from a date.
|
||||
function start_ui_timer() {
|
||||
function start_timing() {
|
||||
ui_timer = window.setInterval(function() {
|
||||
var time = new Date(new Date() - t0);
|
||||
var t = (time.getMinutes() + ":").padStart(2, '0') + ("" + (time.getSeconds())).padStart(2, '0');
|
||||
$("#time").innerText = t;
|
||||
seconds_elapsed += 1;
|
||||
$("#time").innerText = get_elapsed_readable();
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
function stop_timing() {
|
||||
window.clearInterval(ui_timer);
|
||||
}
|
||||
|
||||
function cell_onclick() {
|
||||
if (!mines_placed) {
|
||||
place_mines(this.x, this.y);
|
||||
t0 = new Date();
|
||||
start_ui_timer();
|
||||
start_timing();
|
||||
}
|
||||
if (this.classList.contains("unknown") && !this.classList.contains("flagged")) {
|
||||
if (this.classList.contains("mine")) {
|
||||
@@ -45,16 +95,16 @@ function cell_onclick() {
|
||||
function cell_oncontextmenu() {
|
||||
if (this.classList.contains("unknown")) {
|
||||
this.classList.add("flagged");
|
||||
dig_sound.play();
|
||||
sound_mark.play();
|
||||
}
|
||||
check_victory();
|
||||
return false;
|
||||
}
|
||||
|
||||
function minefield_initialize() {
|
||||
for (var y = 0; y < field_height; y++) {
|
||||
for (var x = 0; x < field_width; x++) {
|
||||
var cell = document.createElement("div");
|
||||
for (let y = 0; y < field_height; y++) {
|
||||
for (let x = 0; x < field_width; x++) {
|
||||
let cell = document.createElement("div");
|
||||
cell.id = "c" + x + "-" + y;
|
||||
cell.x = x;
|
||||
cell.y = y;
|
||||
@@ -68,9 +118,9 @@ function minefield_initialize() {
|
||||
}
|
||||
|
||||
function place_mines(avoid_x, avoid_y) {
|
||||
for (var i = 0; i < initial_mines_count; i++) {
|
||||
var x = Math.floor(Math.random() * field_width);
|
||||
var y = Math.floor(Math.random() * field_height);
|
||||
for (let i = 0; i < initial_mines_count; i++) {
|
||||
let x = Math.floor(Math.random() * field_width);
|
||||
let y = Math.floor(Math.random() * field_height);
|
||||
if (Math.abs(x - avoid_x) <= 1 && Math.abs(y - avoid_y) <= 1) {
|
||||
--i;
|
||||
} else {
|
||||
@@ -81,29 +131,29 @@ function place_mines(avoid_x, avoid_y) {
|
||||
}
|
||||
|
||||
function check_victory() {
|
||||
for (var y = 0; y < field_height; ++y) {
|
||||
for (var x = 0; x < field_width; ++x) {
|
||||
var cell = $("#c" + x + "-" + y);
|
||||
for (let y = 0; y < field_height; ++y) {
|
||||
for (let x = 0; x < field_width; ++x) {
|
||||
let cell = $("#c" + x + "-" + y);
|
||||
if (cell.classList.contains("unknown") && !(cell.classList.contains("flagged") && cell.classList.contains("mine"))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
// If we get here, we've won
|
||||
var time = new Date(new Date() - t0);
|
||||
var t = (time.getMinutes() + ":").padStart(2, '0') + ("" + (time.getSeconds())).padStart(2, '0');
|
||||
window.clearInterval(ui_timer);
|
||||
let promise = window.webxdc.sendUpdate({
|
||||
game_finished = true;
|
||||
stop_timing();
|
||||
// Send a message proclaiming we've won.
|
||||
window.webxdc.sendUpdate({
|
||||
payload: {},
|
||||
info: window.webxdc.selfName + " cleaned up all the mines in " + t + "!"
|
||||
info: window.webxdc.selfName + " cleaned up all the mines in " + get_elapsed_readable() + "!"
|
||||
}, window.webxdc.selfName + " won a game of Minesweeper");
|
||||
return true;
|
||||
}
|
||||
|
||||
function get_neighbours(cell) {
|
||||
var cells = [];
|
||||
for (var x = cell.x - 1; x <= cell.x + 1; ++x) {
|
||||
for (var y = cell.y - 1; y <= cell.y + 1; ++y) {
|
||||
let cells = [];
|
||||
for (let x = cell.x - 1; x <= cell.x + 1; ++x) {
|
||||
for (let y = cell.y - 1; y <= cell.y + 1; ++y) {
|
||||
if (x >= 0 && x < field_width && y >= 0 && y < field_height && !(cell.x == x && cell.y == y)) {
|
||||
cells.push($("#c" + x + "-" + y));
|
||||
}
|
||||
@@ -123,7 +173,7 @@ function count_neighbouring_mines(cell) {
|
||||
}
|
||||
|
||||
function reveal_mines(cell) {
|
||||
var n_mines = count_neighbouring_mines(cell);
|
||||
let n_mines = count_neighbouring_mines(cell);
|
||||
cell.classList.remove("unknown");
|
||||
cell.classList.add("known");
|
||||
if (n_mines == 0) {
|
||||
@@ -140,11 +190,12 @@ function reveal_mines(cell) {
|
||||
cell.innerText = "" + n_mines;
|
||||
cell.classList.add("n" + n_mines);
|
||||
}
|
||||
cut_sound.play();
|
||||
sound_reveal.play();
|
||||
}
|
||||
|
||||
function lose_game() {
|
||||
window.clearInterval(ui_timer);
|
||||
game_finished = true;
|
||||
stop_timing();
|
||||
$$("#minefield div").forEach(function(cell) {
|
||||
cell.classList.remove("unknown");
|
||||
cell.classList.add("known");
|
||||
|
||||
Reference in New Issue
Block a user