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 {