Füge Countdown-Logik für den Spielstart hinzu und verbessere die Benutzerverwaltung in Lobbys

This commit is contained in:
2025-03-24 19:46:49 +01:00
parent 101b29193c
commit d299a90067
10 changed files with 178 additions and 5 deletions

View File

@@ -8,15 +8,22 @@ class Lobby {
this.code = code; this.code = code;
/** @type {Array<SocketUser>} */ /** @type {Array<SocketUser>} */
this.users = []; this.users = [];
this.gameStart = false;
this.currentSecond = 5;
} }
addUser(user) { addUser(user) {
if (this.users.length >= 2) return 1; if (this.users.length >= 2) return 1;
this.users.push(user); this.users.push(user);
this.sendLobbyUserUpdate(); this.sendLobbyUserUpdate();
if(this.users.length === 2) {
console.log("Starte Spiel");
setTimeout(this.startGame.bind(this), 2000);
}
return 0; return 0;
} }
@@ -45,6 +52,49 @@ class Lobby {
this.io.to(`lobby-${this.code}`).emit("lobbyUserUpdate", data); this.io.to(`lobby-${this.code}`).emit("lobbyUserUpdate", data);
} }
startGame() {
this.users.forEach(user => {
user.socket.on("disconnect", this.interruptStart.bind(this));
});
this.gameStart = true;
setTimeout(this.sendStartGameUpdate.bind(this), 1000);
}
sendStartGameUpdate() {
if(!this.gameStart) return;
const data = {
code: this.code,
needRedirect: this.currentSecond <= 0,
currentSecond: this.currentSecond
}
this.io.to(`lobby-${this.code}`).emit("startGame", data);
this.currentSecond--;
if(this.currentSecond === -2) {
this.gameStart = false;
this.currentSecond = 5;
return;
}
setTimeout(this.sendStartGameUpdate.bind(this), 1000);
}
interruptStart() {
this.gameStart = false;
this.currentSecond = 5;
this.users.forEach(user => {
user.socket.off("disconnect", this.interruptStart.bind(this));
});
this.io.to(`lobby-${this.code}`).emit("interruptStart");
}
} }
module.exports = Lobby; module.exports = Lobby;

View File

@@ -5,7 +5,7 @@ class SocketUser {
constructor(id, username, socket) { constructor(id, username, socket) {
this.id = id; this.id = id;
this.username = username; this.username = username;
this.socket = socket; this.socket = socket || null;
} }
} }

View File

@@ -0,0 +1,9 @@
class TemporaryLobby{
/** @param { string } code @param {Array<SocketUser>} users */
constructor(code, users){
this.code = code;
this.users = users;
}
}
module.exports = TemporaryLobby;

View File

@@ -20,7 +20,7 @@ class ClientHandler {
this.socket.on("createLobby", () => { this.createLobby() }) this.socket.on("createLobby", () => { this.createLobby() })
this.socket.on("joinLobby", (code) => { this.joinLobby(code) }) this.socket.on("joinLobby", (code) => { this.joinLobby(code) })
this.socket.on("refreshLobby", () => { this.refreshLobby() }) this.socket.on("refreshLobby", () => { this.refreshLobby() })
this.socket.on("disconnect", () => { this.disconnect() }) this.socket.on("disconnect", () => { this.defaultDisconnect() })
} }
createLobby(){ createLobby(){
@@ -43,7 +43,7 @@ class ClientHandler {
this.currentLobbyCode = response; this.currentLobbyCode = response;
this.socket.join(`lobby-${response}`) this.socket.join(`lobby-${response}`);
this.socket.emit("lobbyJoined", response); this.socket.emit("lobbyJoined", response);
this.refreshLobby(); this.refreshLobby();
} }
@@ -52,7 +52,7 @@ class ClientHandler {
this.lobbyManager.refreshLobby(this.currentLobbyCode); this.lobbyManager.refreshLobby(this.currentLobbyCode);
} }
disconnect(){ defaultDisconnect(){
this.lobbyManager.removeFromLobby(this.currentLobbyCode, this.user); this.lobbyManager.removeFromLobby(this.currentLobbyCode, this.user);
} }
} }

View File

@@ -1,6 +1,7 @@
const socketIO = require("socket.io"); const socketIO = require("socket.io");
const Lobby = require("./Classes/Lobby"); const Lobby = require("./Classes/Lobby");
const SocketUser = require("./Classes/SocketUser"); const SocketUser = require("./Classes/SocketUser");
const TemporaryLobby = require("./Classes/TemporaryLobby");
class LobbyManager { class LobbyManager {
/** @param {socketIO.Server} io */ /** @param {socketIO.Server} io */
@@ -10,6 +11,9 @@ class LobbyManager {
/** @type {Map<string, Lobby>}*/ /** @type {Map<string, Lobby>}*/
this.lobbys = new Map(); this.lobbys = new Map();
/** @type {Array<TemporaryLobby>}*/
this.oldLobbys = [];
// Zeigt die Anzahl der Lobbys an | Für Testing // Zeigt die Anzahl der Lobbys an | Für Testing
// setInterval(() => { // setInterval(() => {
// console.log(this.lobbys.size); // console.log(this.lobbys.size);

72
doublesnake.sql Normal file
View File

@@ -0,0 +1,72 @@
-- phpMyAdmin SQL Dump
-- version 5.2.1
-- https://www.phpmyadmin.net/
--
-- Host: 127.0.0.1
-- Erstellungszeit: 22. Mrz 2025 um 20:49
-- Server-Version: 10.4.32-MariaDB
-- PHP-Version: 8.2.12
SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
START TRANSACTION;
SET time_zone = "+00:00";
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8mb4 */;
--
-- Datenbank: `doublesnake`
--
-- --------------------------------------------------------
--
-- Tabellenstruktur für Tabelle `users`
--
CREATE TABLE `users` (
`id` int(11) NOT NULL,
`username` varchar(255) NOT NULL,
`email` varchar(255) DEFAULT NULL,
`password` varchar(255) NOT NULL,
`fullName` varchar(255) DEFAULT NULL,
`createdAt` timestamp NOT NULL DEFAULT current_timestamp()
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
--
-- Daten für Tabelle `users`
--
INSERT INTO `users` (`id`, `username`, `email`, `password`, `fullName`, `createdAt`) VALUES
(1, 'test', 'test@gmail.com', '$2b$10$lAwMUGqw45KAzY1xv2x1vutNLwQTelz7UaPkPEJq9lST6GChJODHq', 'Test Person', '2025-03-22 19:48:37'),
(2, 'test2', 'test2@gmail.com', '$2b$10$fRrqNkFVA4TIyy61ovgPae83drW6oZOCND94BErwthKmt1MxzgTci', 'Test Person 2', '2025-03-22 19:48:45'),
(3, 'test3', NULL, '$2b$10$5QEkQuI/HxnaNovp8XPbnOnkuPpfSLdjwyqXMXKCB5oHZQR3ILTkq', NULL, '2025-03-22 19:48:51');
--
-- Indizes der exportierten Tabellen
--
--
-- Indizes für die Tabelle `users`
--
ALTER TABLE `users`
ADD PRIMARY KEY (`id`),
ADD UNIQUE KEY `username` (`username`);
--
-- AUTO_INCREMENT für exportierte Tabellen
--
--
-- AUTO_INCREMENT für Tabelle `users`
--
ALTER TABLE `users`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=4;
COMMIT;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;

View File

@@ -45,6 +45,9 @@
</button> </button>
</div> </div>
<div class="container"> <div class="container">
<div id="gameStartCountdown" class="hidden">
<h2>Das Spiel startet in <span id="countdown">5</span> Sekunden</h2>
</div>
<button id="leaveBtn"> <button id="leaveBtn">
<div class="buttonIcon"> <div class="buttonIcon">
<svg xmlns="http://www.w3.org/2000/svg" height="35px" viewBox="0 -960 960 960" width="35px" <svg xmlns="http://www.w3.org/2000/svg" height="35px" viewBox="0 -960 960 960" width="35px"

View File

@@ -1,3 +1,5 @@
import StartGameHandler from "./StartGameHandler.js";
class LobbyHandler { class LobbyHandler {
/**@param {import("../../../../../backend/node_modules/socket.io-client".Socket} socket Autocompletions VSC*/ /**@param {import("../../../../../backend/node_modules/socket.io-client".Socket} socket Autocompletions VSC*/
constructor(socket) { constructor(socket) {
@@ -22,6 +24,9 @@ class LobbyHandler {
// Für das Aktualisieren // Für das Aktualisieren
this.socket.on("lobbyUserUpdate", (data) => { this.lobbyUserUpdate(data) }); this.socket.on("lobbyUserUpdate", (data) => { this.lobbyUserUpdate(data) });
// Für alles Was mit dem Starten zu tuhen hat
this.startGameHandler = new StartGameHandler(this.socket);
} }
handleCreateClick() { handleCreateClick() {

View File

@@ -0,0 +1,26 @@
class StartGameHandler {
/**@param {import("../../../../../backend/node_modules/socket.io-client".Socket} socket Autocompletions VSC*/
constructor(socket) {
this.socket = socket;
this.countDownText = document.getElementById("countdown");
this.socket.on("startGame", (data) => { this.startGame(data) });
this.socket.on("interruptStart", () => { this.interruptStart() });
}
startGame(data) {
document.getElementById("gameStartCountdown").style.display = "block";
this.countDownText.innerText = data.currentSecond;
if(data.needRedirect){
window.location.pathname = `/game`;
}
}
interruptStart() {
document.getElementById("gameStartCountdown").style.display = "none";
}
}
export default StartGameHandler;

View File

@@ -72,4 +72,8 @@ button {
#codeInp{ #codeInp{
text-align: center; text-align: center;
}
.hidden{
display: none;
} }