diff --git a/frontend/src/App.js b/frontend/src/App.js
index 461a9b3dc..9d6420651 100644
--- a/frontend/src/App.js
+++ b/frontend/src/App.js
@@ -177,12 +177,7 @@ function App() {
path="tournament"
element={
-
+
}
/>
diff --git a/frontend/src/images/tournament/baby.png b/frontend/src/images/tournament/baby.png
new file mode 100644
index 000000000..4b3c8bf21
Binary files /dev/null and b/frontend/src/images/tournament/baby.png differ
diff --git a/frontend/src/images/tournament/balanced.png b/frontend/src/images/tournament/balanced.png
new file mode 100644
index 000000000..1562ce173
Binary files /dev/null and b/frontend/src/images/tournament/balanced.png differ
diff --git a/frontend/src/images/tournament/eliminate.png b/frontend/src/images/tournament/eliminate.png
new file mode 100644
index 000000000..c25a63635
Binary files /dev/null and b/frontend/src/images/tournament/eliminate.png differ
diff --git a/frontend/src/images/tournament/insane.png b/frontend/src/images/tournament/insane.png
new file mode 100644
index 000000000..c96b9ce47
Binary files /dev/null and b/frontend/src/images/tournament/insane.png differ
diff --git a/frontend/src/images/tournament/player.png b/frontend/src/images/tournament/player.png
new file mode 100644
index 000000000..7579a1191
Binary files /dev/null and b/frontend/src/images/tournament/player.png differ
diff --git a/frontend/src/images/tournament/pong.jpg b/frontend/src/images/tournament/pong.jpg
new file mode 100644
index 000000000..c16a264d5
Binary files /dev/null and b/frontend/src/images/tournament/pong.jpg differ
diff --git a/frontend/src/pages/Games/Pong3D.js b/frontend/src/pages/Games/Pong3D.js
index 088ac94c9..d19da650d 100644
--- a/frontend/src/pages/Games/Pong3D.js
+++ b/frontend/src/pages/Games/Pong3D.js
@@ -28,8 +28,8 @@ function Pong3D() {
map: textureLoader.load(venus),
reflectivity: 1,
});
- const [gameOver, setGameOver] = React.useState(false);
- const [returnCounter, setBounceCounter] = useState(0);
+ const [gameOver] = React.useState(false);
+ const [returnCounter] = useState(0);
const asteroidGeometry = new THREE.SphereGeometry(1, 32, 32);
const asteroids = [];
@@ -44,7 +44,7 @@ function Pong3D() {
let leftPaddlePosition = 0;
let bounceCounter = 0;
let isCodeExecuted = false;
- let lifes = 7;
+ var lifes = 7;
class Asteroid {
constructor(x, y, radius, currentWayPoint, scene) {
@@ -402,11 +402,11 @@ function Pong3D() {
if (leftPaddleBoundingBox.intersectsBox(ballBoundingBox)) {
// eslint-disable-next-line react-hooks/exhaustive-deps
if (!isCodeExecuted) {
- // eslint-disable-next-line react-hooks/exhaustive-deps
+ // eslint-disable-next-line react-hooks/exhaustive-deps
bounceCounter = bounceCounter + 1;
- // eslint-disable-next-line react-hooks/exhaustive-deps
+ // eslint-disable-next-line react-hooks/exhaustive-deps
ballSpeed += 0.02;
- // eslint-disable-next-line react-hooks/exhaustive-deps
+ // eslint-disable-next-line react-hooks/exhaustive-deps
leftPaddleSpeedConst += 0.005;
bounceContext.clearRect(
0,
@@ -416,7 +416,7 @@ function Pong3D() {
);
bounceContext.fillText("BOUNCE COUNT: " + bounceCounter, 6, 24);
bounceMaterialTexture.needsUpdate = true;
- // eslint-disable-next-line react-hooks/exhaustive-deps
+ // eslint-disable-next-line react-hooks/exhaustive-deps
isCodeExecuted = true;
} else {
isCodeExecuted = false;
@@ -435,22 +435,23 @@ function Pong3D() {
ball.position.x = 0;
ball.position.y = 0;
// eslint-disable-next-line react-hooks/exhaustive-deps
- lifes = orbits.length - 1;
- if (orbits.length === 0) {
- if (orbits.length === 0) {
- setGameOver(true);
- setBounceCounter(bounceCounter);
- ballSpeed = 0;
- }
- }
- if (orbits.length > 0) {
- scene.remove(orbits[orbits.length - 1]);
- orbits.pop();
- ball.material = planetMaterials[lifes];
- ball.material.needsUpdate = true;
- ballSpeed = 0.3;
- leftPaddleSpeedConst = 0.5;
- }
+ // lifes = orbits.length - 1;
+ // if (orbits.length === 0) {
+ // // setGameOver(true);
+ // setBounceCounter(bounceCounter);
+ // ballSpeed = 0;
+ // }
+ // if (orbits.length > 0) {
+ // scene.remove(orbits[orbits.length - 1]);
+ // orbits.pop();
+
+ ball.material =
+ planetMaterials[Math.floor(Math.random() * (lifes + 1))];
+ ball.material.needsUpdate = true;
+ // ballSpeed = 0.3;
+ // leftPaddleSpeedConst = 0.5;
+ // }
+
pointLight.intensity += 50;
pointLight.distance += 10;
} else ballDirection.y *= -1;
@@ -531,7 +532,7 @@ function Pong3D() {
if (isSKeyPressed) {
leftPaddlePosition -= leftPaddleSpeedConst;
}
- // eslint-disable-next-line react-hooks/exhaustive-deps
+ // eslint-disable-next-line react-hooks/exhaustive-deps
leftPaddlePosition = Math.max(
-wallOffsetY + paddleHeight / 2 + wallThickness / 2,
Math.min(
diff --git a/frontend/src/pages/Games/PongAi.js b/frontend/src/pages/Games/PongAi.js
index 019aad5d4..6a794bf79 100644
--- a/frontend/src/pages/Games/PongAi.js
+++ b/frontend/src/pages/Games/PongAi.js
@@ -281,7 +281,7 @@ const GameCanvas = (aiDifficulty) => {
if (canvasRef.current && event.touches.length > 0) {
const rect = canvasRef.current.getBoundingClientRect();
const touchY = event.touches[0].clientY - rect.top - window.scrollY;
- // eslint-disable-next-line react-hooks/exhaustive-deps
+ // eslint-disable-next-line react-hooks/exhaustive-deps
leftPaddleY = touchY - paddleHeight / 2;
leftPaddleY = Math.max(
0,
@@ -395,19 +395,36 @@ const PongAi = () => {
-
Level: {difficulty}
-
-
setGameDifficulty(parseInt(e.target.value))}
- style={{
- width: "150px",
- height: "25px",
- }}
- />
+
+
+ Level: {difficulty}
+
+
+ setGameDifficulty(parseInt(e.target.value))}
+ style={{
+ fontSize: "30px",
+ width: "200px",
+ height: "25px",
+ border: "none",
+ borderRadius: "5px",
+ outline: "none",
+ backgroundColor: "#444",
+ }}
+ />
+
diff --git a/frontend/src/pages/Games/Tournament.js b/frontend/src/pages/Games/Tournament.js
index 02999b504..4eb82e3e2 100644
--- a/frontend/src/pages/Games/Tournament.js
+++ b/frontend/src/pages/Games/Tournament.js
@@ -1,14 +1,1310 @@
-import React, { useEffect, useRef, useState } from "react";
+import React, { useRef, useEffect, useState } from "react";
import backgroundImage from "../../images/pongbg.png";
-import { useLocation, useNavigate } from "react-router-dom";
+import { useNavigate } from "react-router-dom";
import BackButton from "../../components/buttons/BackButton";
import { useTranslation } from "react-i18next";
import { WelcomeButtonStyle } from "../../components/buttons/ButtonStyle";
-import LoseScreen from "../../components/game/LoseScreen";
-import WinScreen from "../../components/game/WinScreen";
-import handleResize from "../../components/game/HandleResize";
-import FullScreenButton from "../../components/buttons/FullScreen";
+import babyPic from "../../images/tournament/baby.png";
+import mediumPic from "../../images/tournament/balanced.png";
+import insanePic from "../../images/tournament/insane.png";
+import playerPic from "../../images/tournament/player.png";
+import eliminate from "../../images/tournament/eliminate.png";
+import playPong from "../../images/tournament/pong.jpg";
-const Tournament = () => { };
+class Match {
+ constructor(player1, player2) {
+ this.player1 = player1;
+ this.player2 = player2;
+ this.scorePlayer1 = 0;
+ this.scorePlayer2 = 0;
+ this.winner = null;
+ this.matchId = null;
+ }
-export default Tournament;
\ No newline at end of file
+ playMatch() {}
+}
+
+class Player {
+ constructor(name, mode) {
+ this.name = name;
+ this.mode = mode;
+ this.picture = this.setPicture(mode);
+ this.score = 0;
+ this.x = Math.random();
+ this.y = Math.random();
+ this.matchHistory = [];
+ }
+ setPicture(mode) {
+ let picture;
+ switch (mode) {
+ case 0:
+ picture = playerPic;
+ break;
+ case 1:
+ picture = babyPic;
+ break;
+ case 2:
+ picture = mediumPic;
+ break;
+ case 3:
+ picture = insanePic;
+ break;
+ default:
+ picture = playerPic;
+ break;
+ }
+ return picture;
+ }
+}
+
+class TournamentData {
+ constructor(players, mode) {
+ this.players = players;
+ this.roundCount = 0;
+ this.currentMatch = 0;
+ this.currentRound = 0;
+ this.mode = 0;
+ this.matches = [];
+ this.matchHistory = [];
+ this.randomizePlayerOrder();
+ switch (mode) {
+ case 0:
+ this.createRoundRobin();
+ break;
+ case 1:
+ this.createSingleElimination();
+ break;
+ case 2:
+ this.createSwiss();
+ break;
+ default:
+ this.createRoundRobin();
+ break;
+ }
+ }
+
+ randomizePlayerOrder() {
+ this.players.sort(() => Math.random() - 0.5);
+ }
+
+ sortPlayersByScore() {
+ this.players.sort((a, b) => b.score - a.score);
+ }
+
+ createSingleElimination() {}
+
+ createSwiss() {}
+
+ createRoundRobin() {
+ this.roundCount = 1;
+ this.currentRound = 1;
+ for (let i = 0; i < this.players.length; i++) {
+ for (let j = i + 1; j < this.players.length; j++) {
+ this.matches.push(new Match(this.players[i], this.players[j]));
+ }
+ }
+ }
+}
+
+const Tournament = () => {
+ const navigate = useNavigate();
+ const { t } = useTranslation();
+ const [pageToRender, setPageToRender] = useState(0);
+ const [listOfPlayers, setListOfPlayers] = useState([]);
+ const [tournamentName, setTournamentName] = useState("Round Robin");
+ const [tournament, setTournament] = useState(null);
+ const [arrowUp, setArrowUp] = useState(false);
+ const [arrowDown, setArrowDown] = useState(false);
+ const [wDown, setWDown] = useState(false);
+ const [sDown, setSDown] = useState(false);
+ const [playerModeToAdd, setPlayerModeToAdd] = useState(0);
+ const paddleWidth = 1;
+ const paddleHeight = 12;
+ let tournamentModeToAdd = 0;
+ const canvasRef = useRef(null);
+ const ctxRef = useRef(null);
+
+ function createTournamentButtonClicked() {
+ setPageToRender(1);
+ }
+
+ function startTournamentButtonPressed() {
+ if (listOfPlayers.length > 2) {
+ setPageToRender(2);
+ setTournament(new TournamentData(listOfPlayers, tournamentModeToAdd));
+ }
+ }
+
+ function playGameButtonPressed() {
+ setPageToRender(3);
+ }
+
+ function CanvasComponent() {
+ useEffect(() => {
+ const canvas = document.getElementById("selectionCanvas");
+ const ctx = canvas.getContext("2d");
+ const ratio = window.devicePixelRatio || 1;
+ canvas.width = canvas.offsetWidth * ratio;
+ canvas.height = canvas.offsetHeight * ratio;
+ ctx.scale(ratio, ratio);
+
+ for (let i = 0; i < listOfPlayers.length; i++) {
+ const player = listOfPlayers[i];
+ const img = new Image();
+
+ img.onload = function () {
+ const x = (player.x * canvas.width * 0.75) / 2;
+ const y = (player.y * canvas.height) / 2;
+ const textWidth = ctx.measureText(player.name).width;
+ ctx.drawImage(img, x, y, 32, 32);
+ ctx.fillStyle = "white";
+ ctx.fillText(player.name, x - textWidth / 2 + 16, y - 20);
+ };
+ img.src = player.picture;
+ }
+ }, []);
+ return (
+
+ );
+ }
+
+ function tournamentMode(input) {
+ const buttonData = [
+ { id: 0, imgSrc: playerPic, alt: "Round Robin" },
+ { id: 1, imgSrc: babyPic, alt: "Single Elimination" },
+ { id: 2, imgSrc: mediumPic, alt: "Swiss" },
+ ];
+ for (let i = 0; i < 3; i++) {
+ const button = document.getElementById("buttonMode" + i);
+ button.style.width = "12%";
+ button.style.height = "90%";
+ }
+ tournamentModeToAdd = input;
+ setTournamentName(buttonData[input].alt);
+ const selectedButton = document.getElementById("buttonMode" + input);
+ selectedButton.style.width = "14%";
+ selectedButton.style.height = "100%";
+ }
+
+ function selectButton(input) {
+ for (let i = 0; i < 4; i++) {
+ const button = document.getElementById("button" + i);
+ button.style.width = "12%";
+ button.style.height = "90%";
+ }
+ setPlayerModeToAdd(input);
+ const selectedButton = document.getElementById("button" + input);
+ selectedButton.style.width = "14%";
+ selectedButton.style.height = "100%";
+ }
+
+ function addPlayer() {
+ const input = document.querySelector("input");
+ const name = input.value;
+ if (name === "") {
+ return;
+ }
+ for (let i = 0; i < listOfPlayers.length; i++) {
+ const player = listOfPlayers[i];
+ if (player.name === name) {
+ return;
+ }
+ }
+ setListOfPlayers((prevPlayers) => [
+ ...prevPlayers,
+ new Player(name, playerModeToAdd),
+ ]);
+ }
+
+ function removePlayer(index) {
+ setListOfPlayers((prevPlayers) =>
+ prevPlayers.filter((player, i) => i !== index)
+ );
+ }
+
+ function displayCurrentMatch() {
+ if (tournament.matches.length === 0)
+ return No Matches
;
+ const match = tournament.matches[tournament.currentMatch];
+ return (
+
+
+
{match.player1.name}
+
+
+
{match.player2.name}
+
+
+ );
+ }
+
+ function renderMatches(matches) {
+ const listOfMatches = [];
+
+ for (let i = 0; i < matches.length; i++) {
+ const match = matches[i];
+ listOfMatches.push(
+
+
+
{match.player1.name}
+ {match.scorePlayer1}
+
+
+
{match.player2.name}
+ {match.scorePlayer2}
+
+
+ );
+ }
+ return listOfMatches;
+ }
+
+ function renderPlayersTournament() {
+ const playerElements = [];
+
+ for (let i = 0; i < tournament.players.length; i++) {
+ playerElements.push(
+
+ );
+ }
+ return playerElements;
+ }
+
+ function tournomentButtons(functionToCall, text, imgSrc, alt) {
+ return (
+
+
+
+ {text}
+
+
+ );
+ }
+
+ function tournamentPage() {
+ return (
+
+
+
+
+
+ LeaderBoards
+
+
+ {renderPlayersTournament()}
+
+
+
+
+ Round {tournament.currentRound} of {tournament.roundCount}
+
+
+ {renderMatches(tournament.matches)}
+
+
+
+
+ Match History
+
+
+ {renderMatches(tournament.matchHistory)}
+
+
+
+
+ {tournamentName}
+
+
+ {tournomentButtons(
+ playGameButtonPressed,
+ "Play Match",
+ playPong,
+ "Play"
+ )}
+
+
+
+ Next Match
+
+
+ {displayCurrentMatch()}
+
+
+
+ );
+ }
+
+ function renderPlayers() {
+ const playerElements = [];
+
+ for (let i = 0; i < listOfPlayers.length; i++) {
+ playerElements.push(
+
+
![{listOfPlayers[i].name}]({listOfPlayers[i].picture})
+
+ {listOfPlayers[i].name}
+
+
+
+ );
+ }
+
+ return playerElements;
+ }
+
+ function renderTournamentMode() {
+ const buttonData = [
+ { id: 0, imgSrc: playerPic, alt: "Round Robin" },
+ { id: 1, imgSrc: babyPic, alt: "Single Elimination" },
+ { id: 2, imgSrc: mediumPic, alt: "Swiss" },
+ ];
+
+ return (
+
+ {buttonData.map((button) => (
+
+ ))}
+
+ );
+ }
+
+ function renderButtons() {
+ const buttonData = [
+ { id: 0, imgSrc: playerPic, alt: "Player" },
+ { id: 1, imgSrc: babyPic, alt: "BabyBot" },
+ { id: 2, imgSrc: mediumPic, alt: "MediumBot" },
+ { id: 3, imgSrc: insanePic, alt: "InsaneBot" },
+ ];
+
+ return (
+
+ {buttonData.map((button) => (
+
+ ))}
+
+ );
+ }
+
+ function selectionPage() {
+ return (
+
+
+
+
+
+
+
+
+
+ {renderButtons()}
+
+
+ Choose tournament Mode
+
+ {renderTournamentMode()}
+
+
+ {renderPlayers()}
+
+
+
+
+ );
+ }
+
+ function startPage() {
+ return (
+
+
+
![Background]({backgroundImage})
+
+
+
+
+
+
+ );
+ }
+
+ const arrowUpRef = useRef(arrowUp);
+ const arrowDownRef = useRef(arrowDown);
+ const wDownRef = useRef(wDown);
+ const sDownRef = useRef(sDown);
+ var paddleSpeed = 1;
+ var leftPaddlePos = 50;
+ var rightPaddlePos = 50;
+ var ballSpeed = 0.9;
+ var ballX = 50;
+ var ballY = 50;
+ var ballDirX = 1;
+ var ballDirY = 0;
+ var scorePlayer1 = 0;
+ var scorePlayer2 = 0;
+
+ function resultPage() {
+ tournament.sortPlayersByScore();
+ return (
+
+
+
+ {renderPlayersTournament()}
+
+
+
+
+ );
+ }
+
+ useEffect(() => {
+ if (pageToRender === 3) {
+ const canvas = canvasRef.current;
+ const ctx = canvas.getContext("2d");
+ const ratio = window.devicePixelRatio || 1;
+ canvas.width = canvas.offsetWidth * ratio;
+ canvas.height = canvas.offsetHeight * ratio;
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ ballX = canvas.width / 2;
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ ballY = canvas.height / 2;
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ ballSpeed = 0.9;
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ scorePlayer1 = 0;
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ scorePlayer2 = 0;
+ ctxRef.current = ctx;
+ const interval = setInterval(() => update(canvas, ctx), 1000 / 30);
+ return () => clearInterval(interval);
+ }
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, [pageToRender]);
+
+ useEffect(() => {
+ arrowUpRef.current = arrowUp;
+ arrowDownRef.current = arrowDown;
+ wDownRef.current = wDown;
+ sDownRef.current = sDown;
+ }, [arrowUp, arrowDown, wDown, sDown]);
+
+ const updateResults = () => {
+ const match = tournament.matches[tournament.currentMatch];
+ match.winner = scorePlayer1 > scorePlayer2 ? match.player1 : match.player2;
+ match.matchId = tournament.currentMatch;
+ if (match.player1.score > match.player2.score) match.player1.score += 1;
+ else match.player2.score += 1;
+ match.scorePlayer1 = scorePlayer1;
+ match.scorePlayer2 = scorePlayer2;
+ tournament.matchHistory.push(match);
+ tournament.matches.splice(tournament.currentMatch, 1);
+ tournament.sortPlayersByScore();
+ };
+
+ const updateBall = (ctx, canvas) => {
+ ballX += (ballSpeed * ballDirX * canvas.width) / 100;
+ ballY += (ballSpeed * ballDirY * canvas.height) / 100;
+ if (ballY <= 0 || ballY >= canvas.height) ballDirY *= -1;
+ if (ballY <= 0) ballY = 25;
+ if (ballY >= canvas.height) ballY = canvas.height - 25;
+
+ if (ballX <= (paddleWidth * canvas.width) / 100) {
+ if (
+ ballY >= (leftPaddlePos * canvas.height) / 100 &&
+ ballY <= ((leftPaddlePos + paddleHeight) * canvas.height) / 100
+ ) {
+ ballDirY =
+ 2 *
+ ((ballY - (leftPaddlePos * canvas.height) / 100) /
+ ((paddleHeight * canvas.height) / 100)) -
+ 1;
+ ballDirX *= -1;
+ ballSpeed += 0.05;
+ ballX = (paddleWidth * canvas.width) / 100;
+ }
+ }
+ if (ballX >= canvas.width - (paddleWidth * canvas.width) / 100) {
+ if (
+ ballY >= (rightPaddlePos * canvas.height) / 100 &&
+ ballY <= ((rightPaddlePos + paddleHeight) * canvas.height) / 100
+ ) {
+ ballDirY =
+ 2 *
+ ((ballY - (rightPaddlePos * canvas.height) / 100) /
+ ((paddleHeight * canvas.height) / 100)) -
+ 1;
+ ballDirX *= -1;
+ ballSpeed += 0.05;
+ ballX = canvas.width - (paddleWidth * canvas.width) / 100;
+ }
+ }
+ if (ballX <= 0 || ballX >= canvas.width) {
+ if (ballX <= 0) scorePlayer2++;
+ if (ballX >= canvas.width) scorePlayer1++;
+ ballX = canvas.width / 2;
+ ballY = canvas.height / 2;
+ ballDirX = ballDirX * -1;
+ ballDirY = 0;
+ ballSpeed = 0.9;
+ if (scorePlayer1 >= 2 || scorePlayer2 >= 2) {
+ ballSpeed = 0;
+ updateResults();
+ if (tournament.matches.length !== 0) setPageToRender(2);
+ else setPageToRender(4);
+ }
+ }
+ ctx.beginPath();
+ ctx.arc(ballX, ballY, canvas.height / 100, 0, Math.PI * 2, false);
+ ctx.fill();
+ };
+
+ const updatePaddlesPlayer1 = () => {
+ if (wDownRef.current)
+ if (leftPaddlePos - paddleSpeed >= 0) leftPaddlePos -= paddleSpeed;
+ if (sDownRef.current)
+ if (leftPaddlePos + paddleSpeed <= 100 - paddleHeight)
+ leftPaddlePos += paddleSpeed;
+ };
+
+ const updatePaddlesPlayer2 = () => {
+ if (arrowUpRef.current)
+ if (rightPaddlePos - paddleSpeed >= 0) rightPaddlePos -= paddleSpeed;
+ if (arrowDownRef.current)
+ if (rightPaddlePos + paddleSpeed <= 100 - paddleHeight)
+ rightPaddlePos += paddleSpeed;
+ };
+
+ const drawPaddles = (ctx, canvas) => {
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
+ ctx.fillStyle = "white";
+ ctx.fillRect(
+ 0,
+ (leftPaddlePos / 100) * canvas.height,
+ (paddleWidth * canvas.width) / 100,
+ (paddleHeight / 100) * canvas.height
+ );
+ ctx.fillRect(
+ canvas.width - (paddleWidth * canvas.width) / 100,
+ (rightPaddlePos / 100) * canvas.height,
+ (paddleWidth * canvas.width) / 100,
+ (paddleHeight / 100) * canvas.height
+ );
+ let lineLen = canvas.width / 40 - 2;
+ for (let i = 0; i < 22; i++) {
+ if (i % 2 === 0) continue;
+ ctx.fillRect((canvas.width - 5) / 2, i * lineLen, 10, lineLen);
+ }
+ };
+
+ const updatePaddlesBabyBot1 = (canvas) => {
+ if (
+ ballY + (ballDirY / 15) * canvas.height <
+ ((leftPaddlePos + paddleHeight / 2) * canvas.height) / 100
+ )
+ leftPaddlePos -= paddleSpeed;
+ if (
+ ballY + (ballDirY / 15) * canvas.height >
+ ((leftPaddlePos + paddleHeight / 2) * canvas.height) / 100
+ )
+ leftPaddlePos += paddleSpeed;
+ if (leftPaddlePos < 0) leftPaddlePos = 0;
+ if (leftPaddlePos > 100 - paddleHeight) leftPaddlePos = 100 - paddleHeight;
+ };
+
+ const updatePaddlesBabyBot2 = (canvas) => {
+ if (
+ ballY + (ballDirY / 15) * canvas.height <
+ ((rightPaddlePos + paddleHeight / 2) * canvas.height) / 100
+ )
+ rightPaddlePos -= paddleSpeed;
+ if (
+ ballY + (ballDirY / 15) * canvas.height >
+ ((rightPaddlePos + paddleHeight / 2) * canvas.height) / 100
+ )
+ rightPaddlePos += paddleSpeed;
+ if (rightPaddlePos < 0) rightPaddlePos = 0;
+ if (rightPaddlePos > 100 - paddleHeight)
+ rightPaddlePos = 100 - paddleHeight;
+ };
+
+ const updatePaddlesMediumBot1 = (canvas) => {
+ if (ballY < ((leftPaddlePos + paddleHeight / 2) * canvas.height) / 100)
+ leftPaddlePos -= paddleSpeed;
+ if (ballY > ((leftPaddlePos + paddleHeight / 2) * canvas.height) / 100)
+ leftPaddlePos += paddleSpeed;
+ if (leftPaddlePos < 0) leftPaddlePos = 0;
+ if (leftPaddlePos > 100 - paddleHeight) leftPaddlePos = 100 - paddleHeight;
+ };
+
+ const updatePaddlesMediumBot2 = (canvas) => {
+ if (ballY < ((rightPaddlePos + paddleHeight / 2) * canvas.height) / 100)
+ rightPaddlePos -= paddleSpeed;
+ if (ballY > ((rightPaddlePos + paddleHeight / 2) * canvas.height) / 100)
+ rightPaddlePos += paddleSpeed;
+ if (rightPaddlePos < 0) rightPaddlePos = 0;
+ if (rightPaddlePos > 100 - paddleHeight)
+ rightPaddlePos = 100 - paddleHeight;
+ };
+
+ const updatePaddlesInsaneBot1 = (canvas) => {
+ let estimateTime = Math.abs(ballX) / ((ballSpeed * canvas.width) / 100);
+ let estimatePostionY =
+ ballY + (ballDirY * estimateTime * canvas.height * ballSpeed) / 100;
+ if (estimatePostionY > canvas.height)
+ estimatePostionY = Math.abs(
+ canvas.height - (estimatePostionY % canvas.height)
+ );
+ else if (estimatePostionY < 0)
+ estimatePostionY = Math.abs(estimatePostionY % canvas.height);
+ else estimatePostionY = Math.abs(estimatePostionY);
+ if (
+ estimatePostionY + 30 <
+ ((leftPaddlePos + paddleHeight / 2) * canvas.height) / 100
+ )
+ leftPaddlePos -= paddleSpeed;
+ else if (
+ estimatePostionY - 30 >
+ ((leftPaddlePos + paddleHeight / 2) * canvas.height) / 100
+ )
+ leftPaddlePos += paddleSpeed;
+ if (leftPaddlePos < 0) leftPaddlePos = 0;
+ if (leftPaddlePos > 100 - paddleHeight) leftPaddlePos = 100 - paddleHeight;
+ };
+
+ const updatePaddlesInsaneBot2 = (canvas) => {
+ let estimateTime =
+ Math.abs(canvas.width - ballX) / ((ballSpeed * canvas.width) / 100);
+ let estimatePostionY =
+ ballY + (ballDirY * estimateTime * canvas.height * ballSpeed) / 100;
+ if (estimatePostionY > canvas.height)
+ estimatePostionY = Math.abs(
+ canvas.height - (estimatePostionY % canvas.height)
+ );
+ else if (estimatePostionY < 0)
+ estimatePostionY = Math.abs(estimatePostionY % canvas.height);
+ else estimatePostionY = Math.abs(estimatePostionY);
+ if (
+ estimatePostionY + 30 <
+ ((rightPaddlePos + paddleHeight / 2) * canvas.height) / 100
+ )
+ rightPaddlePos -= paddleSpeed;
+ else if (
+ estimatePostionY - 30 >
+ ((rightPaddlePos + paddleHeight / 2) * canvas.height) / 100
+ )
+ rightPaddlePos += paddleSpeed;
+ if (rightPaddlePos < 0) rightPaddlePos = 0;
+ if (rightPaddlePos > 100 - paddleHeight)
+ rightPaddlePos = 100 - paddleHeight;
+ };
+
+ const drawScore = (ctx, canvas) => {
+ if (tournament.matches.length === 0) return;
+ ctx.fillStyle = "white";
+ ctx.font = "50px Nosifer";
+ let text =
+ tournament.matches[tournament.currentMatch].player1.name +
+ " Score:" +
+ scorePlayer1;
+ let textMetrics = ctx.measureText(text);
+ ctx.fillText(text, canvas.width / 4 - textMetrics.width / 2, 120);
+ text =
+ tournament.matches[tournament.currentMatch].player2.name +
+ " Score:" +
+ scorePlayer2;
+ textMetrics = ctx.measureText(text);
+ ctx.fillText(text, (canvas.width * 3) / 4 - textMetrics.width / 2, 120);
+ };
+
+ const paddlesToRender = (canvas) => {
+ switch (tournament.matches[tournament.currentMatch].player1.mode) {
+ case 0:
+ updatePaddlesPlayer1();
+ break;
+ case 1:
+ updatePaddlesBabyBot1(canvas);
+ break;
+ case 2:
+ updatePaddlesMediumBot1(canvas);
+ break;
+ case 3:
+ updatePaddlesInsaneBot1(canvas);
+ break;
+ default:
+ updatePaddlesPlayer1();
+ break;
+ }
+ switch (tournament.matches[tournament.currentMatch].player2.mode) {
+ case 0:
+ updatePaddlesPlayer2();
+ break;
+ case 1:
+ updatePaddlesBabyBot2(canvas);
+ break;
+ case 2:
+ updatePaddlesMediumBot2(canvas);
+ break;
+ case 3:
+ updatePaddlesInsaneBot2(canvas);
+ break;
+ default:
+ updatePaddlesPlayer2();
+ break;
+ }
+ };
+
+ const update = (canvas, ctx) => {
+ paddlesToRender(canvas);
+ drawPaddles(ctx, canvas);
+ updateBall(ctx, canvas);
+ drawScore(ctx, canvas);
+ };
+
+ const handleKeyDown = (e) => {
+ if (e.key === "ArrowUp") setArrowUp(true);
+ if (e.key === "ArrowDown") setArrowDown(true);
+ if (e.key === "w") setWDown(true);
+ if (e.key === "s") setSDown(true);
+ };
+
+ const handleKeyUp = (event) => {
+ if (event.key === "ArrowUp") setArrowUp(false);
+ if (event.key === "ArrowDown") setArrowDown(false);
+ if (event.key === "w") setWDown(false);
+ if (event.key === "s") setSDown(false);
+ };
+
+ useEffect(() => {
+ window.addEventListener("keydown", handleKeyDown);
+ window.addEventListener("keyup", handleKeyUp);
+
+ return () => {
+ window.removeEventListener("keydown", handleKeyDown);
+ window.removeEventListener("keyup", handleKeyUp);
+ };
+ }, []);
+
+ function gamePage(match) {
+ return (
+
+ );
+ }
+
+ switch (pageToRender) {
+ case 0:
+ return startPage();
+ case 1:
+ return selectionPage();
+ case 2:
+ return tournamentPage();
+ case 3:
+ return gamePage(tournament.matches[tournament.currentMatch]);
+ case 4:
+ return resultPage();
+ default:
+ return startPage();
+ }
+};
+
+export default Tournament;