From f2c3496e71cd240f6d6b345a9f004ab811304daf Mon Sep 17 00:00:00 2001 From: Jonas Date: Wed, 16 Apr 2025 11:51:30 +0200 Subject: [PATCH] Statt Table nun canvas zur rendern im Frontend --- .../src/SocketIO/GameManager/Game/GameLoop.js | 2 +- .../game/scripts/Game/Elements/Overlay.js | 12 ++ .../game/scripts/Game/Elements/Playground.js | 109 ++++++++++-------- frontend/game/scripts/Game/Loop.js | 16 +-- frontend/game/scripts/Game/UI/UIManager.js | 7 +- 5 files changed, 84 insertions(+), 62 deletions(-) create mode 100644 frontend/game/scripts/Game/Elements/Overlay.js diff --git a/backend/src/SocketIO/GameManager/Game/GameLoop.js b/backend/src/SocketIO/GameManager/Game/GameLoop.js index fbccf71..b57d521 100644 --- a/backend/src/SocketIO/GameManager/Game/GameLoop.js +++ b/backend/src/SocketIO/GameManager/Game/GameLoop.js @@ -24,7 +24,7 @@ class GameLoop{ setTimeout(() => { this.loop(); - }, 250); + }, 125); } sendUpdate(){ diff --git a/frontend/game/scripts/Game/Elements/Overlay.js b/frontend/game/scripts/Game/Elements/Overlay.js new file mode 100644 index 0000000..c46f321 --- /dev/null +++ b/frontend/game/scripts/Game/Elements/Overlay.js @@ -0,0 +1,12 @@ +class Overlay{ + constructor(src = null, deg = 0){ + this.src = src; + this.deg = deg; + + if(!this.src) return; + this.image = new Image(); + this.image.src = src; + } +} + +export default Overlay \ 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 cce113d..32e8c34 100644 --- a/frontend/game/scripts/Game/Elements/Playground.js +++ b/frontend/game/scripts/Game/Elements/Playground.js @@ -1,5 +1,6 @@ import UIManager from "../UI/UIManager.js"; import Game from "../Game.js"; +import Overlay from "./Overlay.js"; class Playground{ /**@param {import(Game} game @param {UIManager} uiManager */ @@ -7,74 +8,80 @@ class Playground{ this.playgroundSize = playgroundSize; this.game = game; this.uiManager = uiManager; - - this.tiles = []; this.tileSize = Math.floor(window.innerHeight / playgroundSize.height); - this.setupTiles(); - } + // Canvas erstellen + this.canvas = document.createElement("canvas"); + this.canvas.height = this.playgroundSize.height * this.tileSize; + this.canvas.width = this.playgroundSize.width * this.tileSize; + this.uiManager.gameCanvasDiv.appendChild(this.canvas); - setupTiles(){ - for(let i = 0; i < this.playgroundSize.width; i++){ - const row = document.createElement("tr"); - let rowTiles = []; - this.uiManager.gameTable.appendChild(row); + this.ctx = this.canvas.getContext("2d"); - for(let u = 0; u < this.playgroundSize.height; u++){ - const td = document.createElement("td"); + // Hintergrund Bilder Laden + this.bgImage1 = new Image(); + this.bgImage1.src = "./assets/Gras/Gras1.png"; + this.bgImage2 = new Image(); + this.bgImage2.src = "./assets/Gras/Gras2.png"; - // 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"; + // Overlays Also Schlangen und Früchte erstellen + /** @type {Array>} */ + this.overlays = []; - // Das Gras als Hintergrundbild - const bgImage = document.createElement("img"); - 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"); - - // 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(overlayImage); + for(let y = 0; y < this.playgroundSize.height; y++){ + const row = []; + for(let x = 0; x < this.playgroundSize.width; x++){ + const overlay = new Overlay(); + row.push(overlay); } - - this.tiles.push(rowTiles); + this.overlays.push(row); } } - getOverlayTile(x, y){ - if ( - y >= 0 && y < this.tiles.length && - x >= 0 && x < this.tiles[y].length - ) { - return this.tiles[y][x]; - } + draw () { + // Canvas leeren + this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height); - return null; + // Jedes Tile / Overlay durchgehen und erst background dann falls da Overlay rendern + for(let y = 0; y < this.playgroundSize.height; y++){ + for (let x = 0; x < this.playgroundSize.width; x++){ + const posX = x * this.tileSize; + const posY = y * this.tileSize; + + // Hintergrund rendern + const bgImage = ((x % 2) === (y % 2)) ? this.bgImage1 : this.bgImage2; + this.ctx.drawImage(bgImage, posX, posY, this.tileSize, this.tileSize); + + // Falls overlay vorhanden darauf rendern + const overlay = this.overlays[y][x]; + if(!overlay.src) continue; + this.ctx.save(); + + // Rotation anwenden | Bisschen Komplexes Mathe Funzt :) + const centerX = posX + this.tileSize / 2; + const centerY = posY + this.tileSize / 2; + this.ctx.translate(centerX, centerY); + const rotation = (overlay.deg) * Math.PI / 180; + this.ctx.rotate(rotation); + this.ctx.drawImage(overlay.image, -this.tileSize / 2, -this.tileSize / 2, this.tileSize, this.tileSize); + this.ctx.restore(); + } + } } - resetOverlays(){ - this.tiles.forEach(r => { - r.forEach(e => { - e.style.display = "none"; - e.src = ""; + resetOverlay(){ + this.overlays.forEach(row => { + row.forEach(overlay => { + overlay.src = null; + overlay.deg = 0; }) }) } + + setOverlay(x, y, newOverlay){ + this.overlays[y][x] = newOverlay; + } } export default Playground; \ No newline at end of file diff --git a/frontend/game/scripts/Game/Loop.js b/frontend/game/scripts/Game/Loop.js index 1b6b7be..dedc492 100644 --- a/frontend/game/scripts/Game/Loop.js +++ b/frontend/game/scripts/Game/Loop.js @@ -1,3 +1,4 @@ +import Overlay from "./Elements/Overlay.js"; import Game from "./Game.js" class Loop{ @@ -10,23 +11,24 @@ class Loop{ } loop(data){ - this.game.playGround.resetOverlays(); + this.game.playGround.resetOverlay(); 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); + const overlay = new Overlay( + `./assets/Snakes/${tile.color}/${tile.type}.png`, + tile.deg + ) - tileImg.src = `./assets/Snakes/${tile.color}/${tile.type}.png`; - tileImg.style.display = "block" - tileImg.style.transform = `rotate(${tile.deg}deg)`; + this.game.playGround.setOverlay(x, y, overlay); } }) }); + + this.game.playGround.draw(); } } diff --git a/frontend/game/scripts/Game/UI/UIManager.js b/frontend/game/scripts/Game/UI/UIManager.js index 57c05ec..93d2af9 100644 --- a/frontend/game/scripts/Game/UI/UIManager.js +++ b/frontend/game/scripts/Game/UI/UIManager.js @@ -2,7 +2,7 @@ class UIManager{ constructor(){ this.mainDiv = document.getElementById("mainMenu"); - this.gameTable = undefined; + this.gameCanvasDiv = undefined; } // Erstellen des Grundgerüstes der UI @@ -14,9 +14,10 @@ class UIManager{ body.style.backgroundRepeat = "no-repeat"; body.style.backgroundColor = "#3b3b3f"; - this.gameTable = document.createElement("table"); + this.gameCanvasDiv = document.createElement("div"); + this.gameCanvasDiv.id = "gameCanvasDiv" - this.mainDiv.appendChild(this.gameTable); + this.mainDiv.appendChild(this.gameCanvasDiv); } // Erstellen der Info für welche Schlange man ist