From e4fd6dcea51f2fe08bb07341f4ef26f03431c72c Mon Sep 17 00:00:00 2001 From: Xamora Date: Sun, 5 May 2024 09:41:41 +0200 Subject: [PATCH] tournament 4 players offline finish --- frontend/static/css/gameOffline.css | 6 +- frontend/static/js/views/HomeView.js | 2 +- frontend/static/js/views/PongOfflineView.js | 184 +++++++++++++++++--- 3 files changed, 161 insertions(+), 31 deletions(-) diff --git a/frontend/static/css/gameOffline.css b/frontend/static/css/gameOffline.css index afcbed8..909af74 100644 --- a/frontend/static/css/gameOffline.css +++ b/frontend/static/css/gameOffline.css @@ -13,7 +13,11 @@ font-size: 40px; } +#up1, #down1 { + position: relative; +} + #up2, #down2 { position: relative; - float: right; + left: calc(420px - (60px * 3)); } diff --git a/frontend/static/js/views/HomeView.js b/frontend/static/js/views/HomeView.js index aa153d4..4822dbd 100644 --- a/frontend/static/js/views/HomeView.js +++ b/frontend/static/js/views/HomeView.js @@ -11,7 +11,7 @@ export default class extends AbstractAuthenticatedView { return /* HTML */ `

${lang.get('homeTitle', 'Home')}

${lang.get('homeOnline', 'Play online')} - ${lang.get('homeOffline', 'Play offline')} + ${lang.get('homeOffline', 'Play offline')} ${lang.get('ticTacToe')} ${lang.get('homeSettings', 'Settings')} ${lang.get('homeLogout', 'Logout')} diff --git a/frontend/static/js/views/PongOfflineView.js b/frontend/static/js/views/PongOfflineView.js index a1f5fe4..5916710 100644 --- a/frontend/static/js/views/PongOfflineView.js +++ b/frontend/static/js/views/PongOfflineView.js @@ -3,9 +3,21 @@ import AbstractAuthenticatedView from "./abstracts/AbstractAuthenticatedView.js" export class PongOfflineView extends AbstractAuthenticatedView { constructor(params) { super(params, 'Game'); + this.init(); + } + + init(round) { this.game = null; this.player1 = "Player 1"; this.player2 = "Player 2"; + this.player3 = "Player 3"; + this.player4 = "Player 4"; + + this.winner1 = undefined; + this.winner2 = undefined; + + this.final_winner = undefined; + this.round = -1; } async getHtml() { @@ -13,14 +25,20 @@ export class PongOfflineView extends AbstractAuthenticatedView {

Game

+ +
+
+ `; } async postInit() { - this.app = document.getElementById("app"); + this.app = document.getElementById("display"); document.getElementById('startGameButton').onclick = this.startGame.bind(this); + document.getElementById('resetGameButton').onclick = this.resetGame.bind(this); + document.getElementById('resetGameButton').hidden = 1; document.getElementById('stopGameButton').onclick = this.stopGame.bind(this); document.getElementById('stopGameButton').hidden = 1; document.getElementById('startTournament').onclick = this.startTournament.bind(this); @@ -33,33 +51,37 @@ export class PongOfflineView extends AbstractAuthenticatedView { startTournament() { let startTournament = document.getElementById("startTournament"); let player1 = document.createElement("input"); - player1.id="player1"; player1.type="text"; player1.name="message"; player1.placeholder="Player 1"; player1.maxLength=20; player1.value = ""; + player1.id="player1"; player1.type="text"; player1.name="message"; player1.placeholder="Player 1"; player1.maxLength=10; player1.value = ""; startTournament.before(player1); let player2 = document.createElement("input"); - player2.id="player2"; player2.type="text"; player2.name="message"; player2.placeholder="Player 2"; player2.maxLength=20; player2.value = ""; + player2.id="player2"; player2.type="text"; player2.name="message"; player2.placeholder="Player 2"; player2.maxLength=10; player2.value = ""; player1.after(player2); - /*let player3 = document.createElement("input"); - player3.id="player3"; player3.type="text"; player3.name="message"; player3.placeholder="Player 3"; player3.maxLength=20; + let player3 = document.createElement("input"); + player3.id="player3"; player3.type="text"; player3.name="message"; player3.placeholder="Player 3"; player3.maxLength=10; player3.value = ""; player2.after(player3); let player4 = document.createElement("input"); - player4.id="player4"; player4.type="text"; player4.name="message"; player4.placeholder="Player 4"; player4.maxLength=40; - player3.after(player4);*/ + player4.id="player4"; player4.type="text"; player4.name="message"; player4.placeholder="Player 4"; player4.maxLength=10; player4.value = ""; + player3.after(player4); startTournament.onclick = () => { if (player1.value.length > 0) this.player1 = player1.value; if (player2.value.length > 0) this.player2 = player2.value; - /*if (player3.value.length > 0) + if (player3.value.length > 0) this.player3 = player3.value; if (player4.value.length > 0) - this.player4 = player4.value;*/ + this.player4 = player4.value; player1.remove(); player2.remove(); + player3.remove(); + player4.remove(); + + this.round = 0; this.startGame(this.player1, this.player2); startTournament.onclick = this.startTournament.bind(this); @@ -103,29 +125,45 @@ export class PongOfflineView extends AbstractAuthenticatedView { button.ontouchend = this.game.keyUpHandler.bind(this.game); }); - document.getElementById("gameCanvas").after(this.up2, this.down2); - document.getElementById("gameCanvas").after(this.up1, this.down1); + document.getElementById("display-button").append(this.up1, this.down1); + document.getElementById("display-button").append(this.up2, this.down2); } - startGame(player1, player2) { + resetGame(player1, player2) { + if (this.round >= 0) + this.round = 0; + + this.winner1 = undefined; + this.winner2 = undefined; + this.final_winner = undefined; + + this.startGame(player1, player2) + } + + async startGame(player1, player2) { if (player1 == null || player2 == null) { player1 = this.player1; player2 = this.player2; } if (this.game == null) { - document.getElementById('startGameButton').innerHTML = 'Reset Game'; - this.game = new Game(player1, player2); + this.game = new Game(this, player1, player2); this.createButton(); } else { this.app.removeChild(this.game.canvas); this.app.removeChild(this.game.scoresDisplay); this.game.cleanup(); - this.game = new Game(player1, player2); + this.game = new Game(this, player1, player2); this.createButton(); } + + if (this.round >= 0) { + await this.display_tree_tournament(); + } document.getElementById('startTournament').hidden = 1; + document.getElementById('startGameButton').hidden = 1; document.getElementById('stopGameButton').hidden = 0; + document.getElementById('resetGameButton').hidden = 0; } stopGame() { @@ -134,16 +172,78 @@ export class PongOfflineView extends AbstractAuthenticatedView { this.app.removeChild(this.game.canvas); this.app.removeChild(this.game.scoresDisplay); this.game.cleanup(); - this.game = null; + this.init(); document.getElementById('startGameButton').innerHTML = 'Start Game'; document.getElementById('startTournament').hidden = 0; + document.getElementById('startGameButton').hidden = 0; document.getElementById('stopGameButton').hidden = 1; + document.getElementById('resetGameButton').hidden = 1; this.app.style.maxWidth = null; + + } + + async display_tree_tournament() { + let players = [this.player1, this.player2, this.player3, this.player4, this.winner1, this.winner2, this.final_winner]; + const svg = document.getElementById('tree'); + + svg.innerHTML = ''; + + let width = 150; + let height = 40; + let gap_y = height + 25; + let gap_x = width + 25; + let start_y = height / 2; + + let rounds = Math.log2(4) + 1; + + let k = 0; + for (let i = 0; i < rounds; i++) { + let number_square = 4 / Math.pow(2, i) + for(let j = 0; j < number_square; j++) { + const y = start_y + gap_y * j * Math.pow(2, i) + (gap_y / 2 * Math.pow(2, i)); + svg.appendChild(await this.create_square(gap_x * i, y, width, height, "white", "black", players[k])); + svg.appendChild(await this.create_text(gap_x * i, y, width, height, "white", "black", players[k])); + k++; + } + } + } + + async create_square(x, y, width, height, fill, stroke, text) { + const square = document.createElementNS("http://www.w3.org/2000/svg", "rect"); + square.setAttribute("id", "square") + square.setAttribute("x", x); + square.setAttribute("y", y); + square.setAttribute("width", width); + square.setAttribute("height", height); + square.setAttribute("fill", fill); + square.setAttribute("stroke", stroke); + + return square + } + + async create_text(x, y, width, height, fill, stroke, text) { + const textElement = document.createElementNS("http://www.w3.org/2000/svg", "text"); + textElement.setAttribute("id", "textElement") + textElement.setAttribute("x", x); + textElement.setAttribute("y", y + height / 2 + 5); + textElement.setAttribute("font-family", "Arial") + textElement.setAttribute("font-size", "20") + textElement.setAttribute("fill", stroke); + textElement.setAttribute("stroke", fill); + + if (text == undefined) + text = ""; + textElement.appendChild(document.createTextNode(text)); + + return textElement; } } class Game { - constructor(player1, player2) { + constructor(this_pong, player_name1, player_name2) { + + this.pong = this_pong; + //Global variables this.def = { CANVASHEIGHT: 270, @@ -156,14 +256,14 @@ class Game { BALLSPEED: 2, BALLSPEEDINCR: 0.15, MAXBOUNCEANGLE: 10 * (Math.PI / 12), - MAXSCORE: 0 + MAXSCORE: 2 }; - this.app = document.getElementById("app"); + this.app = document.getElementById("display"); this.app.style.maxWidth = Number(this.def.CANVASWIDTH) + "px"; - this.player1 = player1; - this.player2 = player2; + this.player_name1 = player_name1; + this.player_name2 = player_name2; this.canvas = document.createElement('canvas'); this.canvas.id = 'gameCanvas'; @@ -173,8 +273,9 @@ class Game { this.canvas.style.backgroundColor = '#f1f1f1'; this.context = this.canvas.getContext('2d'); this.app.appendChild(this.canvas); + this.scoresDisplay = document.createElement('p'); - this.scoresDisplay.innerHTML = `${this.player1}: 0 - ${this.player2}: 0`; + this.scoresDisplay.innerHTML = `${this.player_name1}: 0 - ${this.player_name2}: 0`; this.app.appendChild(this.scoresDisplay); this.players = [ @@ -205,15 +306,41 @@ class Game { } + finish(winner) { + this.cleanup(); + if (this.pong.round >= 0) { + if (this.pong.round == 0) { + this.pong.winner1 = winner; + this.pong.startGame(this.pong.player3, this.pong.player4) + this.pong.round++; + } + else if (this.pong.round == 1) { + this.pong.winner2 = winner; + this.pong.startGame(this.pong.winner1, this.pong.winner2) + this.pong.round++; + } + else { + this.pong.final_winner = winner; + this.pong.display_tree_tournament(); + this.scoresDisplay.innerHTML = winner + ' wins!! GGS'; + } + } + else + this.scoresDisplay.innerHTML = winner + ' wins!! GGS'; + } + cleanup() { clearInterval(this.interval); document.removeEventListener('keydown', this.keyDownHandler); document.removeEventListener('keyup', this.keyUpHandler); this.canvas.style.display = 'none'; - ["up1", "up2", "down1", "down2", "player1", "player2"].forEach(button => { + ["up1", "up2", "down1", "down2", "player_name1", "player_name2"].forEach(button => { if (document.getElementById(button) != null) document.getElementById(button).remove(); - }); + }); + let svg = document.getElementById("tree"); + while (svg.firstChild) + svg.removeChild(svg.firstChild); } clear() { @@ -270,14 +397,12 @@ class Game { updateScore(p1Score, p2Score) { if (p1Score > this.def.MAXSCORE) { - this.scoresDisplay.innerHTML = this.player1 + ' wins!! GGS'; - this.cleanup(); + this.finish(this.player_name1); } else if (p2Score > this.def.MAXSCORE) { - this.scoresDisplay.innerHTML = this.player2 + ' wins!! GGS'; - this.cleanup(); + this.finish(this.player_name2); } else { - this.scoresDisplay.innerHTML = `${this.player1}: ${p1Score} - ${this.player2}: ${p2Score}`; + this.scoresDisplay.innerHTML = `${this.player_name1}: ${p1Score} - ${this.player_name2}: ${p2Score}`; this.ballStartSide = 1 - this.ballStartSide; this.ball = new Ball(this.context, this.def, this.ballStartSide); this.ballRespawned = true; @@ -324,6 +449,7 @@ class Game { if (!this.keys.includes(key)) this.keys.push(key); } + } class Paddle {