From e19453dc6634606764c11f53d8524f5d464ce4a9 Mon Sep 17 00:00:00 2001 From: Flummi Date: Wed, 8 Aug 2018 16:56:34 +0200 Subject: [PATCH] =?UTF-8?q?msgbox=20und=20ein=20Haufen=20M=C3=BCll?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/index.mjs | 39 ++++++++--- src/static/{ => css}/main.css | 66 +++++++++++++++++- src/static/css/msgbox.css | 90 ++++++++++++++++++++++++ src/static/index.html | 124 +++++++++++++++++++--------------- src/static/js/events.js | 23 +++---- src/static/js/main.js | 37 +++++++--- src/static/js/render.js | 23 +++++-- src/static/js/socket.js | 45 ++++++++++++ src/static/js/tpl.js | 96 +++++++++++++++++++++++++- 9 files changed, 444 insertions(+), 99 deletions(-) rename src/static/{ => css}/main.css (79%) create mode 100644 src/static/css/msgbox.css create mode 100644 src/static/js/socket.js diff --git a/src/index.mjs b/src/index.mjs index fcd9405..6849646 100644 --- a/src/index.mjs +++ b/src/index.mjs @@ -1,35 +1,34 @@ import cfg from "./cfg"; import express from "express"; +import repl from "repl"; import http from "http"; import sio from "socket.io"; import path from "path"; -let deck = [ +let deck = () => [ ...[...Array(12)].map((_, i) => new Array(12).fill(++i)).reduce((a,b)=>[...b,...a]) , ...[...Array(18).fill(13)] ].map(a => [Math.random(), a]).sort((a, b) => a[0] - b[0]).map(a => a[1]); -const player = new Map(); +//const player = new Map(); +const rooms = new Map(); function cards() { this.hand = []; this.pile = Array(cfg.iters.pile); this.stock = []; } -//player.set("Spieler 1", new cards); -//player.set("Spieler 2", new cards); - const fillHand = _player => { _player = player.get(_player); _player.hand.push(...deck.splice(0, cfg.iters.hand - _player.hand.length)); _player.hand.sort((a,b)=>a>b); }; -const begin = () => { +/*const begin = () => { player.forEach((cards, _player) => { fillHand(_player); //cards.stock.push(...deck.splice(0, cfg.iters.stock - cards.stock.length)); }); }; -begin(); +begin();*/ const app = express(); const server = http.Server(app); @@ -40,9 +39,29 @@ server.listen(8080); app .use(express.static(path.resolve("src", "static"))) + io.on("connection", socket => { - socket.on("player", data => { - console.log(data); + socket.emit("auth"); // initial ping + socket.on("test", blah => { + console.log(blah); + io.in(socket.room).emit("test", blah); + }); + socket.on("player", data => { // playername, roomname + socket.playername = data.playername; + socket.room = data.roomname; + + socket.join(data.roomname); + + if(!rooms.has(data.roomname)) { + rooms.set(data.roomname, { + player: new Map(Object.entries({ [data.playername]: { cards: new cards }})), + mainstack: deck() + }); + } + console.log(rooms); + socket.emit("done"); }); -}); \ No newline at end of file +}); + +//repl.start("> "); \ No newline at end of file diff --git a/src/static/main.css b/src/static/css/main.css similarity index 79% rename from src/static/main.css rename to src/static/css/main.css index c918b44..20d29c2 100644 --- a/src/static/main.css +++ b/src/static/css/main.css @@ -1,6 +1,7 @@ html, body { height: 100%; min-height: 100%; + background-color: rgb(18, 153, 0); } * { margin: 0; @@ -14,7 +15,21 @@ html, body { #debug { position: absolute; bottom: 0; - z-index: 999; + z-index: 2; +} +#log { + position: fixed; + top: 50%; + left: 10px; + border: 1px solid #000; + background-color: #fff; + height: 50%; + width: 400px; + transform: translateY(-50%); + white-space: pre; + overflow-y: scroll; + z-index: 2; + display: none; } .player { @@ -203,7 +218,7 @@ html, body { #spielfeld { height: 100vh; - background-color: rgb(18, 153, 0); + } #player { @@ -254,4 +269,51 @@ html, body { } #player1_pile { grid-area: c; +} + + +#layer_game { + display: block; +} + +div#black { + position: fixed; + top: 0; + left: 0; + height: 100%; + width: 100%; + margin: 0; + padding: 0; + background-color: rgba(0,0,0,0.8); + z-index: 100; +} + +div#menu { + z-index: 101; + border: 1px solid #000; + border-radius: 10px; + display: grid; + grid-template-columns: 1fr 1fr; + grid-template-rows: auto 1fr; + grid-template-areas: "head head" "left right"; + height: 300px; + width: 400px; + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + background-color: #fff; +} +div#menu_title { + grid-area: head; + text-align: center; + border-bottom: 1px solid #000; +} +div.menu_new { + grid-area: left; + border: 1px dotted #000; +} +div.menu_join { + grid-area: right; + border: 1px dotted #000; } \ No newline at end of file diff --git a/src/static/css/msgbox.css b/src/static/css/msgbox.css new file mode 100644 index 0000000..e3ef820 --- /dev/null +++ b/src/static/css/msgbox.css @@ -0,0 +1,90 @@ +div.msgBox { + position: fixed; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + + padding: 4px 10px 4px 10px; + position: fixed; + z-index: 9999999; + width: 430px; + min-height: 160px; + color: #00335e; + border-radius: 6px; + box-shadow: 0px 0px 11px #000; + background-color: #fff; +} + +div.msgBoxTitle { + padding: 5px 0 5px 0; + font-variant: small-caps; + font-size: 16pt; + font-weight: lighter; + color: #00335e; + width: 100%; + border-bottom: 1px solid #002c5f; +} + +div.msgBoxButtons { + display: inline-block; + width: 100%; + text-align: right; +} + +div.msgBoxButtons input[type='button'] { + cursor: pointer; + margin: 2px; + height: 35px; + width: 90px; + border: 1px solid #afafaf; + background-color: #004076; + color: #fff; + border-radius: 6px; + outline: none; +} + +div.msgBoxButtons input[type='button']:hover { + background-color: #00549c; + color: #fff; +} + +div.msgBoxButtons input[type='button']:active { + background-color: #aaa; + color: #fff; +} + +div.msgBoxButtons input[type='button']:focus { + outline: none; + border: solid 2px #fc6; +} + +div.msgBoxInputs { + margin: 0 auto; + padding-top: 2px; + padding-bottom: 2px; + margin-top: 5px; + width: 195px; +} + +div.msgInput input[type='text'], div.msgInput input[type='password'] { + padding: 4px; + border: 1px solid #dfdfdf; + color: #2f2f2f; + width: 180px; +} + +div.msgBoxContent { + font-size: 11pt; + margin: 0 3px 6px 3px; + display: inline-block; + height: 100%; + width: 100%; +} +div.msgBoxContentTableRow { + display: table-row; + width: 100%; +} +div.msgBoxContentTableCell { + display: table-cell; + width: 50%; +} \ No newline at end of file diff --git a/src/static/index.html b/src/static/index.html index 13317d5..527abc8 100644 --- a/src/static/index.html +++ b/src/static/index.html @@ -1,68 +1,82 @@ - + + -
- new card - + -
-
-
-
Spieler 2
-
-
-
-
-
-
-
-
-
-
Spieler 3
-
-
-
-
-
-
-
-
+
+
+
+ new card +
-
-
-
-
-
-
+
+
+
+
+
Spieler 2
+
+
+
+
+
+
+
+
+
+
Spieler 3
+
+
+
+
+
+
+
+
-
-
-
Spieler 1
- -
-
-
-
-
-
+
+
+
+
+
+
+
+
+
Spieler 1
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+ +
+
+
+
+
+
+
+
diff --git a/src/static/js/events.js b/src/static/js/events.js index dd62ae7..477fc7c 100644 --- a/src/static/js/events.js +++ b/src/static/js/events.js @@ -2,6 +2,7 @@ import * as render from "./render.js"; let debug = true; let activeElement, droptimer; let dropto = null; +let log = document.querySelector("#log"); const allowDrop = e => { if(debug) console.log("dropover"); @@ -21,9 +22,9 @@ const dragEnd = e => { if(debug) console.log("dragend"); e.preventDefault(); if(dropto !== null) { - const [pstack, , , ppileid] = activeElement.parentNode.id.split("_"); + const [pstack, ptype, , ppileid] = activeElement.parentNode.id.split("_"); const [mstack, , , mpileid] = dropto.id.split("_"); - const pile = render.stackables.getID(parseInt(pstack.slice(-1))).pile[ppileid]; + const pile = render.stackables.getID(parseInt(pstack.slice(-1)))[ptype][ppileid]; let from = pile.splice(-1)[0]; let to = render.mainstack[mpileid]; let last = to[to.length - 1] || { val: 0 }; @@ -35,12 +36,12 @@ const dragEnd = e => { if(last.val + 1 === 12) render.mainstack[mpileid].length = 0; // clear stack + + log.innerHTML += `from: ${pstack}_${ptype}_${ppileid} (${from.val}) to: ${mstack}_slot_${mpileid} (${last.val})\n`; + log.scrollTop = log.scrollHeight; render.render(render.stackables.getName(parseInt(pstack.slice(-1)))); render.renderMain(); - - //dropto.insertAdjacentHTML("beforeend", `
${activeElement.innerHTML}
`); - //activeElement.parentNode.removeChild(activeElement); } activeElement.style.display = "block"; activeElement = null; @@ -58,16 +59,8 @@ const dragenter = e => { const dragleave = e => { if(debug) console.log("dragleave"); e.preventDefault(); - removeOver(); - droptimer = setTimeout(() => { - dropto = null; - }, 100); -}; - -const removeOver = () => { - document.querySelectorAll("div[dropable='true']").forEach(slot => { - slot.classList.remove("over"); - }); + document.querySelectorAll("div[dropable='true']").forEach(slot => slot.classList.remove("over")); + droptimer = setTimeout(() => dropto = null, 100); }; document.querySelectorAll("div[dropable='true']").forEach(slot => { diff --git a/src/static/js/main.js b/src/static/js/main.js index 410c9d5..cc04173 100644 --- a/src/static/js/main.js +++ b/src/static/js/main.js @@ -1,7 +1,6 @@ import * as render from "./render.js"; -//import { render, renderAll, stackables, mainstack } from "./render.js"; -//import events from "./events.js"; -//const socket = io(); +import { tpl, msgBox } from "./tpl.js"; +//let socket = io(); function card({ type = "normal", val = "" }) { this.type = type; @@ -14,13 +13,25 @@ function player(id) { this.stock = []; } -render.stackables.set("P1", new player(1)); +/*render.stackables.set("P1", new player(1)); render.stackables.get("P1").pile[0].push(new card({ val: 12 })); render.stackables.get("P1").pile[1].push(new card({ val: 11 })); render.stackables.get("P1").pile[2].push(new card({ val: 2 })); render.stackables.get("P1").pile[2].push(new card({ val: 1 })); render.stackables.get("P1").pile[2].push(new card({ type: "joker" })); +render.stackables.get("P1").hand[0].push(new card({ val: 12 })); +render.stackables.get("P1").hand[1].push(new card({ type: "joker" })); +render.stackables.get("P1").hand[1].push(new card({ type: "joker" })); +render.stackables.get("P1").hand[1].push(new card({ type: "joker" })); +render.stackables.get("P1").hand[1].push(new card({ type: "joker" })); +render.stackables.get("P1").hand[1].push(new card({ type: "joker" })); +render.stackables.get("P1").hand[1].push(new card({ type: "joker" })); +render.stackables.get("P1").hand[1].push(new card({ type: "joker" })); +render.stackables.get("P1").hand[1].push(new card({ type: "joker" })); +render.stackables.get("P1").hand[1].push(new card({ type: "joker" })); +render.stackables.get("P1").hand[1].push(new card({ type: "joker" })); + render.stackables.set("P2", new player(2)); render.stackables.get("P2").pile[0].push(new card({ type: "joker", val: 12 })); render.stackables.get("P2").pile[1].push(new card({ val: 3 })); @@ -30,16 +41,26 @@ render.stackables.get("P2").pile[2].push(new card({ val: 12 })); render.stackables.set("P3", new player(3)); render.stackables.get("P3").pile[2].push(new card({ val: 5 })); -render.mainstack[1].push(new card({ val: 10 })); +render.mainstack[1].push(new card({ val: 10 }));*/ render.renderAll(); document.querySelector("#debug > #newcard").addEventListener("click", () => { const selcard = document.querySelector("#debug > #selcard"); const selindex = selcard.selectedIndex; const selval = selcard.options[selindex].textContent; - render.stackables.get("Test").pile[0].push(new card({ - val: selval === "Skip-Bo" ? "" : selval, + render.stackables.get("P1").pile[0].push(new card({ + val: selval === "Skip-Bo" ? "" : parseInt(selval), type: selval === "Skip-Bo" ? "joker" : "normal" })); - render.render("Test"); + render.render("P1"); }); + +//console.log(msgBox("joinGame")); +//console.log(msgBox("newGame")); + +document.querySelector("#menu button.menu_new").addEventListener("click", () => { + msgBox("newGame"); +}); +document.querySelector("#menu button.menu_join").addEventListener("click", () => { + msgBox("joinGame"); +}); \ No newline at end of file diff --git a/src/static/js/render.js b/src/static/js/render.js index 3d2ea4f..c2894c8 100644 --- a/src/static/js/render.js +++ b/src/static/js/render.js @@ -1,22 +1,23 @@ -import tpl from "./tpl.js"; +import { tpl } from "./tpl.js"; import events from "./events.js"; export let stackables = new Map(); export let mainstack = Array(4).fill().map(()=>[]); -export const clear = player => { +const clear = player => { const _player = stackables.get(player); _player.pile.forEach((slots, slotid) => { document.querySelector(`#player${_player.id}_pile_slot_${slotid}`).innerHTML = ""; }); + if(_player.id === 1) { + _player.hand.forEach((slots, slotid) => { + document.querySelector(`#player${_player.id}_hand_slot_${slotid}`).innerHTML = ""; + }); + } }; const clearMain = () => { mainstack.forEach((cards, slotid) => document.querySelector(`#mainstock_pile_slot_${slotid}`).innerHTML = ""); }; -export const clearAll = () => { - clearMain(); - stackables.forEach((e, player) => clear(player)); -}; export const render = player => { console.log(`render ${player}`); @@ -30,6 +31,15 @@ export const render = player => { ); }); }); + if(_player.hand) { + _player.hand.forEach((slots, slotid) => { + slots.forEach(card => { + document.querySelector(`#player${_player.id}_hand_slot_${slotid}`).insertAdjacentHTML("beforeend", + [{ val: card.val, draggable: _player.id === 1 }].map(card.type === "joker" ? tpl.joker : tpl.card).join`` + ); + }); + }); + } events.createCardEvents(); }; export const renderMain = () => { @@ -44,7 +54,6 @@ export const renderMain = () => { }); }; export const renderAll = () => { - //clearAll(); stackables.forEach((e, player) => render(player)); renderMain(); }; diff --git a/src/static/js/socket.js b/src/static/js/socket.js new file mode 100644 index 0000000..c81cb83 --- /dev/null +++ b/src/static/js/socket.js @@ -0,0 +1,45 @@ +let socket = false; +let _playername; +let _roomname; + +export const connect = ({ playername, roomname = "default" }) => { + // checks + if(playername < 3 || roomname < 3) + return false; + + [_playername, _roomname] = [playername, roomname]; + socket = io(); + socketevents(); +}; + +const socketevents = () => { + socket.on("auth", () => { + + }); +}; + +/*const socketevents = () => { + socket.on("auth", () => { + socket.emit("player", { + roomname: _roomname, + playername: _playername + }); + }); + socket.on("done", () => { + socket.emit("test", "lul"); + }); + socket.on("test", blah => { + console.log(blah); + }); +}; + +export const connect = ({ playername, roomname = "default" }) => { + [_playername, _roomname] = [playername, roomname]; + if(!socket) + socket = io(); + else { + socket.disconnect(true); + socket = io(); + } + socketevents(); +};*/ \ No newline at end of file diff --git a/src/static/js/tpl.js b/src/static/js/tpl.js index 85a11ff..ce9adff 100644 --- a/src/static/js/tpl.js +++ b/src/static/js/tpl.js @@ -1,3 +1,5 @@ +import { connect } from "./socket.js"; + const colors = { 1: "blue", 2: "blue", @@ -13,7 +15,7 @@ const colors = { 12: "red" } -export default { +export const tpl = { card: ({ val, draggable = false }) => `
@@ -29,5 +31,95 @@ export default {
Skip-Bo
${val}
- ` + `, + msgBoxes: { + tpl: ({ title, content, buttons }) => ` +
+
${title}
+
+
+
+ ${content} +
+
+
+ ${buttons.map(button => button.tpl).join``} +
+
+
+ `, + joinGame: { + title: "join game", + content: ` +
+

Game room

+ +
+
+

Your name

+ +
+ `, + buttons: [{ + tpl: ``, + event: e => { + alert("join"); + } + }, { + tpl: ``, + event: e => { + removemsgBox(e.target.parentNode.parentNode.parentNode); + } + }] + }, + newGame: { + title: "new game", + content: ` +
+

Game room

+ +
+
+

Your name

+ +
+ `, + buttons: [{ + tpl: ``, + event: e => { + const box = e.target.parentNode.parentNode.parentNode; + connect({ + gameroom: box.querySelector("input[name='gameroom']").value, + playername: box.querySelector("input[name='playername']").value + }); + } + }, { + tpl: ``, + event: e => { + removemsgBox(e.target.parentNode.parentNode.parentNode); + } + }] + } + } +}; + +const removemsgBox = node => { + document.querySelector("body").removeChild(node); + if(document.querySelectorAll(".msgBox").length === 0 && document.querySelector("div#menu").style.display === "none") + document.querySelector("#black").style.display = "none"; +}; + +export const msgBox = type => { + if(document.querySelector("#black").style.display === "none") + document.querySelector("#black").style.display = "block"; + + document.querySelector("body").insertAdjacentHTML("afterbegin", + [tpl.msgBoxes[type]].map(tpl.msgBoxes.tpl).join`` + ); + document.querySelectorAll(".msgBox:first-child input[type='button']").forEach((button, i) => { + button.addEventListener("click", tpl.msgBoxes[type].buttons[i].event); + }); + return document.querySelector(".msgBox:first-child"); }; \ No newline at end of file