Files
DoubleSnake/backend/src/SocketIO/GameManager/Game/Game.js
2025-09-21 20:23:42 +02:00

177 lines
4.8 KiB
JavaScript

const socketIO = require("socket.io");
const SocketUser = require("../../Classes/SocketUser");
const TemporaryLobby = require("../../LobbyManager/Classes/TemporaryLobby");
const GameManager = require("../GameManager");
const GameLoop = require("./GameLoop");
const Snake = require("./Classes/Snake/Snake");
const SNAKE_COLORS = ["red", "blue"]; // must stay in sync with the frontend asset map
class Game{
/** @param {socketIO.Server} io @param {GameManager} gameManager @param {number} code */
constructor(io, gameManager, code) {
this.io = io;
this.gameManager = gameManager;
this.code = code;
this.score = 0;
this.waitingSeconds = 5;
this.gameStarted = false;
this.snakeColors = [...SNAKE_COLORS];
/**@type {Array<SocketUser>} */
this.players = [];
/**@type {Array<SocketUser>} */
this.playerIds = [];
this.gameLoop = new GameLoop(io, this);
setTimeout(() => { this.waitingForPlayers(true) }, 100);
}
startGame(){
this.io.to(`game-${this.code}`).emit("startGame", {
width: this.gameLoop.playground.width,
height: this.gameLoop.playground.height
});
this.gameStarted = true;
// 2 Schlangen für die Spieler Instazieren
this.players.forEach((player, i) => {
// id pushen um nachher das Endgame zu beenden
this.playerIds.push(player.id);
const start = (10 * i + 5) - 1;
const snake = new Snake(
player,
this.gameLoop.playground,
this,
this.snakeColors[i],
{
x: start,
y: start
},
i == 0 ? "right" : "left"
);
this.gameLoop.snakes.push(snake);
});
this.gameLoop.loop();
}
async endGame(msg){
let scoreDb = undefined;
if(this.gameStarted){
scoreDb = await this.gameManager.db.scoremanager.createScore({
user1: this.playerIds[0],
user2: this.playerIds[1],
score: this.score
});
}
this.gameStarted = false;
/*
Hinzufügen der Funktion zum erneuten Spielen
Nur wenn noch beide Spieler da sind
*/
let replayPossible = false;
const replayTime = 5000;
if(this.players.length === 2){
const lobbyManager = this.gameManager.lobbyManager;
const newUserList = [];
this.players.forEach(x => {
const user = new SocketUser(x.id, x.username);
newUserList.push(user);
})
const tempLobby = new TemporaryLobby(
0,
newUserList,
lobbyManager,
replayTime
);
lobbyManager.oldLobbys.push(tempLobby);
replayPossible = true;
}
this.io.to(`game-${this.code}`).emit("gameEnd", {
msg: msg,
score: this.score,
rang: scoreDb?.rank || "-",
replay: {
possible: replayPossible,
time: replayTime
}
});
}
async waitingForPlayers(changeTime = false){
if(this.waitingSeconds <= 0){
if(this.players.length < 2) {
await this.endGame("Das Spiel ist zu Ende, da nicht genug Spieler beigetreten sind!");
this.gameManager.games.delete(this.code);
return;
}
return this.startGame();
}
let msg = "";
this.players.forEach(player => {
if(msg === ""){
msg = `Schon beigetreten: ${player.username}`;
}
else{
msg += ` und ${player.username}, es geht Sofort los!`;
}
});
this.io.to(`game-${this.code}`).emit("waitingForPlayers", {
msg: msg,
waitingSeconds: this.waitingSeconds
});
if (changeTime){
this.waitingSeconds--;
setTimeout(() => { this.waitingForPlayers(true) }, 1000);
}
}
/** @param {SocketUser} user */
addUser(user){
if(this.players.length >= 2) return 1;
this.waitingForPlayers();
this.players.push(user);
}
/** @param {SocketUser} user */
async leaveUser(user){
this.players.forEach((player, index) => {
if(player.id === user.id){
this.players.splice(index, 1);
}
});
if(this.players.length != 2){
if(this.gameStarted) await this.endGame("Das Spiel ist zu Ende, da ein Spieler verlassen hat!");
return 1;
}
}
}
module.exports = Game;