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].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 +
+ +
+ +
+
+ ); + } + + 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;