let canvas = document.getElementById("game"); let ctx = canvas.getContext("2d"); let score = 0; let running = false; let ball, paddle, bricks, rows, cols, speed; let currentDiff = "easy"; const brickColors = ["#FF5733", "#33FF57", "#3357FF", "#FF33F5", "#33FFF5", "#F5FF33"]; let hitSound = new Audio("hit.wav"); let loseSound = new Audio("lose.wav"); let wallSound = new Audio("wall.wav"); let winSound = new Audio("win.wav"); const gameModal = document.getElementById("gameModal"); const modalTitle = document.getElementById("modalTitle"); const modalScore = document.getElementById("modalScore"); const saveScoreBtn = document.getElementById("saveScoreBtn"); const playAgainBtn = document.getElementById("playAgainBtn"); if (playAgainBtn) { playAgainBtn.addEventListener('click', () => { gameModal.style.display = 'none'; startGame(); }); } if (saveScoreBtn) { saveScoreBtn.addEventListener('click', () => { saveScore(true); }); } function lockSpeed() { let currentSpeedSq = ball.dx * ball.dx + ball.dy * ball.dy; if (currentSpeedSq > 0.0001) { let currentSpeed = Math.sqrt(currentSpeedSq); let ratio = speed / currentSpeed; ball.dx *= ratio; ball.dy *= ratio; } } function startGame(){ score = 0; document.getElementById("score").textContent = score; running = true; // Simpan kesulitan yang dipilih ke variabel global currentDiff let diffInput = document.getElementById("diff").value; currentDiff = diffInput; let initialHealth = 1; if(currentDiff === "easy"){ rows = 3; cols = 5; speed = 2; initialHealth = 1; } if(currentDiff === "medium"){ rows = 4; cols = 7; speed = 4; initialHealth = 3; } if(currentDiff === "hard"){ rows = 6; cols = 9; speed = 5; initialHealth = 5; } paddle = { x:200, w:80, h:10 }; ball = { x:240, y:200, dx:speed, dy:-speed, r:6 }; bricks = []; let brickW = (canvas.width - cols * 5) / cols; let brickH = 15; for(let r=0;r canvas.width || ball.x - ball.r < 0){ ball.dx *= -1; lockSpeed(); wallSound.currentTime = 0; wallSound.play(); } if(ball.y - ball.r < 0){ ball.dy *= -1; lockSpeed(); wallSound.currentTime = 0; wallSound.play(); } if(ball.y + ball.r > canvas.height - paddle.h && ball.x > paddle.x && ball.x < paddle.x + paddle.w){ let deltaX = ball.x - (paddle.x + paddle.w/2); let dy_abs = Math.abs(speed) * -1; ball.dx = deltaX * 0.15; ball.dy = dy_abs; lockSpeed(); wallSound.currentTime = 0; wallSound.play(); } bricks.forEach(b =>{ if(!b.hit && ball.x > b.x && ball.x < b.x+b.w && ball.y > b.y && ball.y < b.y+b.h){ b.health--; ball.dy *= -1; lockSpeed(); if (b.health <= 0) { b.hit = true; score += 10; winSound.currentTime = 0; winSound.play(); } else { hitSound.currentTime = 0; hitSound.play(); if (b.health === 4) b.color = '#B22222'; if (b.health === 3) b.color = '#CD853F'; if (b.health === 2) b.color = '#FFA07A'; if (b.health === 1) b.color = '#F08080'; } document.getElementById("score").textContent = score; } }); bricks.forEach(b =>{ if(!b.hit){ ctx.fillStyle = b.color; ctx.fillRect(b.x,b.y,b.w,b.h); ctx.strokeStyle = "#000000"; ctx.strokeRect(b.x,b.y,b.w,b.h); } }); if(bricks.every(b => b.hit)){ winSound.currentTime = 0; winSound.play(); running = false; showModal("YOU WIN!", score); } if(ball.y > canvas.height){ loseSound.currentTime = 0; loseSound.play(); running = false; showModal("GAME OVER!", score); } } canvas.addEventListener("mousemove", e =>{ if (!paddle || !canvas) return; const canvasRect = canvas.getBoundingClientRect(); let newX = e.clientX - canvasRect.left - paddle.w/2; if(newX < 0) newX = 0; if(newX > canvas.width - paddle.w) newX = canvas.width - paddle.w; paddle.x = newX; }); function showModal(title, finalScore) { modalTitle.textContent = title; modalScore.innerHTML = `Final Score: ${finalScore}
(${currentDiff.toUpperCase()})`; gameModal.style.display = 'flex'; if (saveScoreBtn) { saveScoreBtn.disabled = false; saveScoreBtn.textContent = 'Save Score'; saveScoreBtn.style.background = 'linear-gradient(45deg, #28a745, #21c064)'; saveScoreBtn.style.opacity = '1'; } } function saveScore(fromModal = false){ let isUserLoggedIn = document.querySelector('.user-info'); if (isUserLoggedIn) { if (fromModal) { if (saveScoreBtn) { saveScoreBtn.disabled = true; saveScoreBtn.textContent = 'Saving...'; saveScoreBtn.style.opacity = '0.7'; } // Perubahan: Menambahkan &diff=... ke URL fetch(`save.php?score=${score}&diff=${currentDiff}`) .then(response => { if (response.ok) { if (saveScoreBtn) { saveScoreBtn.textContent = 'Saved! ✅'; saveScoreBtn.style.background = 'gray'; saveScoreBtn.style.opacity = '1'; } } else { if (saveScoreBtn) { saveScoreBtn.textContent = 'Failed ❌'; saveScoreBtn.disabled = false; saveScoreBtn.style.opacity = '1'; } } }) .catch(error => { console.error("Error saving score:", error); if (saveScoreBtn) { saveScoreBtn.textContent = 'Error ❌'; saveScoreBtn.disabled = false; saveScoreBtn.style.opacity = '1'; } }); } } }