diff --git a/backend/src/SocketIO/GameManager/Game/Classes/Playground/Playground.js b/backend/src/SocketIO/GameManager/Game/Classes/Playground/Playground.js index c97dd28..aeb8c3b 100644 --- a/backend/src/SocketIO/GameManager/Game/Classes/Playground/Playground.js +++ b/backend/src/SocketIO/GameManager/Game/Classes/Playground/Playground.js @@ -5,21 +5,20 @@ class Playground { this.height = 20; /** @type {Array} */ - this.tiles = this.createPlayground(); + this.tiles = []; + + this.resetPlayground(); } - createPlayground(){ - const tilesArray = []; - + resetPlayground(){ + this.tiles = []; for (let i = 0; i < this.width; i++) { const column = []; for (let j = 0; j < this.height; j++) { column.push(null); } - tilesArray.push(column); + this.tiles.push(column); } - - return tilesArray; } getTile(x, y){ diff --git a/backend/src/SocketIO/GameManager/Game/Classes/Snake/Snake.js b/backend/src/SocketIO/GameManager/Game/Classes/Snake/Snake.js index 1e1ca05..a9bd55d 100644 --- a/backend/src/SocketIO/GameManager/Game/Classes/Snake/Snake.js +++ b/backend/src/SocketIO/GameManager/Game/Classes/Snake/Snake.js @@ -3,19 +3,77 @@ const Playground = require("../Playground/Playground"); class Snake{ /** @param {SocketUser} player @param {Playground} playground */ - constructor(player, playground, color, startTiles) { + constructor(player, playground, color, startTiles, startMovement) { this.player = player; this.playground = playground; this.color = color; this.tiles = []; - this.nextMovement = null; + this.nextMovement = startMovement; + + this.directionDegree = new Map([ + ["right", 0], + ["down", 90], + ["left", 180], + ["up", 270] + ]); this.player.socket.on("movement", (data) => { this.updateNextMovement(data) }) + + this.setup(startTiles); + } + + setup(startTiles){ + this.player.socket.emit("color", this.color); + + const headX = startTiles.x; + const headY = startTiles.y; + + let dx = 0; + let dy = 0; + switch (this.nextMovement) { + case "up": dy = 1; break; + case "down": dy = -1; break; + case "left": dx = 1; break; + case "right": dx = -1; break; + } + + for (let i = 0; i < 3; i++) { + let type = null; + switch(i){ + case 0: + type = "Head"; + break; + case 2: + type = "End"; + break; + default: + type = "Straight"; + break; + } + this.tiles.push({ + class: "Snake", + type: type, + color: this.color, + deg: this.directionDegree.get(this.nextMovement), + x: headX + i * dx, + y: headY + i * dy + }); + } + + this.drawTiles(); + + console.log(this.tiles); + } + + drawTiles(){ + this.tiles.forEach(tile => { + this.playground.setTile(tile.x, tile.y, tile); + }) } updateNextMovement(data){ - + console.log(`${this.player.username} | ${this.nextMovement}`); } } diff --git a/backend/src/SocketIO/GameManager/Game/Game.js b/backend/src/SocketIO/GameManager/Game/Game.js index f5bbf4a..f71a622 100644 --- a/backend/src/SocketIO/GameManager/Game/Game.js +++ b/backend/src/SocketIO/GameManager/Game/Game.js @@ -2,6 +2,7 @@ const socketIO = require("socket.io"); const SocketUser = require("../../Classes/SocketUser"); const GameManager = require("../GameManager"); const GameLoop = require("./GameLoop"); +const Snake = require("./Classes/Snake/Snake"); class Game{ /** @param {socketIO.Server} io @param {GameManager} gameManager @param {number} code */ @@ -13,6 +14,8 @@ class Game{ this.waitingSeconds = 5; this.gameStarted = false; + this.snakeColors = ["red", "blue"]; + /**@type {Array} */ this.players = []; @@ -27,6 +30,24 @@ class Game{ height: this.gameLoop.playground.height }); this.gameStarted = true; + + // 2 Schlangen für die Spieler Instazieren + this.players.forEach((player, i) => { + const start = (10 * i + 5) - 1; + const snake = new Snake( + player, + this.gameLoop.playground, + this.snakeColors[i], + { + x: start, + y: start + }, + i == 0 ? "right" : "left" + ); + + this.gameLoop.snakes.push(snake); + }); + this.gameLoop.loop(); } diff --git a/backend/src/SocketIO/GameManager/Game/GameLoop.js b/backend/src/SocketIO/GameManager/Game/GameLoop.js index 598d0c4..795fa8b 100644 --- a/backend/src/SocketIO/GameManager/Game/GameLoop.js +++ b/backend/src/SocketIO/GameManager/Game/GameLoop.js @@ -1,6 +1,7 @@ const socketIO = require("socket.io"); const Playground = require("./Classes/Playground/Playground"); const Game = require("./Game"); +const Snake = require("./Classes/Snake/Snake"); class GameLoop{ /** @param {socketIO.Server} io @param {Game} game */ @@ -9,22 +10,29 @@ class GameLoop{ this.game = game; this.playground = new Playground(); + + /** @type {Array} */ + this.snakes = []; } loop(){ - this.io.to(`game-${this.game.code}`).emit("loop", { - code: this.game.code, - playground: { - // height: this.playground.height, - // width: this.playground.width, - tiles: this.playground.tiles, - } - }); + //this.snakes.forEach() + + this.sendUpdate(); setTimeout(() => { this.loop(); }, 250); } + + sendUpdate(){ + this.io.to(`game-${this.game.code}`).emit("loop", { + code: this.game.code, + playground: { + tiles: this.playground.tiles, + } + }); + } } module.exports = GameLoop; \ No newline at end of file diff --git a/frontend/game/scripts/Game/Elements/Playground.js b/frontend/game/scripts/Game/Elements/Playground.js index 6308a27..cce113d 100644 --- a/frontend/game/scripts/Game/Elements/Playground.js +++ b/frontend/game/scripts/Game/Elements/Playground.js @@ -10,7 +10,7 @@ class Playground{ this.tiles = []; - this.tileSize = window.innerHeight / playgroundSize.height; + this.tileSize = Math.floor(window.innerHeight / playgroundSize.height); this.setupTiles(); } @@ -24,20 +24,57 @@ class Playground{ for(let u = 0; u < this.playgroundSize.height; u++){ const td = document.createElement("td"); + // Container um Überlappung zu ermöglichen + const container = document.createElement("div"); + container.style.position = "relative"; + container.style.height = this.tileSize + "px"; + container.style.width = this.tileSize + "px"; + + // Das Gras als Hintergrundbild const bgImage = document.createElement("img"); - (u % 2 == i % 2) ? bgImage.src = "./assets/Gras/Gras1.png" : bgImage.src = "./assets/Gras/Gras2.png"; + bgImage.src = (u % 2 == i % 2) ? "./assets/Gras/Gras1.png" : "./assets/Gras/Gras2.png"; bgImage.height = this.tileSize; bgImage.width = this.tileSize; bgImage.classList.add("backgroundTile"); - td.appendChild(bgImage); + + // Je nach belieben Overlay-Bild + const overlayImage = document.createElement("img") + overlayImage.style.display = "none" + overlayImage.height = this.tileSize; + overlayImage.width = this.tileSize; + overlayImage.classList.add("overlayTile"); + + container.appendChild(bgImage); + container.appendChild(overlayImage); + td.appendChild(container); row.appendChild(td); - rowTiles.push(td); + rowTiles.push(overlayImage); } this.tiles.push(rowTiles); } } + + getOverlayTile(x, y){ + if ( + y >= 0 && y < this.tiles.length && + x >= 0 && x < this.tiles[y].length + ) { + return this.tiles[y][x]; + } + + return null; + } + + resetOverlays(){ + this.tiles.forEach(r => { + r.forEach(e => { + e.style.display = "none"; + e.src = ""; + }) + }) + } } export default Playground; \ No newline at end of file diff --git a/frontend/game/scripts/Game/Game.js b/frontend/game/scripts/Game/Game.js index c02b0d8..7f00dd0 100644 --- a/frontend/game/scripts/Game/Game.js +++ b/frontend/game/scripts/Game/Game.js @@ -15,7 +15,10 @@ class Game{ this.gameStarted = false; + this.ourColor = null; + this.socket.on("startGame", (data) => { this.start(data) }); + this.socket.on("color", (data) => { this.setOutColor(data) }) } start(playgroundSize){ @@ -25,6 +28,12 @@ class Game{ this.movementHandler = new MovementHandler(this.socket); this.playGround = new Playground(this, this.uiManager, playgroundSize); } + + setOutColor(color){ + this.ourColor = color; + + this.uiManager.addSnakeColorInfo(color); + } } export default Game; \ No newline at end of file diff --git a/frontend/game/scripts/Game/Loop.js b/frontend/game/scripts/Game/Loop.js index 9bbe569..1b6b7be 100644 --- a/frontend/game/scripts/Game/Loop.js +++ b/frontend/game/scripts/Game/Loop.js @@ -10,7 +10,23 @@ class Loop{ } loop(data){ - + this.game.playGround.resetOverlays(); + const tiles = data.playground.tiles; + + tiles.forEach((row, x) => { + row.forEach((tile, y) => { + if(!tile) return; + console.log(tile) + if(tile.class === "Snake"){ + /** @type {HTMLImageElement} */ + const tileImg = this.game.playGround.getOverlayTile(x, y); + + tileImg.src = `./assets/Snakes/${tile.color}/${tile.type}.png`; + tileImg.style.display = "block" + tileImg.style.transform = `rotate(${tile.deg}deg)`; + } + }) + }); } } diff --git a/frontend/game/scripts/Game/UI/UIManager.js b/frontend/game/scripts/Game/UI/UIManager.js index 9372348..57c05ec 100644 --- a/frontend/game/scripts/Game/UI/UIManager.js +++ b/frontend/game/scripts/Game/UI/UIManager.js @@ -18,6 +18,47 @@ class UIManager{ this.mainDiv.appendChild(this.gameTable); } + + // Erstellen der Info für welche Schlange man ist + addSnakeColorInfo(color){ + const infoDiv = document.createElement("div"); + infoDiv.id = "infoDiv" + + const header = document.createElement("h1") + header.innerText = "Deine Schlange:" + infoDiv.appendChild(header); + + const snakeTable = document.createElement("table"); + const lenght = 3; + for (let i = 0; i < lenght; i++) { + const tr = document.createElement("tr"); + const td = document.createElement("td"); + + const img = document.createElement("img"); + switch (i) { + case 0: + img.src = `./assets/Snakes/${color}/Head.png`; + break; + case lenght - 1: + img.src = `./assets/Snakes/${color}/End.png`; + break; + default: + img.src = `./assets/Snakes/${color}/Straight.png`; + break; + } + img.style.transform = "rotate(270deg)"; + img.style.width = "10vw"; + img.style.height = "10vw"; + + td.appendChild(img); + tr.appendChild(td); + snakeTable.appendChild(tr); + } + + infoDiv.append(snakeTable); + + this.mainDiv.appendChild(infoDiv); + } } export default UIManager; \ No newline at end of file diff --git a/frontend/game/style/mainStyle.css b/frontend/game/style/mainStyle.css index c990c49..1e92f5a 100644 --- a/frontend/game/style/mainStyle.css +++ b/frontend/game/style/mainStyle.css @@ -10,7 +10,44 @@ td, tr { td img { vertical-align: top; +} + +img{ -moz-user-select: none; -webkit-user-select: none; user-select: none; -} \ No newline at end of file +} + +#infoDiv{ + background-color: rgba(0, 0, 0, 0.3); + + position: absolute; + height: 75vh; + width: 15vw; + + border: 5px solid rgba(255, 255, 255, 0.678); + border-radius: 25px; + right: 2.5vw; + + text-align: center; + + display: flex; + flex-direction: column; + align-items: center; + justify-content: space-evenly; +} + +.backgroundTile, +.overlayTile { + position: absolute; + top: 0; + left: 0; +} + +.backgroundTile { + z-index: 0; +} + +.overlayTile { + z-index: 1; +}