diff --git a/core/templates/base.html b/core/templates/base.html index ae0fe7e..11d2670 100644 --- a/core/templates/base.html +++ b/core/templates/base.html @@ -27,6 +27,6 @@ - + {% block scripts %}{% endblock %} diff --git a/core/templates/core/index.html b/core/templates/core/index.html index cea3883..ddab575 100644 --- a/core/templates/core/index.html +++ b/core/templates/core/index.html @@ -1,4 +1,5 @@ {% extends "base.html" %} +{% load static %} {% block title %}Orange Catcher - A Fun Arcade Game{% endblock %} @@ -45,4 +46,289 @@ +{% endblock %} + +{% block scripts %} + {% endblock %} \ No newline at end of file diff --git a/static/js/game.js b/static/js/game.js index 9fd816e..4a650f5 100644 --- a/static/js/game.js +++ b/static/js/game.js @@ -1,279 +1,280 @@ -document.addEventListener('DOMContentLoaded', () => { - const canvas = document.getElementById('gameCanvas'); - if (!canvas) { - console.error('Canvas element not found!'); +const canvas = document.getElementById('gameCanvas'); +if (!canvas) { + console.error('Canvas element not found!'); +} +const ctx = canvas.getContext('2d'); + +// Set fixed canvas size +canvas.width = 800; +canvas.height = 600; + +const audioCtx = new (window.AudioContext || window.webkitAudioContext)(); +let score = 0; +let lives = 3; +let gameOver = false; +let gameStarted = false; +let orangeInterval; + +const player = { + width: 100, + height: 50, + x: canvas.width / 2 - 50, + y: canvas.height - 60, + speed: 500, + dx: 0, + draw() { + ctx.fillStyle = '#8B4513'; + ctx.beginPath(); + ctx.moveTo(this.x, this.y); + ctx.lineTo(this.x + this.width, this.y); + ctx.lineTo(this.x + this.width - 15, this.y + this.height); + ctx.lineTo(this.x + 15, this.y + this.height); + ctx.closePath(); + ctx.fill(); + ctx.strokeStyle = '#5C2F0E'; + ctx.lineWidth = 8; + ctx.beginPath(); + ctx.moveTo(this.x, this.y); + ctx.lineTo(this.x + this.width, this.y); + ctx.stroke(); + } +}; + +const orangeProps = { + size: 20, + speed: 150, +}; +let oranges = []; + +function createOrange() { + oranges.push({ + x: Math.random() * (canvas.width - orangeProps.size), + y: -orangeProps.size, + size: orangeProps.size, + speed: orangeProps.speed + Math.random() * 100, + draw() { + ctx.beginPath(); + ctx.arc(this.x + this.size / 2, this.y + this.size / 2, this.size, 0, Math.PI * 2); + ctx.fillStyle = '#FFA500'; + ctx.fill(); + ctx.beginPath(); + ctx.ellipse(this.x + this.size / 2 + 5, this.y, 8, 3, Math.PI / 4, 0, Math.PI * 2); + ctx.fillStyle = '#228B22'; + ctx.fill(); + } + }); +} + +let lastTime = 0; + +function update(timestamp) { + if (!gameStarted) { return; } - const ctx = canvas.getContext('2d'); - // Set fixed canvas size - canvas.width = 800; - canvas.height = 600; - - const audioCtx = new (window.AudioContext || window.webkitAudioContext)(); - let score = 0; - let lives = 3; - let gameOver = false; - let gameStarted = false; - let orangeInterval; - - const player = { - width: 100, - height: 50, - x: canvas.width / 2 - 50, - y: canvas.height - 60, - speed: 500, - dx: 0, - draw() { - ctx.fillStyle = '#8B4513'; - ctx.beginPath(); - ctx.moveTo(this.x, this.y); - ctx.lineTo(this.x + this.width, this.y); - ctx.lineTo(this.x + this.width - 15, this.y + this.height); - ctx.lineTo(this.x + 15, this.y + this.height); - ctx.closePath(); - ctx.fill(); - ctx.strokeStyle = '#5C2F0E'; - ctx.lineWidth = 8; - ctx.beginPath(); - ctx.moveTo(this.x, this.y); - ctx.lineTo(this.x + this.width, this.y); - ctx.stroke(); - } - }; - - const orangeProps = { - size: 20, - speed: 150, - }; - let oranges = []; - - function createOrange() { - oranges.push({ - x: Math.random() * (canvas.width - orangeProps.size), - y: -orangeProps.size, - size: orangeProps.size, - speed: orangeProps.speed + Math.random() * 100, - draw() { - ctx.beginPath(); - ctx.arc(this.x + this.size / 2, this.y + this.size / 2, this.size, 0, Math.PI * 2); - ctx.fillStyle = '#FFA500'; - ctx.fill(); - ctx.beginPath(); - ctx.ellipse(this.x + this.size / 2 + 5, this.y, 8, 3, Math.PI / 4, 0, Math.PI * 2); - ctx.fillStyle = '#228B22'; - ctx.fill(); - } - }); + if (gameOver) { + drawGameOver(); + return; } - let lastTime = 0; + const deltaTime = (timestamp - lastTime) / 1000; + lastTime = timestamp; - function update(timestamp) { - if (!gameStarted) return; + ctx.clearRect(0, 0, canvas.width, canvas.height); + drawScene(); + player.draw(); + player.x += player.dx * player.speed * deltaTime; - if (gameOver) { - drawGameOver(); - return; + if (player.x < 0) player.x = 0; + if (player.x + player.width > canvas.width) { + player.x = canvas.width - player.width; + } + + oranges.forEach((orange, index) => { + orange.y += orange.speed * deltaTime; + orange.draw(); + + if ( + orange.y + orange.size > player.y && + orange.x < player.x + player.width && + orange.x + orange.size > player.x + ) { + score++; + playCatchSound(); + oranges.splice(index, 1); } - const deltaTime = (timestamp - lastTime) / 1000; - lastTime = timestamp; + if (orange.y > canvas.height) { + lives--; + oranges.splice(index, 1); + if (lives <= 0) { + gameOver = true; + } + } + }); + drawUI(); + requestAnimationFrame(update); +} + +function drawScene() { + ctx.fillStyle = '#0A192F'; + ctx.fillRect(0, 0, canvas.width, canvas.height); + ctx.fillStyle = '#228B22'; + ctx.fillRect(0, canvas.height - 20, canvas.width, 20); +} + +function drawUI() { + ctx.fillStyle = '#E6F1FF'; + ctx.font = '24px Poppins, sans-serif'; + ctx.textAlign = 'left'; + ctx.fillText(`Score: ${score}`, 20, 40); + ctx.textAlign = 'right'; + ctx.fillText(`Lives: ${lives}`, canvas.width - 20, 40); + ctx.textAlign = 'center'; +} + +function drawGameOver() { + clearInterval(orangeInterval); + ctx.fillStyle = 'rgba(0, 0, 0, 0.7)'; + ctx.fillRect(0, 0, canvas.width, canvas.height); + ctx.fillStyle = '#E6F1FF'; + ctx.font = '50px Poppins, sans-serif'; + ctx.textAlign = 'center'; + ctx.fillText('GAME OVER', canvas.width / 2, canvas.height / 2 - 40); + ctx.font = '30px Poppins, sans-serif'; + ctx.fillText(`Final Score: ${score}`, canvas.width / 2, canvas.height / 2 + 20); + ctx.font = '20px Poppins, sans-serif'; + ctx.fillText('Click to Restart', canvas.width / 2, canvas.height / 2 + 70); +} + +function drawInitialMessage() { + ctx.fillStyle = '#E6F1FF'; + ctx.font = '30px Poppins, sans-serif'; + ctx.textAlign = 'center'; + ctx.fillText('Click "Play Now" to Start!', canvas.width / 2, canvas.height / 2); +} + +function playCatchSound() { + if (!audioCtx) return; + const oscillator = audioCtx.createOscillator(); + const gainNode = audioCtx.createGain(); + oscillator.connect(gainNode); + gainNode.connect(audioCtx.destination); + oscillator.type = 'sine'; + oscillator.frequency.setValueAtTime(880, audioCtx.currentTime); + gainNode.gain.setValueAtTime(0.1, audioCtx.currentTime); + gainNode.gain.exponentialRampToValueAtTime(0.00001, audioCtx.currentTime + 0.5); + oscillator.start(audioCtx.currentTime); + oscillator.stop(audioCtx.currentTime + 0.5); +} + +async function updateLeaderboard() { + try { + const response = await fetch('/api/scores/'); + const scores = await response.json(); + const leaderboardBody = document.getElementById('leaderboard-body'); + leaderboardBody.innerHTML = ''; + scores.forEach((score, index) => { + const row = ` + ${index + 1} + ${score.player_name} + ${score.score} + `; + leaderboardBody.innerHTML += row; + }); + } catch (error) { + console.error('Error updating leaderboard:', error); + } +} + +function move(e) { + if (!gameStarted || gameOver) return; + if (e.key === 'ArrowRight' || e.key === 'd') { + player.dx = 1; + } else if (e.key === 'ArrowLeft' || e.key === 'a') { + player.dx = -1; + } +} + +function stopMove(e) { + if (['ArrowRight', 'd', 'ArrowLeft', 'a'].includes(e.key)) { + player.dx = 0; + } +} + +function initGame() { + score = 0; + lives = 3; + oranges = []; + gameOver = false; + gameStarted = false; + player.x = canvas.width / 2 - player.width / 2; + drawScene(); + drawInitialMessage(); +} + +function restartGame() { + score = 0; + lives = 3; + oranges = []; + gameOver = false; + player.x = canvas.width / 2 - player.width / 2; + startCountdown(); +} + +function startCountdown() { + let count = 3; + const countdown = setInterval(() => { ctx.clearRect(0, 0, canvas.width, canvas.height); drawScene(); - player.draw(); - player.x += player.dx * player.speed * deltaTime; - - if (player.x < 0) player.x = 0; - if (player.x + player.width > canvas.width) { - player.x = canvas.width - player.width; - } - - oranges.forEach((orange, index) => { - orange.y += orange.speed * deltaTime; - orange.draw(); - - if ( - orange.y + orange.size > player.y && - orange.x < player.x + player.width && - orange.x + orange.size > player.x - ) { - score++; - playCatchSound(); - oranges.splice(index, 1); - } - - if (orange.y > canvas.height) { - lives--; - oranges.splice(index, 1); - if (lives <= 0) { - gameOver = true; - } - } - }); - - drawUI(); - requestAnimationFrame(update); - } - - function drawScene() { - ctx.fillStyle = '#0A192F'; - ctx.fillRect(0, 0, canvas.width, canvas.height); - ctx.fillStyle = '#228B22'; - ctx.fillRect(0, canvas.height - 20, canvas.width, 20); - } - - function drawUI() { ctx.fillStyle = '#E6F1FF'; - ctx.font = '24px Poppins, sans-serif'; - ctx.textAlign = 'left'; - ctx.fillText(`Score: ${score}`, 20, 40); - ctx.textAlign = 'right'; - ctx.fillText(`Lives: ${lives}`, canvas.width - 20, 40); + ctx.font = '60px Poppins, sans-serif'; ctx.textAlign = 'center'; - } - - function drawGameOver() { - clearInterval(orangeInterval); - ctx.fillStyle = 'rgba(0, 0, 0, 0.7)'; - ctx.fillRect(0, 0, canvas.width, canvas.height); - ctx.fillStyle = '#E6F1FF'; - ctx.font = '50px Poppins, sans-serif'; - ctx.textAlign = 'center'; - ctx.fillText('GAME OVER', canvas.width / 2, canvas.height / 2 - 40); - ctx.font = '30px Poppins, sans-serif'; - ctx.fillText(`Final Score: ${score}`, canvas.width / 2, canvas.height / 2 + 20); - ctx.font = '20px Poppins, sans-serif'; - ctx.fillText('Click to Restart', canvas.width / 2, canvas.height / 2 + 70); - } - - function drawInitialMessage() { - ctx.fillStyle = '#E6F1FF'; - ctx.font = '30px Poppins, sans-serif'; - ctx.textAlign = 'center'; - ctx.fillText('Click "Play Now" to Start!', canvas.width / 2, canvas.height / 2); - } - - function playCatchSound() { - if (!audioCtx) return; - const oscillator = audioCtx.createOscillator(); - const gainNode = audioCtx.createGain(); - oscillator.connect(gainNode); - gainNode.connect(audioCtx.destination); - oscillator.type = 'sine'; - oscillator.frequency.setValueAtTime(880, audioCtx.currentTime); - gainNode.gain.setValueAtTime(0.1, audioCtx.currentTime); - gainNode.gain.exponentialRampToValueAtTime(0.00001, audioCtx.currentTime + 0.5); - oscillator.start(audioCtx.currentTime); - oscillator.stop(audioCtx.currentTime + 0.5); - } - - async function updateLeaderboard() { - try { - const response = await fetch('/api/scores/'); - const scores = await response.json(); - const leaderboardBody = document.getElementById('leaderboard-body'); - leaderboardBody.innerHTML = ''; - scores.forEach((score, index) => { - const row = ` - ${index + 1} - ${score.player_name} - ${score.score} - `; - leaderboardBody.innerHTML += row; - }); - } catch (error) { - console.error('Error updating leaderboard:', error); + if (count > 0) { + ctx.fillText(count, canvas.width / 2, canvas.height / 2); + count--; + } else { + clearInterval(countdown); + ctx.fillText('Go!', canvas.width / 2, canvas.height / 2); + setTimeout(startGame, 500); } - } + }, 1000); +} - function move(e) { - if (!gameStarted || gameOver) return; - if (e.key === 'ArrowRight' || e.key === 'd') { - player.dx = 1; - } else if (e.key === 'ArrowLeft' || e.key === 'a') { - player.dx = -1; - } - } +function startGame() { + gameStarted = true; + lastTime = performance.now(); + if (orangeInterval) clearInterval(orangeInterval); + orangeInterval = setInterval(createOrange, 1200); + requestAnimationFrame(update); +} - function stopMove(e) { - if (['ArrowRight', 'd', 'ArrowLeft', 'a'].includes(e.key)) { - player.dx = 0; - } - } +// Event Listeners +document.addEventListener('keydown', move); +document.addEventListener('keyup', stopMove); - function initGame() { - score = 0; - lives = 3; - oranges = []; - gameOver = false; - gameStarted = false; - player.x = canvas.width / 2 - player.width / 2; - drawScene(); - drawInitialMessage(); +canvas.addEventListener('click', () => { + if (gameOver) { + restartGame(); } +}); - function restartGame() { - score = 0; - lives = 3; - oranges = []; - gameOver = false; - player.x = canvas.width / 2 - player.width / 2; - startCountdown(); - } - - function startCountdown() { - let count = 3; - const countdown = setInterval(() => { - ctx.clearRect(0, 0, canvas.width, canvas.height); - drawScene(); - ctx.fillStyle = '#E6F1FF'; - ctx.font = '60px Poppins, sans-serif'; - ctx.textAlign = 'center'; - if (count > 0) { - ctx.fillText(count, canvas.width / 2, canvas.height / 2); - count--; - } else { - clearInterval(countdown); - ctx.fillText('Go!', canvas.width / 2, canvas.height / 2); - setTimeout(startGame, 500); - } - }, 1000); - } - - function startGame() { - gameStarted = true; - lastTime = performance.now(); - if (orangeInterval) clearInterval(orangeInterval); - orangeInterval = setInterval(createOrange, 1200); - requestAnimationFrame(update); - } - - // Event Listeners - document.addEventListener('keydown', move); - document.addEventListener('keyup', stopMove); - +document.addEventListener('DOMContentLoaded', function() { const playButton = document.querySelector('.btn-play'); const gameArea = document.getElementById('game-area'); if (playButton && gameArea) { - playButton.addEventListener('click', (e) => { + playButton.addEventListener('click', function(e) { e.preventDefault(); gameArea.scrollIntoView({ behavior: 'smooth' }); - if (!gameStarted && !gameOver) { - startCountdown(); - } + startCountdown(); }); + } else { + console.error('Play button or game area not found!'); } - - canvas.addEventListener('click', () => { - if (gameOver) { - restartGame(); - } - }); +}); - // Initial Setup - initGame(); - updateLeaderboard(); -}); \ No newline at end of file +// Initial Setup +initGame(); +updateLeaderboard(); diff --git a/staticfiles/js/game.js b/staticfiles/js/game.js index 9fd816e..4a650f5 100644 --- a/staticfiles/js/game.js +++ b/staticfiles/js/game.js @@ -1,279 +1,280 @@ -document.addEventListener('DOMContentLoaded', () => { - const canvas = document.getElementById('gameCanvas'); - if (!canvas) { - console.error('Canvas element not found!'); +const canvas = document.getElementById('gameCanvas'); +if (!canvas) { + console.error('Canvas element not found!'); +} +const ctx = canvas.getContext('2d'); + +// Set fixed canvas size +canvas.width = 800; +canvas.height = 600; + +const audioCtx = new (window.AudioContext || window.webkitAudioContext)(); +let score = 0; +let lives = 3; +let gameOver = false; +let gameStarted = false; +let orangeInterval; + +const player = { + width: 100, + height: 50, + x: canvas.width / 2 - 50, + y: canvas.height - 60, + speed: 500, + dx: 0, + draw() { + ctx.fillStyle = '#8B4513'; + ctx.beginPath(); + ctx.moveTo(this.x, this.y); + ctx.lineTo(this.x + this.width, this.y); + ctx.lineTo(this.x + this.width - 15, this.y + this.height); + ctx.lineTo(this.x + 15, this.y + this.height); + ctx.closePath(); + ctx.fill(); + ctx.strokeStyle = '#5C2F0E'; + ctx.lineWidth = 8; + ctx.beginPath(); + ctx.moveTo(this.x, this.y); + ctx.lineTo(this.x + this.width, this.y); + ctx.stroke(); + } +}; + +const orangeProps = { + size: 20, + speed: 150, +}; +let oranges = []; + +function createOrange() { + oranges.push({ + x: Math.random() * (canvas.width - orangeProps.size), + y: -orangeProps.size, + size: orangeProps.size, + speed: orangeProps.speed + Math.random() * 100, + draw() { + ctx.beginPath(); + ctx.arc(this.x + this.size / 2, this.y + this.size / 2, this.size, 0, Math.PI * 2); + ctx.fillStyle = '#FFA500'; + ctx.fill(); + ctx.beginPath(); + ctx.ellipse(this.x + this.size / 2 + 5, this.y, 8, 3, Math.PI / 4, 0, Math.PI * 2); + ctx.fillStyle = '#228B22'; + ctx.fill(); + } + }); +} + +let lastTime = 0; + +function update(timestamp) { + if (!gameStarted) { return; } - const ctx = canvas.getContext('2d'); - // Set fixed canvas size - canvas.width = 800; - canvas.height = 600; - - const audioCtx = new (window.AudioContext || window.webkitAudioContext)(); - let score = 0; - let lives = 3; - let gameOver = false; - let gameStarted = false; - let orangeInterval; - - const player = { - width: 100, - height: 50, - x: canvas.width / 2 - 50, - y: canvas.height - 60, - speed: 500, - dx: 0, - draw() { - ctx.fillStyle = '#8B4513'; - ctx.beginPath(); - ctx.moveTo(this.x, this.y); - ctx.lineTo(this.x + this.width, this.y); - ctx.lineTo(this.x + this.width - 15, this.y + this.height); - ctx.lineTo(this.x + 15, this.y + this.height); - ctx.closePath(); - ctx.fill(); - ctx.strokeStyle = '#5C2F0E'; - ctx.lineWidth = 8; - ctx.beginPath(); - ctx.moveTo(this.x, this.y); - ctx.lineTo(this.x + this.width, this.y); - ctx.stroke(); - } - }; - - const orangeProps = { - size: 20, - speed: 150, - }; - let oranges = []; - - function createOrange() { - oranges.push({ - x: Math.random() * (canvas.width - orangeProps.size), - y: -orangeProps.size, - size: orangeProps.size, - speed: orangeProps.speed + Math.random() * 100, - draw() { - ctx.beginPath(); - ctx.arc(this.x + this.size / 2, this.y + this.size / 2, this.size, 0, Math.PI * 2); - ctx.fillStyle = '#FFA500'; - ctx.fill(); - ctx.beginPath(); - ctx.ellipse(this.x + this.size / 2 + 5, this.y, 8, 3, Math.PI / 4, 0, Math.PI * 2); - ctx.fillStyle = '#228B22'; - ctx.fill(); - } - }); + if (gameOver) { + drawGameOver(); + return; } - let lastTime = 0; + const deltaTime = (timestamp - lastTime) / 1000; + lastTime = timestamp; - function update(timestamp) { - if (!gameStarted) return; + ctx.clearRect(0, 0, canvas.width, canvas.height); + drawScene(); + player.draw(); + player.x += player.dx * player.speed * deltaTime; - if (gameOver) { - drawGameOver(); - return; + if (player.x < 0) player.x = 0; + if (player.x + player.width > canvas.width) { + player.x = canvas.width - player.width; + } + + oranges.forEach((orange, index) => { + orange.y += orange.speed * deltaTime; + orange.draw(); + + if ( + orange.y + orange.size > player.y && + orange.x < player.x + player.width && + orange.x + orange.size > player.x + ) { + score++; + playCatchSound(); + oranges.splice(index, 1); } - const deltaTime = (timestamp - lastTime) / 1000; - lastTime = timestamp; + if (orange.y > canvas.height) { + lives--; + oranges.splice(index, 1); + if (lives <= 0) { + gameOver = true; + } + } + }); + drawUI(); + requestAnimationFrame(update); +} + +function drawScene() { + ctx.fillStyle = '#0A192F'; + ctx.fillRect(0, 0, canvas.width, canvas.height); + ctx.fillStyle = '#228B22'; + ctx.fillRect(0, canvas.height - 20, canvas.width, 20); +} + +function drawUI() { + ctx.fillStyle = '#E6F1FF'; + ctx.font = '24px Poppins, sans-serif'; + ctx.textAlign = 'left'; + ctx.fillText(`Score: ${score}`, 20, 40); + ctx.textAlign = 'right'; + ctx.fillText(`Lives: ${lives}`, canvas.width - 20, 40); + ctx.textAlign = 'center'; +} + +function drawGameOver() { + clearInterval(orangeInterval); + ctx.fillStyle = 'rgba(0, 0, 0, 0.7)'; + ctx.fillRect(0, 0, canvas.width, canvas.height); + ctx.fillStyle = '#E6F1FF'; + ctx.font = '50px Poppins, sans-serif'; + ctx.textAlign = 'center'; + ctx.fillText('GAME OVER', canvas.width / 2, canvas.height / 2 - 40); + ctx.font = '30px Poppins, sans-serif'; + ctx.fillText(`Final Score: ${score}`, canvas.width / 2, canvas.height / 2 + 20); + ctx.font = '20px Poppins, sans-serif'; + ctx.fillText('Click to Restart', canvas.width / 2, canvas.height / 2 + 70); +} + +function drawInitialMessage() { + ctx.fillStyle = '#E6F1FF'; + ctx.font = '30px Poppins, sans-serif'; + ctx.textAlign = 'center'; + ctx.fillText('Click "Play Now" to Start!', canvas.width / 2, canvas.height / 2); +} + +function playCatchSound() { + if (!audioCtx) return; + const oscillator = audioCtx.createOscillator(); + const gainNode = audioCtx.createGain(); + oscillator.connect(gainNode); + gainNode.connect(audioCtx.destination); + oscillator.type = 'sine'; + oscillator.frequency.setValueAtTime(880, audioCtx.currentTime); + gainNode.gain.setValueAtTime(0.1, audioCtx.currentTime); + gainNode.gain.exponentialRampToValueAtTime(0.00001, audioCtx.currentTime + 0.5); + oscillator.start(audioCtx.currentTime); + oscillator.stop(audioCtx.currentTime + 0.5); +} + +async function updateLeaderboard() { + try { + const response = await fetch('/api/scores/'); + const scores = await response.json(); + const leaderboardBody = document.getElementById('leaderboard-body'); + leaderboardBody.innerHTML = ''; + scores.forEach((score, index) => { + const row = ` + ${index + 1} + ${score.player_name} + ${score.score} + `; + leaderboardBody.innerHTML += row; + }); + } catch (error) { + console.error('Error updating leaderboard:', error); + } +} + +function move(e) { + if (!gameStarted || gameOver) return; + if (e.key === 'ArrowRight' || e.key === 'd') { + player.dx = 1; + } else if (e.key === 'ArrowLeft' || e.key === 'a') { + player.dx = -1; + } +} + +function stopMove(e) { + if (['ArrowRight', 'd', 'ArrowLeft', 'a'].includes(e.key)) { + player.dx = 0; + } +} + +function initGame() { + score = 0; + lives = 3; + oranges = []; + gameOver = false; + gameStarted = false; + player.x = canvas.width / 2 - player.width / 2; + drawScene(); + drawInitialMessage(); +} + +function restartGame() { + score = 0; + lives = 3; + oranges = []; + gameOver = false; + player.x = canvas.width / 2 - player.width / 2; + startCountdown(); +} + +function startCountdown() { + let count = 3; + const countdown = setInterval(() => { ctx.clearRect(0, 0, canvas.width, canvas.height); drawScene(); - player.draw(); - player.x += player.dx * player.speed * deltaTime; - - if (player.x < 0) player.x = 0; - if (player.x + player.width > canvas.width) { - player.x = canvas.width - player.width; - } - - oranges.forEach((orange, index) => { - orange.y += orange.speed * deltaTime; - orange.draw(); - - if ( - orange.y + orange.size > player.y && - orange.x < player.x + player.width && - orange.x + orange.size > player.x - ) { - score++; - playCatchSound(); - oranges.splice(index, 1); - } - - if (orange.y > canvas.height) { - lives--; - oranges.splice(index, 1); - if (lives <= 0) { - gameOver = true; - } - } - }); - - drawUI(); - requestAnimationFrame(update); - } - - function drawScene() { - ctx.fillStyle = '#0A192F'; - ctx.fillRect(0, 0, canvas.width, canvas.height); - ctx.fillStyle = '#228B22'; - ctx.fillRect(0, canvas.height - 20, canvas.width, 20); - } - - function drawUI() { ctx.fillStyle = '#E6F1FF'; - ctx.font = '24px Poppins, sans-serif'; - ctx.textAlign = 'left'; - ctx.fillText(`Score: ${score}`, 20, 40); - ctx.textAlign = 'right'; - ctx.fillText(`Lives: ${lives}`, canvas.width - 20, 40); + ctx.font = '60px Poppins, sans-serif'; ctx.textAlign = 'center'; - } - - function drawGameOver() { - clearInterval(orangeInterval); - ctx.fillStyle = 'rgba(0, 0, 0, 0.7)'; - ctx.fillRect(0, 0, canvas.width, canvas.height); - ctx.fillStyle = '#E6F1FF'; - ctx.font = '50px Poppins, sans-serif'; - ctx.textAlign = 'center'; - ctx.fillText('GAME OVER', canvas.width / 2, canvas.height / 2 - 40); - ctx.font = '30px Poppins, sans-serif'; - ctx.fillText(`Final Score: ${score}`, canvas.width / 2, canvas.height / 2 + 20); - ctx.font = '20px Poppins, sans-serif'; - ctx.fillText('Click to Restart', canvas.width / 2, canvas.height / 2 + 70); - } - - function drawInitialMessage() { - ctx.fillStyle = '#E6F1FF'; - ctx.font = '30px Poppins, sans-serif'; - ctx.textAlign = 'center'; - ctx.fillText('Click "Play Now" to Start!', canvas.width / 2, canvas.height / 2); - } - - function playCatchSound() { - if (!audioCtx) return; - const oscillator = audioCtx.createOscillator(); - const gainNode = audioCtx.createGain(); - oscillator.connect(gainNode); - gainNode.connect(audioCtx.destination); - oscillator.type = 'sine'; - oscillator.frequency.setValueAtTime(880, audioCtx.currentTime); - gainNode.gain.setValueAtTime(0.1, audioCtx.currentTime); - gainNode.gain.exponentialRampToValueAtTime(0.00001, audioCtx.currentTime + 0.5); - oscillator.start(audioCtx.currentTime); - oscillator.stop(audioCtx.currentTime + 0.5); - } - - async function updateLeaderboard() { - try { - const response = await fetch('/api/scores/'); - const scores = await response.json(); - const leaderboardBody = document.getElementById('leaderboard-body'); - leaderboardBody.innerHTML = ''; - scores.forEach((score, index) => { - const row = ` - ${index + 1} - ${score.player_name} - ${score.score} - `; - leaderboardBody.innerHTML += row; - }); - } catch (error) { - console.error('Error updating leaderboard:', error); + if (count > 0) { + ctx.fillText(count, canvas.width / 2, canvas.height / 2); + count--; + } else { + clearInterval(countdown); + ctx.fillText('Go!', canvas.width / 2, canvas.height / 2); + setTimeout(startGame, 500); } - } + }, 1000); +} - function move(e) { - if (!gameStarted || gameOver) return; - if (e.key === 'ArrowRight' || e.key === 'd') { - player.dx = 1; - } else if (e.key === 'ArrowLeft' || e.key === 'a') { - player.dx = -1; - } - } +function startGame() { + gameStarted = true; + lastTime = performance.now(); + if (orangeInterval) clearInterval(orangeInterval); + orangeInterval = setInterval(createOrange, 1200); + requestAnimationFrame(update); +} - function stopMove(e) { - if (['ArrowRight', 'd', 'ArrowLeft', 'a'].includes(e.key)) { - player.dx = 0; - } - } +// Event Listeners +document.addEventListener('keydown', move); +document.addEventListener('keyup', stopMove); - function initGame() { - score = 0; - lives = 3; - oranges = []; - gameOver = false; - gameStarted = false; - player.x = canvas.width / 2 - player.width / 2; - drawScene(); - drawInitialMessage(); +canvas.addEventListener('click', () => { + if (gameOver) { + restartGame(); } +}); - function restartGame() { - score = 0; - lives = 3; - oranges = []; - gameOver = false; - player.x = canvas.width / 2 - player.width / 2; - startCountdown(); - } - - function startCountdown() { - let count = 3; - const countdown = setInterval(() => { - ctx.clearRect(0, 0, canvas.width, canvas.height); - drawScene(); - ctx.fillStyle = '#E6F1FF'; - ctx.font = '60px Poppins, sans-serif'; - ctx.textAlign = 'center'; - if (count > 0) { - ctx.fillText(count, canvas.width / 2, canvas.height / 2); - count--; - } else { - clearInterval(countdown); - ctx.fillText('Go!', canvas.width / 2, canvas.height / 2); - setTimeout(startGame, 500); - } - }, 1000); - } - - function startGame() { - gameStarted = true; - lastTime = performance.now(); - if (orangeInterval) clearInterval(orangeInterval); - orangeInterval = setInterval(createOrange, 1200); - requestAnimationFrame(update); - } - - // Event Listeners - document.addEventListener('keydown', move); - document.addEventListener('keyup', stopMove); - +document.addEventListener('DOMContentLoaded', function() { const playButton = document.querySelector('.btn-play'); const gameArea = document.getElementById('game-area'); if (playButton && gameArea) { - playButton.addEventListener('click', (e) => { + playButton.addEventListener('click', function(e) { e.preventDefault(); gameArea.scrollIntoView({ behavior: 'smooth' }); - if (!gameStarted && !gameOver) { - startCountdown(); - } + startCountdown(); }); + } else { + console.error('Play button or game area not found!'); } - - canvas.addEventListener('click', () => { - if (gameOver) { - restartGame(); - } - }); +}); - // Initial Setup - initGame(); - updateLeaderboard(); -}); \ No newline at end of file +// Initial Setup +initGame(); +updateLeaderboard();