The main game and server connections are working
This commit is contained in:
parent
4dc5ed358c
commit
c19f2dbcc3
35
.eslintrc.js
Normal file
35
.eslintrc.js
Normal file
@ -0,0 +1,35 @@
|
||||
module.exports = {
|
||||
"env": {
|
||||
"browser": true,
|
||||
"commonjs": true,
|
||||
"es6": true,
|
||||
"node": true
|
||||
},
|
||||
"extends": "eslint:recommended",
|
||||
"globals": {
|
||||
"Atomics": "readonly",
|
||||
"SharedArrayBuffer": "readonly"
|
||||
},
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 2018,
|
||||
"sourceType": "module",
|
||||
},
|
||||
"rules": {
|
||||
"indent": [
|
||||
"error",
|
||||
4
|
||||
],
|
||||
"linebreak-style": [
|
||||
"error",
|
||||
"unix"
|
||||
],
|
||||
"quotes": [
|
||||
"error",
|
||||
"double"
|
||||
],
|
||||
"semi": [
|
||||
"error",
|
||||
"always"
|
||||
]
|
||||
}
|
||||
};
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -106,4 +106,5 @@ dist
|
||||
|
||||
# Stores VSCode versions used for testing VSCode extensions
|
||||
.vscode-test
|
||||
*.code-workspace
|
||||
|
||||
|
27
html/index.html
Normal file
27
html/index.html
Normal file
@ -0,0 +1,27 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Minesweeper 99</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1><i class="fas fa-bomb"></i>Minesweeper 99</h1>
|
||||
|
||||
<div id="main">
|
||||
<div id="board">
|
||||
<!-- Renderer will push content here -->
|
||||
</div>
|
||||
|
||||
<div id="log">
|
||||
<h2>Gamelog</h2>
|
||||
<!-- Game log will be pushed here -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="/main.js"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
5970
package-lock.json
generated
Normal file
5970
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
31
package.json
Normal file
31
package.json
Normal file
@ -0,0 +1,31 @@
|
||||
{
|
||||
"name": "minesweeper",
|
||||
"version": "1.0.0",
|
||||
"description": "Real actual competitive minesweeper in Node.JS. Flagging a mine correctly will send it to one of the other players.",
|
||||
"main": "src/index.js",
|
||||
"scripts": {
|
||||
"start": "webpack serve",
|
||||
"lint": "eslint .",
|
||||
"build": "webpack"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://gitea.arnweb.nl/arne/minesweeper.git"
|
||||
},
|
||||
"author": "Arne van Iterson",
|
||||
"license": "GPL-3.0-or-later",
|
||||
"dependencies": {
|
||||
"css-loader": "^5.0.1",
|
||||
"eslint": "^7.12.1",
|
||||
"file-loader": "^6.2.0",
|
||||
"jquery": "^3.5.1",
|
||||
"node-sass": "^5.0.0",
|
||||
"sass": "^1.29.0",
|
||||
"sass-loader": "^10.0.5",
|
||||
"socket.io-client": "^3.0.0",
|
||||
"style-loader": "^2.0.0",
|
||||
"webpack": "^5.4.0",
|
||||
"webpack-cli": "^4.2.0",
|
||||
"webpack-dev-server": "^3.11.0"
|
||||
}
|
||||
}
|
69
scss/index.scss
Normal file
69
scss/index.scss
Normal file
@ -0,0 +1,69 @@
|
||||
body {
|
||||
font-family: 'Courier New', Courier, monospace;
|
||||
background: #121212;
|
||||
color: lightgray;
|
||||
// * {
|
||||
// border: 1px solid white;
|
||||
// }
|
||||
h1 {
|
||||
text-align: center;
|
||||
}
|
||||
div#main {
|
||||
height: 100%;
|
||||
width: max-content;
|
||||
display: grid;
|
||||
grid-template-columns: auto auto;
|
||||
column-gap: 1em;
|
||||
margin: 0 auto;
|
||||
div {
|
||||
padding: 1em;
|
||||
border-radius: 0.75em;
|
||||
background-color: #1E1E1E;
|
||||
&#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: 0.25em;
|
||||
row-gap: 0.25em;
|
||||
span.cell {
|
||||
border: 1px solid grey;
|
||||
color: lightgray;
|
||||
text-align: center;
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
padding: 0.5em;
|
||||
border-radius: 0.25em;
|
||||
&.discovered {
|
||||
background-color: #5c5c5c;
|
||||
}
|
||||
&.bomb {
|
||||
background-color: #5e3030;
|
||||
}
|
||||
}
|
||||
}
|
||||
&#log {
|
||||
font-size: 12px;
|
||||
width: 20vw;
|
||||
h2 {
|
||||
text-align: center;
|
||||
}
|
||||
span {
|
||||
display: block;
|
||||
width: 100%;
|
||||
color: darkgray;
|
||||
padding-bottom: 0.5em;
|
||||
&.error {
|
||||
color: red;
|
||||
}
|
||||
&.alert {
|
||||
color: orange;
|
||||
}
|
||||
&.success {
|
||||
color: cyan;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
8
src/helpers/log.js
Normal file
8
src/helpers/log.js
Normal file
@ -0,0 +1,8 @@
|
||||
function log(message, type) {
|
||||
var child = document.createElement("span");
|
||||
child.innerHTML = "- " + message;
|
||||
child.className = type;
|
||||
document.getElementById("log").appendChild(child);
|
||||
}
|
||||
|
||||
export default log;
|
65
src/helpers/multiplayer.js
Normal file
65
src/helpers/multiplayer.js
Normal file
@ -0,0 +1,65 @@
|
||||
/* eslint-disable no-unused-vars */
|
||||
import io from "socket.io-client";
|
||||
import log from "./log.js";
|
||||
|
||||
class Multiplayer {
|
||||
constructor() {
|
||||
// Keep local and external players
|
||||
this.players = [];
|
||||
this.connected = false;
|
||||
this.game;
|
||||
|
||||
// Connect to TanksJS-Server instance
|
||||
log("Connecting to server...");
|
||||
this.socket = io("http://localhost:3000");
|
||||
this.socket.on("identify", () => {
|
||||
this.socket.emit("identification", {
|
||||
name: "Arn",
|
||||
playersMax: 2,
|
||||
gameID: "ms99"
|
||||
});
|
||||
log(`Connected to server as ${this.socket.id}`, "success");
|
||||
this.connected = true;
|
||||
this.game.active = true;
|
||||
});
|
||||
|
||||
// Handle player logins
|
||||
this.socket.on("roomUpdate", (data) => {
|
||||
console.log("roomUpdate");
|
||||
// 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)) {
|
||||
console.log(id);
|
||||
this.players.push(id);
|
||||
console.log(this.players);
|
||||
}
|
||||
}
|
||||
|
||||
// Remove any player that disconnects from the game
|
||||
for (const id in this.players) {
|
||||
if (data[id] == undefined) {
|
||||
var index = this.players.indexOf(id);
|
||||
this.players.splice(index, 1);
|
||||
console.log(this.players);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Handle player updates
|
||||
this.socket.on("update", (data) => {
|
||||
console.log("update");
|
||||
});
|
||||
|
||||
// Start game
|
||||
this.socket.on("gameStart", () => {
|
||||
console.log("gameStart");
|
||||
});
|
||||
}
|
||||
|
||||
setInstance(game) {
|
||||
this.game = game;
|
||||
log("Game instance initialized");
|
||||
}
|
||||
}
|
||||
|
||||
export default Multiplayer;
|
11
src/index.js
Normal file
11
src/index.js
Normal file
@ -0,0 +1,11 @@
|
||||
/* eslint-disable no-unused-vars */
|
||||
import "../scss/index.scss";
|
||||
import log from "./helpers/log.js";
|
||||
import Game from "./screens/game.js";
|
||||
import Multiplayer from "./helpers/multiplayer.js";
|
||||
|
||||
var board = document.getElementById("board");
|
||||
var mp = new Multiplayer();
|
||||
var game = new Game(board);
|
||||
mp.setInstance(game);
|
||||
|
133
src/screens/game.js
Normal file
133
src/screens/game.js
Normal file
@ -0,0 +1,133 @@
|
||||
import * as math from "../utilities/math.js";
|
||||
import log from "../helpers/log.js";
|
||||
|
||||
class Game {
|
||||
constructor(element) {
|
||||
this.board = element;
|
||||
this.children = element.children;
|
||||
|
||||
this.active = false;
|
||||
|
||||
this.sides = 15;
|
||||
this.size = Math.pow(this.sides, 2);
|
||||
this.bombAmount = 35;
|
||||
this.bombs = [];
|
||||
this.discovered = [];
|
||||
|
||||
for (let cell = 0; cell < this.size; cell++) {
|
||||
this.bombs.push(0);
|
||||
this.discovered.push(0);
|
||||
|
||||
var child = document.createElement("span");
|
||||
child.className = "cell";
|
||||
|
||||
child.addEventListener("click", () => {
|
||||
this.discover(cell);
|
||||
});
|
||||
|
||||
this.board.appendChild(child);
|
||||
}
|
||||
|
||||
for (let index = 0; index < this.bombAmount; index++) {
|
||||
var rand = math.default.rand(0, this.size);
|
||||
this.bombs[rand] = 1;
|
||||
}
|
||||
|
||||
console.log(this.bombs);
|
||||
console.log(this.discovered);
|
||||
}
|
||||
|
||||
discover(cell) {
|
||||
if (this.active && !this.discovered[cell]) {
|
||||
this.discovered[cell] = 1;
|
||||
this.children[cell].classList.add("discovered");
|
||||
|
||||
if (this.bombs[cell]) {
|
||||
log("Game over", "error");
|
||||
this.active = false;
|
||||
for (let index = 0; index < this.size; index++) {
|
||||
if (this.bombs[index]) {
|
||||
this.children[index].innerHTML = "[]";
|
||||
this.children[index].classList.add("bomb");
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
var surrounds = [];
|
||||
var limit = {
|
||||
top: true,
|
||||
bottom: true
|
||||
};
|
||||
|
||||
if (!(cell - this.sides < 0)) {
|
||||
// Cell is not on top of the map
|
||||
limit.top = false;
|
||||
surrounds.push(
|
||||
cell - this.sides
|
||||
);
|
||||
}
|
||||
|
||||
if (!(cell + this.sides > this.size - 1)) {
|
||||
// Cell is not on the bottom of the map
|
||||
limit.bottom = false;
|
||||
surrounds.push(
|
||||
cell + this.sides
|
||||
);
|
||||
}
|
||||
|
||||
if (cell % this.sides === 0) {
|
||||
// Cell is on the left side of the map
|
||||
surrounds.push(cell + 1);
|
||||
if (!limit.top) {
|
||||
surrounds.push(cell - this.sides + 1);
|
||||
}
|
||||
if (!limit.bottom) {
|
||||
surrounds.push(cell + this.sides + 1);
|
||||
}
|
||||
} else if ((cell + 1) % this.sides === 0 ) {
|
||||
// Cell is on the right side of the map
|
||||
surrounds.push(cell - 1);
|
||||
if (!limit.top) {
|
||||
surrounds.push(cell - this.sides - 1);
|
||||
}
|
||||
if (!limit.bottom) {
|
||||
surrounds.push(cell + this.sides - 1);
|
||||
}
|
||||
} else {
|
||||
// Cell is not on either sides of the map
|
||||
surrounds.push(cell - 1);
|
||||
surrounds.push(cell + 1);
|
||||
if (!limit.top) {
|
||||
surrounds.push(cell - this.sides - 1);
|
||||
surrounds.push(cell - this.sides + 1);
|
||||
}
|
||||
if (!limit.bottom) {
|
||||
surrounds.push(cell + this.sides - 1);
|
||||
surrounds.push(cell + this.sides + 1);
|
||||
}
|
||||
}
|
||||
|
||||
var value = 0;
|
||||
surrounds.forEach((number) => {
|
||||
if (number != cell) {
|
||||
if (this.bombs[number]) {
|
||||
value++;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (value == 0) {
|
||||
surrounds.forEach((number) => {
|
||||
if (number != cell) {
|
||||
this.discover(number);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
this.children[cell].innerHTML = String(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default Game;
|
48
src/utilities/math.js
Normal file
48
src/utilities/math.js
Normal file
@ -0,0 +1,48 @@
|
||||
function angle(a, b) {
|
||||
const dx = a.x - b.x;
|
||||
const dy = a.y - b.y;
|
||||
const angle = Math.atan2(dy, dx);
|
||||
|
||||
return angle;
|
||||
}
|
||||
|
||||
function clamp(x, min, max) {
|
||||
return Math.max(min, Math.min(x, max));
|
||||
}
|
||||
|
||||
function distance(a, b) {
|
||||
const dx = a.x - b.x;
|
||||
const dy = a.y - b.y;
|
||||
|
||||
return Math.sqrt(dx * dx + dy * dy);
|
||||
}
|
||||
|
||||
function rand(min, max) {
|
||||
return Math.floor(randf(min, max));
|
||||
}
|
||||
|
||||
function randf(min, max) {
|
||||
if (max == null) {
|
||||
max = min || 1;
|
||||
min = 0;
|
||||
}
|
||||
return Math.random() * (max - min) + min;
|
||||
}
|
||||
|
||||
function randOneFrom(items) {
|
||||
return items[rand(items.length)];
|
||||
}
|
||||
|
||||
function randOneIn(max = 2) {
|
||||
return rand(0, max) === 0;
|
||||
}
|
||||
|
||||
export default {
|
||||
angle,
|
||||
clamp,
|
||||
distance,
|
||||
rand,
|
||||
randf,
|
||||
randOneFrom,
|
||||
randOneIn
|
||||
};
|
15
webpack.config.js
Normal file
15
webpack.config.js
Normal file
@ -0,0 +1,15 @@
|
||||
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",
|
||||
],
|
||||
}, ]
|
||||
}
|
||||
};
|
Loading…
Reference in New Issue
Block a user