From 3a739e33a99f75cf3b980e531cf831f7f099d558 Mon Sep 17 00:00:00 2001 From: Arne van Iterson Date: Wed, 18 Nov 2020 11:43:45 +0100 Subject: [PATCH] Multiplayer kind of working --- html/index.html | 41 +++++++-- package-lock.json | 170 ++++++++++++++++++++++++++++++++++--- package.json | 8 +- res/fonts/alarm clock.ttf | Bin 0 -> 21664 bytes scss/index.scss | 96 +++++++++++++++------ src/helpers/log.js | 7 +- src/helpers/multiplayer.js | 59 +++++++++++-- src/index.js | 20 +++++ src/screens/game.js | 95 +++++++++++++++------ webpack.config.js | 34 +++++--- 10 files changed, 442 insertions(+), 88 deletions(-) create mode 100644 res/fonts/alarm clock.ttf diff --git a/html/index.html b/html/index.html index 8c4b1bc..0088263 100644 --- a/html/index.html +++ b/html/index.html @@ -11,20 +11,49 @@

Minesweeper 99

-
- +
+ +
+ +
+
-
-

Gamelog

- +
+ +
+

Time left:

+ 00:00 +
+
+ +
+

Welcome

+
+
+

+ + +
+

+ + +
+
+ +
+

Gamelog

+
+ +
+
diff --git a/package-lock.json b/package-lock.json index 38a82ab..0e4be13 100644 --- a/package-lock.json +++ b/package-lock.json @@ -56,6 +56,11 @@ "strip-json-comments": "^3.1.1" } }, + "@fortawesome/fontawesome-free": { + "version": "5.15.1", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free/-/fontawesome-free-5.15.1.tgz", + "integrity": "sha512-OEdH7SyC1suTdhBGW91/zBfR6qaIhThbcN8PUXtXilY4GYnSBbVqOntdHbC1vXwsDnX0Qix2m2+DSU1J51ybOQ==" + }, "@types/component-emitter": { "version": "1.2.10", "resolved": "https://registry.npmjs.org/@types/component-emitter/-/component-emitter-1.2.10.tgz", @@ -506,6 +511,16 @@ "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==" }, + "babel-runtime": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", + "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", + "dev": true, + "requires": { + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" + } + }, "backo2": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz", @@ -760,6 +775,14 @@ "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" }, + "chainsaw": { + "version": "0.0.9", + "resolved": "https://registry.npmjs.org/chainsaw/-/chainsaw-0.0.9.tgz", + "integrity": "sha1-EaBRAtHEx4W20EFdM21aOhYSkT4=", + "requires": { + "traverse": ">=0.3.0 <0.4" + } + }, "chalk": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", @@ -1049,11 +1072,22 @@ "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" }, + "cookie-storage": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/cookie-storage/-/cookie-storage-6.1.0.tgz", + "integrity": "sha512-HeVqbVy8BjXhAAuFtL6MTG+witHoLbxfky2jgVh9FmxmyL6IKa9gSSyPNjevXCCCxPu6Tzd9J8+eXTRQzYU/cg==" + }, "copy-descriptor": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=" }, + "core-js": { + "version": "2.6.11", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.11.tgz", + "integrity": "sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg==", + "dev": true + }, "core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", @@ -1940,21 +1974,10 @@ "version": "6.2.0", "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-6.2.0.tgz", "integrity": "sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw==", + "dev": true, "requires": { "loader-utils": "^2.0.0", "schema-utils": "^3.0.0" - }, - "dependencies": { - "loader-utils": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz", - "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==", - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^2.1.2" - } - } } }, "fill-range": { @@ -2371,6 +2394,14 @@ } } }, + "hashish": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/hashish/-/hashish-0.0.4.tgz", + "integrity": "sha1-bWC8b/r3Ebav1g5CbQd5iAFOZVQ=", + "requires": { + "traverse": ">=0.2.4" + } + }, "hosted-git-info": { "version": "2.8.8", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz", @@ -2676,6 +2707,12 @@ "is-extglob": "^2.1.1" } }, + "is-in-browser": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/is-in-browser/-/is-in-browser-1.1.3.tgz", + "integrity": "sha1-Vv9NtoOgeMYILrldrX3GLh0E+DU=", + "dev": true + }, "is-negative-zero": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.0.tgz", @@ -2889,6 +2926,17 @@ "verror": "1.10.0" } }, + "jss": { + "version": "9.8.7", + "resolved": "https://registry.npmjs.org/jss/-/jss-9.8.7.tgz", + "integrity": "sha512-awj3XRZYxbrmmrx9LUSj5pXSUfm12m8xzi/VKeqI1ZwWBtQ0kVPTs3vYs32t4rFw83CgFDukA8wKzOE9sMQnoQ==", + "dev": true, + "requires": { + "is-in-browser": "^1.1.3", + "symbol-observable": "^1.1.0", + "warning": "^3.0.0" + } + }, "killable": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/killable/-/killable-1.0.1.tgz", @@ -2951,6 +2999,17 @@ "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.1.0.tgz", "integrity": "sha512-oR4lB4WvwFoC70ocraKhn5nkKSs23t57h9udUgw8o0iH8hMXeEoRuUgfcvgUwAJ1ZpRqBvcou4N2SMvM1DwMrA==" }, + "loader-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz", + "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==", + "dev": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + } + }, "locate-path": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", @@ -2969,6 +3028,15 @@ "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.7.0.tgz", "integrity": "sha512-i2sY04nal5jDcagM3FMfG++T69GEEM8CYuOfeOIvmXzOIcwE9a/CJPR0MFM97pYMj/u10lzz7/zd7+qwhrBTqQ==" }, + "loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dev": true, + "requires": { + "js-tokens": "^3.0.0 || ^4.0.0" + } + }, "loud-rejection": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", @@ -3042,6 +3110,12 @@ "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" }, + "microbuffer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/microbuffer/-/microbuffer-1.0.0.tgz", + "integrity": "sha1-izgy7UDIfVH0e7I0kTppinVtGdI=", + "dev": true + }, "micromatch": { "version": "3.1.10", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", @@ -3648,6 +3722,12 @@ "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" }, + "pako": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", + "dev": true + }, "parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -4038,6 +4118,12 @@ "resolved": "https://registry.npmjs.org/reduce-flatten/-/reduce-flatten-2.0.0.tgz", "integrity": "sha512-EJ4UNY/U1t2P/2k6oqotuX2Cc3T6nxJwsM0N0asT7dhrtH1ltUxDn4NalSYmPE2rCkVpcf/X6R0wDwcFpzhd4w==" }, + "regenerator-runtime": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", + "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", + "dev": true + }, "regex-not": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", @@ -4081,6 +4167,14 @@ "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz", "integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==" }, + "remove": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/remove/-/remove-0.1.5.tgz", + "integrity": "sha1-CV/9gn1lyfQa2X0z5BanWBEHmVU=", + "requires": { + "seq": ">= 0.3.5" + } + }, "remove-trailing-separator": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", @@ -4355,6 +4449,15 @@ } } }, + "seq": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/seq/-/seq-0.3.5.tgz", + "integrity": "sha1-rgKvOkJHk9jMvyEtaRdODFTf/jg=", + "requires": { + "chainsaw": ">=0.0.7 <0.1", + "hashish": ">=0.0.2 <0.1" + } + }, "serialize-javascript": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz", @@ -4976,6 +5079,12 @@ "has-flag": "^3.0.0" } }, + "symbol-observable": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz", + "integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==", + "dev": true + }, "table": { "version": "5.4.6", "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", @@ -5124,6 +5233,11 @@ "punycode": "^2.1.1" } }, + "traverse": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.3.9.tgz", + "integrity": "sha1-cXuPIgzAu3tE5AUUwisui7xw2Lk=" + }, "trim-newlines": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", @@ -5142,6 +5256,29 @@ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" }, + "ttf-loader": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/ttf-loader/-/ttf-loader-1.0.2.tgz", + "integrity": "sha512-IMlcqjkSxqfOD4UpPrJ+LGm98JQ5URDFami19mR7lfjNR1XAEoG93Xd3loGYUMSxuhfzSTxsnLXu8emIawx/6A==", + "dev": true, + "requires": { + "babel-runtime": "^6.26.0", + "jss": "^9.5.1", + "ttf2woff": "^2.0.1", + "uuid": "^3.2.1" + } + }, + "ttf2woff": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ttf2woff/-/ttf2woff-2.0.2.tgz", + "integrity": "sha512-X68badwBjAy/+itU49scLjXUL094up+rHuYk+YAOTTBYSUMOmLZ7VyhZJuqQESj1gnyLAC2/5V8Euv+mExmyPA==", + "dev": true, + "requires": { + "argparse": "^1.0.6", + "microbuffer": "^1.0.0", + "pako": "^1.0.0" + } + }, "tunnel-agent": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", @@ -5336,6 +5473,15 @@ "extsprintf": "^1.2.0" } }, + "warning": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/warning/-/warning-3.0.0.tgz", + "integrity": "sha1-MuU3fLVy3kqwR1O9+IIcAe1gW3w=", + "dev": true, + "requires": { + "loose-envify": "^1.0.0" + } + }, "watchpack": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.0.1.tgz", diff --git a/package.json b/package.json index cc7c7f7..86712f1 100644 --- a/package.json +++ b/package.json @@ -15,11 +15,13 @@ "author": "Arne van Iterson", "license": "GPL-3.0-or-later", "dependencies": { + "@fortawesome/fontawesome-free": "^5.15.1", + "cookie-storage": "^6.1.0", "css-loader": "^5.0.1", "eslint": "^7.12.1", - "file-loader": "^6.2.0", "jquery": "^3.5.1", "node-sass": "^5.0.0", + "remove": "^0.1.5", "sass": "^1.29.0", "sass-loader": "^10.0.5", "socket.io-client": "^3.0.0", @@ -27,5 +29,9 @@ "webpack": "^5.4.0", "webpack-cli": "^4.2.0", "webpack-dev-server": "^3.11.0" + }, + "devDependencies": { + "file-loader": "^6.2.0", + "ttf-loader": "^1.0.2" } } diff --git a/res/fonts/alarm clock.ttf b/res/fonts/alarm clock.ttf new file mode 100644 index 0000000000000000000000000000000000000000..9e9b5934595209c8a8d22dde952554c91115e50e GIT binary patch literal 21664 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 K_QCFSMEGx{j(KMQ literal 0 HcmV?d00001 diff --git a/scss/index.scss b/scss/index.scss index 228cb45..f6824c8 100644 --- a/scss/index.scss +++ b/scss/index.scss @@ -1,15 +1,19 @@ +@font-face { + font-family: "Alarm Clock"; + src: url("../res/fonts/alarm\ clock.ttf") format("truetype"), +} + body { font-family: monospace; padding: 2em; margin: 0; background-color: #111111; color: white; - // * { - // border: 1px solid white; - // } + h1 { text-align: center; } + div#main { height: 100%; width: max-content; @@ -17,17 +21,22 @@ body { grid-template-columns: auto auto; column-gap: 1em; margin: 0 auto; + div { padding: 1em; + margin-bottom: 1em; border-radius: 0.25em; background-color: #212121; - &#board { + display: block; + + div#board { text-align: center; width: min-content; display: grid; - grid-template-columns: auto auto auto auto auto auto auto auto auto auto auto auto auto auto auto; column-gap: 3px; row-gap: 3px; + margin-bottom: 0; + span.cell { color: white; text-align: center; @@ -37,47 +46,84 @@ body { border-radius: 0.1em; background-color: #303030; font-size: large; + &.discovered { background-color: #424242; } + &.bomb { background-color: #FC5130; } + &.flag { background-color: #51CB20; } } } - &#log { - font-size: 12px; - width: 20vw; - h2 { - text-align: center; + } + + div:nth-of-type(2) { + min-width: 300px; + + div { + margin-bottom: 0; + + &#time { + span { + margin: 0 auto; + display: block; + text-align: center; + font-size: 5em; + font-family: "Alarm Clock"; + } } - span { - display: block; - width: 100%; - color: darkgray; - padding-bottom: 0.5em; - &.error { - color: red; - } - &.alert { - color: orange; - } - &.success { - color: cyan; + + &#register { + display: none; + } + + &#log { + display: none; + font-size: 12px; + + div { + max-height: 23rem; + overflow: auto; + + span { + display: block; + width: 100%; + color: darkgray; + padding-bottom: 0.5em; + + &.error { + color: red; + } + + &.alert { + color: orange; + } + + &.success { + color: cyan; + } + } } } } } } + footer { - position: absolute; - bottom: 1em; + position: sticky; + bottom: 0; left: 1em; color: darkgray; height: 1em; + background: #111111; + width: 100%; + padding: 1em; + a { color: white; } diff --git a/src/helpers/log.js b/src/helpers/log.js index da702c7..72b2700 100644 --- a/src/helpers/log.js +++ b/src/helpers/log.js @@ -1,8 +1,11 @@ function log(message, type) { var child = document.createElement("span"); - child.innerHTML = "- " + message; + child.innerHTML = "- " + String(message); child.className = type; - document.getElementById("log").appendChild(child); + + var log = document.querySelectorAll("div#log > div")[0]; + log.appendChild(child); + log.scrollTo(0, log.scrollHeight); } export default log; \ No newline at end of file diff --git a/src/helpers/multiplayer.js b/src/helpers/multiplayer.js index f2d6b3c..4281e87 100644 --- a/src/helpers/multiplayer.js +++ b/src/helpers/multiplayer.js @@ -1,7 +1,12 @@ /* eslint-disable no-unused-vars */ import io from "socket.io-client"; +import { + CookieStorage +} from "cookie-storage"; import log from "./log.js"; +const cookie = new CookieStorage(); + class Multiplayer { constructor() { // Keep local and external players @@ -9,23 +14,43 @@ class Multiplayer { this.connected = false; this.game; + this.cookie = cookie.getItem("ms99_usr"); + if (this.cookie != null) { + log(`Using previous username ${this.cookie}, delete cookies for this site to reset.`, "alert"); + this.connect(this.cookie); + } else { + this.register(); + } + } + + connect(username) { + // Show gamelog + document.querySelectorAll("div#log")[0].style.display = "block"; + // Connect to TanksJS-Server instance log("Connecting to server..."); - this.socket = io("http://localhost:3000"); + this.socket = io("http://localhost:3000/", { + reconnection: false + }); + + this.socket.on("connect_error", err => this.handleError(err)); + this.socket.on("connect_failed", err => this.handleError(err)); + this.socket.on("disconnect", err => this.handleError(err)); + this.socket.on("identify", () => { this.socket.emit("identification", { - name: "Arn", + name: username, playersMax: 2, gameID: "ms99" }); - log(`Connected to server as ${this.socket.id}`, "success"); + log(`Connected to server as ${username}`, "success"); + console.log(this.socket); this.connected = true; - this.game.active = true; }); // Handle player logins this.socket.on("roomUpdate", (data) => { - console.log("roomUpdate"); + console.log(data); // Add any player that is not the local player and is not already added for (const id in data) { if (id != this.socket.id && this.players.indexOf(id)) { @@ -47,15 +72,35 @@ class Multiplayer { // Handle player updates this.socket.on("update", (data) => { - console.log("update"); + console.log(data); }); // Start game this.socket.on("gameStart", () => { console.log("gameStart"); + this.game.active = true; }); } - + + register() { + var form = document.querySelectorAll("div#register > form")[0]; + form.parentElement.style.display = "block"; + form.addEventListener("submit", (e) => { + e.preventDefault(); + form.parentElement.style.display = "none"; + + var username = String(form.querySelector("input[name=username]").value); + if (form.querySelector("input[name=store]").checked) { + cookie.setItem("ms99_usr", username); + } + this.connect(username); + }); + } + + handleError(error) { + log(error, "error"); + } + setInstance(game) { this.game = game; log("Game instance initialized"); diff --git a/src/index.js b/src/index.js index 0340324..4f781e0 100644 --- a/src/index.js +++ b/src/index.js @@ -1,11 +1,31 @@ /* eslint-disable no-unused-vars */ import "../scss/index.scss"; +import "../node_modules/@fortawesome/fontawesome-free/scss/fontawesome.scss"; import log from "./helpers/log.js"; import Game from "./screens/game.js"; import Multiplayer from "./helpers/multiplayer.js"; + +["DOMContentLoaded", "resize"].forEach(evt => + window.addEventListener(evt, (e) => { + var main = document.getElementById("main"); + var info = main.children[1]; + + if (main.scrollWidth > window.innerWidth) { + main.style.display = "block"; + info.style.maxWidth = "unset"; + } else { + main.style.display = "grid"; + info.style.maxWidth = "350px"; + } + }) +); + var board = document.getElementById("board"); var mp = new Multiplayer(); var game = new Game(board); mp.setInstance(game); +window.setInterval(function () { + game.update(); +}, 1000); \ No newline at end of file diff --git a/src/screens/game.js b/src/screens/game.js index a28fef1..7744d12 100644 --- a/src/screens/game.js +++ b/src/screens/game.js @@ -5,16 +5,29 @@ class Game { constructor(element) { this.board = element; this.children = element.children; + this.colours = [ + "#B8E5E5", + "#A9C6E5", + "#A79AE6", + "#CE8BE7", + "#E97DC1", + "#EB6D6E", + "#ED9B5C", + "#ECED4C" + ]; this.active = false; - - this.sides = 15; + + this.sides = 20; this.size = Math.pow(this.sides, 2); + this.board.style.gridTemplateColumns = `repeat(${this.sides}, auto)`; this.generated = false; - this.bombAmount = 25; + this.bombAmount = 60; this.bombs = []; this.discovered = []; + + this.time = 60; this.strikes = 3; for (let cell = 0; cell < this.size; cell++) { @@ -23,7 +36,7 @@ class Game { var child = document.createElement("span"); child.className = "cell"; - + child.addEventListener("click", () => { this.discover(cell); }); @@ -35,20 +48,43 @@ class Game { this.board.appendChild(child); } + } - // for (let index = 0; index < this.bombAmount; index++) { - // var rand = math.default.rand(0, this.size); - // this.bombs[rand] = 1; - // } + update() { + if (this.active) { + if (this.time - 1 <= 0) { + this.gameOver(); + } else { + this.time--; + this.drawTime(); + } + } + } - console.log(this.bombs); - console.log(this.discovered); + drawTime() { + var minutes = 0; + + while (this.time - 60 - (minutes * 60) >= 0) { + minutes++; + } + var seconds = this.time - (minutes * 60); + + if (minutes < 10) { + minutes = String("0" + minutes); + } + + if (seconds < 10) { + seconds = String("0" + seconds); + } + + var timer = document.getElementById("time").children[1]; + timer.innerHTML = String(minutes + ":" + seconds); } discover(cell) { if (!this.generated) { this.generated = true; - + let index = 0; while (index < this.bombAmount) { var rand = math.default.rand(0, this.size); @@ -99,7 +135,7 @@ class Game { if (!limit.bottom) { surrounds.push(cell + this.sides + 1); } - } else if ((cell + 1) % this.sides === 0 ) { + } else if ((cell + 1) % this.sides === 0) { // Cell is on the right side of the map surrounds.push(cell - 1); if (!limit.top) { @@ -138,26 +174,37 @@ class Game { } }); } else { + this.children[cell].style.color = this.colours[value]; this.children[cell].innerHTML = String(value); } } } flag(cell) { - if (this.bombs[cell]) { - this.children[cell].innerHTML = "#"; - this.children[cell].classList.add("flag"); - this.bombAmount--; - log(`Correctly flagged. ${String(this.bombAmount)} bombs left!`); - } else { - if (this.strikes - 1 == 0) { - this.gameOver(); - return; + if (this.active) { + if (this.bombs[cell]) { + if (!this.discovered[cell]) { + this.discovered[cell] = 1; + this.children[cell].innerHTML = "#"; + this.children[cell].classList.add("flag"); + this.bombAmount--; + + this.time = this.time + 10; + this.drawTime(); + + if (this.bombAmount == 0) { + log("You have cleared all bombs!", "success"); + this.active = false; + } + } } else { - this.strikes--; - log(`Incorrectly flagged. ${String(this.strikes)} strikes left!`, "alert"); + if (!this.discovered[cell]) { + this.time = this.time - 30; + this.drawTime(); + + this.discover(cell); + } } - this.discover(cell); } } diff --git a/webpack.config.js b/webpack.config.js index 5cc658e..8dac062 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -1,15 +1,27 @@ module.exports = { module: { - rules: [{ - test: /\.s[ac]ss$/i, - use: [ - // Creates `style` nodes from JS strings - "style-loader", - // Translates CSS into CommonJS - "css-loader", - // Compiles Sass to CSS - "sass-loader", - ], - }, ] + rules: [ + { + test: /\.s[ac]ss$/i, + use: [ + // Creates `style` nodes from JS strings + "style-loader", + // Translates CSS into CommonJS + "css-loader", + // Compiles Sass to CSS + "sass-loader", + ], + }, + { + test: /\.(woff(2)?|ttf|eot|svg)(\?v=\d+\.\d+\.\d+)?$/, + use: [{ + loader: "file-loader", + options: { + name: "[name].[ext]", + outputPath: "res/fonts/" + } + }] + } + ] } }; \ No newline at end of file