Add score functionality and game timer

This commit is contained in:
Flatlogic Bot 2025-10-01 21:58:29 +00:00
parent 794387fa46
commit e6f6732eaa
3 changed files with 127 additions and 7 deletions

View File

@ -9,3 +9,57 @@
font-weight: bold; font-weight: bold;
text-shadow: 2px 2px 4px #000000; 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;
}

View File

@ -36,6 +36,15 @@ class Game {
this.redScoreEl = document.getElementById('red-score'); this.redScoreEl = document.getElementById('red-score');
this.blueScoreEl = document.getElementById('blue-score'); this.blueScoreEl = document.getElementById('blue-score');
this.isGoalScored = false; 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(); this.animate();
} }
@ -274,6 +283,7 @@ class Game {
handleGoal(scoringTeam) { handleGoal(scoringTeam) {
if (this.isGoalScored) return; if (this.isGoalScored) return;
this.isGoalScored = true; this.isGoalScored = true;
this.goalCooldown = 60; // 60 frames ~ 1 second
if (scoringTeam === 'red') { if (scoringTeam === 'red') {
this.score.blue++; this.score.blue++;
@ -283,16 +293,47 @@ class Game {
this.updateScoreboard(); this.updateScoreboard();
const losingTeam = scoringTeam === 'red' ? 'blue' : 'red'; const losingTeam = scoringTeam === 'red' ? 'blue' : 'red';
this.resetPositions(losingTeam);
}
setTimeout(() => { updateTimer() {
this.resetPositions(losingTeam); if (this.gameOver) return;
this.isGoalScored = false;
}, 1000); // 1-second delay 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() { checkCollisions() {
if (this.isGoalScored) return;
const ballPos = this.ball.mesh.position; const ballPos = this.ball.mesh.position;
const ballRadius = 0.8; // Corrected from this.ball.radius const ballRadius = 0.8; // Corrected from this.ball.radius
const fieldWidth = 60; const fieldWidth = 60;
@ -333,10 +374,26 @@ class Game {
animate() { animate() {
requestAnimationFrame(() => this.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.updatePlayerPosition();
this.updateAIPlayers(); this.updateAIPlayers();
this.updateBall(); this.updateBall();
this.checkCollisions(); if (!this.isGoalScored) {
this.checkCollisions();
}
// Camera follows player from the sideline // Camera follows player from the sideline
this.camera.position.z = this.player.mesh.position.z; this.camera.position.z = this.player.mesh.position.z;

View File

@ -14,6 +14,15 @@
<div id="scoreboard"> <div id="scoreboard">
<span id="red-score">0</span> - <span id="blue-score">0</span> <span id="red-score">0</span> - <span id="blue-score">0</span>
</div> </div>
<div id="timer">30</div>
<div id="game-over-modal" style="display: none;">
<div id="game-over-content">
<h2>Game Over</h2>
<p id="final-score"></p>
<p id="winner"></p>
<button id="restart-button">Restart Game</button>
</div>
</div>
<script type="importmap"> <script type="importmap">
{ {
"imports": { "imports": {