From e6f6732eaa0f9248ab9f9332179f2d4d867a1ce8 Mon Sep 17 00:00:00 2001 From: Flatlogic Bot Date: Wed, 1 Oct 2025 21:58:29 +0000 Subject: [PATCH] Add score functionality and game timer --- assets/css/custom.css | 54 ++++++++++++++++++++++++++++++++ assets/js/main.js | 71 ++++++++++++++++++++++++++++++++++++++----- game.php | 9 ++++++ 3 files changed, 127 insertions(+), 7 deletions(-) diff --git a/assets/css/custom.css b/assets/css/custom.css index b232bf2..126a7fc 100644 --- a/assets/css/custom.css +++ b/assets/css/custom.css @@ -8,4 +8,58 @@ font-family: sans-serif; font-weight: bold; text-shadow: 2px 2px 4px #000000; +} + +#timer { + position: absolute; + top: 60px; /* Below the scoreboard */ + left: 50%; + transform: translateX(-50%); + font-size: 30px; + color: white; + font-family: sans-serif; + font-weight: bold; + text-shadow: 2px 2px 4px #000000; +} + +#game-over-modal { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-color: rgba(0, 0, 0, 0.7); + display: flex; + justify-content: center; + align-items: center; + color: white; + font-family: sans-serif; +} + +#game-over-content { + text-align: center; + background-color: #333; + padding: 40px; + border-radius: 10px; +} + +#game-over-content h2 { + font-size: 50px; + margin-bottom: 20px; +} + +#game-over-content p { + font-size: 24px; + margin-bottom: 10px; +} + +#restart-button { + margin-top: 20px; + padding: 15px 30px; + font-size: 20px; + cursor: pointer; + border: none; + border-radius: 5px; + background-color: #4CAF50; + color: white; } \ No newline at end of file diff --git a/assets/js/main.js b/assets/js/main.js index 631e469..35237ba 100644 --- a/assets/js/main.js +++ b/assets/js/main.js @@ -36,6 +36,15 @@ class Game { this.redScoreEl = document.getElementById('red-score'); this.blueScoreEl = document.getElementById('blue-score'); this.isGoalScored = false; + this.goalCooldown = 0; + this.timer = 30; + this.gameOver = false; + this.timerEl = document.getElementById('timer'); + this.gameOverModal = document.getElementById('game-over-modal'); + this.finalScoreEl = document.getElementById('final-score'); + this.winnerEl = document.getElementById('winner'); + this.restartButton = document.getElementById('restart-button'); + this.restartButton.addEventListener('click', () => this.restartGame()); this.animate(); } @@ -274,6 +283,7 @@ class Game { handleGoal(scoringTeam) { if (this.isGoalScored) return; this.isGoalScored = true; + this.goalCooldown = 60; // 60 frames ~ 1 second if (scoringTeam === 'red') { this.score.blue++; @@ -283,16 +293,47 @@ class Game { this.updateScoreboard(); const losingTeam = scoringTeam === 'red' ? 'blue' : 'red'; + this.resetPositions(losingTeam); + } - setTimeout(() => { - this.resetPositions(losingTeam); - this.isGoalScored = false; - }, 1000); // 1-second delay + updateTimer() { + if (this.gameOver) return; + + this.timer -= 1 / 60; // Assuming 60 FPS + this.timerEl.textContent = Math.ceil(this.timer); + + if (this.timer <= 0) { + this.endGame(); + } + } + + endGame() { + this.gameOver = true; + this.gameOverModal.style.display = 'flex'; + + let winner; + if (this.score.red > this.score.blue) { + winner = 'Red Team Wins!'; + } else if (this.score.blue > this.score.red) { + winner = 'Blue Team Wins!'; + } else { + winner = "It's a draw!"; + } + + this.finalScoreEl.textContent = `Final Score: ${this.score.red} - ${this.score.blue}`; + this.winnerEl.textContent = winner; + } + + restartGame() { + this.gameOver = false; + this.timer = 30; + this.score = { red: 0, blue: 0 }; + this.updateScoreboard(); + this.gameOverModal.style.display = 'none'; + this.resetPositions(); } checkCollisions() { - if (this.isGoalScored) return; - const ballPos = this.ball.mesh.position; const ballRadius = 0.8; // Corrected from this.ball.radius const fieldWidth = 60; @@ -333,10 +374,26 @@ class Game { animate() { requestAnimationFrame(() => this.animate()); + if (this.gameOver) { + this.renderer.render(this.scene, this.camera); + return; + } + + this.updateTimer(); + + if (this.goalCooldown > 0) { + this.goalCooldown--; + if (this.goalCooldown === 0) { + this.isGoalScored = false; + } + } + this.updatePlayerPosition(); this.updateAIPlayers(); this.updateBall(); - this.checkCollisions(); + if (!this.isGoalScored) { + this.checkCollisions(); + } // Camera follows player from the sideline this.camera.position.z = this.player.mesh.position.z; diff --git a/game.php b/game.php index b42638c..787340e 100644 --- a/game.php +++ b/game.php @@ -14,6 +14,15 @@
0 - 0
+
30
+