// Game state variables let canvas = document.getElementById('game'); let ctx = canvas.getContext('2d'); let paddleWidth = 60; let paddleHeight = 10; let ballSpeed = 3; let ballDirectionX = -ballSpeed; let ballDirectionY = (Math.random() > 0.5 ? 2 : -2); let lives = 3; // Bricks' array of objects let bricks = [ {x: 0, y: 0}, {x: 80, y: 0}, {x: 160, y: 0}, {x: 240, y: 0}, {x: 320, y: 0}, {x: 0, y: 40} ]; // Ball object properties let ballX = canvas.width / 2; let ballY = canvas.height - 10 - ballDirectionY; let ballRadius = 3; // Paddle object properties let paddleX = canvas.width / 2 - paddleWidth / 2; // Game functions function gameLoop() { update(); render(); checkCollisions(); movePaddle(); if (lives < 0) { gameOver(); } } function restart() { location.reload(); } function update() { ctx.clearRect(0, 0, canvas.width, canvas.height); ballX += ballDirectionX; ballY += ballDirectionY; // Ball bounces off walls if (ballX < 0 || ballX > canvas.width - ballRadius) { ballDirectionX = -ballDirectionX; } // Ball bounces off paddle if (ballY < 0) { if (ballX >= paddleX && ballX <= paddleX + paddleWidth) { let diffY = ballY - (canvas.height - ballRadius); if (diffY > 0) { ballDirectionY = -ballDirectionY; } else { gameOver(); } } } // Ball bounces off bricks for (let i = bricks.length - 1; i >= 0; i--) { let brick = bricks[i]; if (brick.x + brick.width < 0 || brick.y > canvas.height - ballRadius * 2) { bricks.splice(i, 1); score += 10; } else if (Math.abs(ballX - (brick.x + brick.width / 2)) < ballRadius && Math.abs(ballY - (canvas.height - ballRadius * 2) - brick.y) < ballRadius) { bricks[i].destroyed = true; score += 10; } } // Move paddle paddleX += 5; } function render() { ctx.save(); ctx.fillStyle = 'white'; ctx.fillRect(0, 0, canvas.width, canvas.height); let brickWidth = 80; let brickHeight = 20; let brickPadding = 5; let brickMargin = 10; let brickOffsetX = (canvas.width - (brickWidth * 8)) / 2; let brickOffsetY = (canvas.height - (brickHeight * 4)) / 2 + brickMargin; // Draw bricks for (let i = bricks.length - 1; i >= 0; i--) { let brick = bricks[i]; if (!brick.destroyed) { ctx.fillStyle = 'cyan'; ctx.fillRect(brickOffsetX + brickWidth * brick.x, brickOffsetY + brickHeight * brick.y, brickWidth, brickHeight); ctx.strokeRect(brickOffsetX + brickWidth * brick.x, brickOffsetY + brickHeight * brick.y, brickWidth, brickHeight); } } // Draw paddle ctx.fillStyle = 'cyan'; ctx.fillRect(paddleX, canvas.height - 10 - paddleHeight, paddleWidth, paddleHeight); ctx.strokeRect(paddleX, canvas.height - 10 - paddleHeight, paddleWidth, paddleHeight); // Draw score ctx.fillStyle = 'white'; ctx.textBaseline = 'top'; ctx.font = '24px Arial'; ctx.fillText('Score: ' + score, 5, 5); ctx.restore(); } function checkCollisions() { for (let i = bricks.length - 1; i >= 0; i--) { let brick = bricks[i]; if (!brick.destroyed) { let diffX = ballX - (brick.x + brickWidth / 2); let diffY = ballY - (canvas.height - ballRadius * 2 - brick.y); // Check collision with walls if (diffX < 0 && diffX > -ballRadius) { ballDirectionX = -ballDirectionX; } else if (diffX > 0 && diffX < canvas.width - ballRadius) { ballDirectionX = -ballDirectionX; } // Check collision with paddle if ((diffY <= ballRadius * 2 + paddleHeight / 2 && diffX >= paddleWidth / 2 - ballRadius && diffX <= paddleWidth / 2 + ballRadius) || (diffY <= ballRadius)) { let diffDirectionX = Math.sign(ballDirectionX); let diffDirectionY = Math.sign(ballDirectionY); // Reflect ball upward and flip dy if hit top/bottom paddle edge if ((brick.x + brickWidth / 2 < paddleX && diffY <= -paddleHeight / 2) || (brick.x + brickWidth / 2 > canvas.width - paddleWidth + paddleX && diffY >= paddleHeight / 2)) { ballDirectionY = -ballDirectionY; if (diffY < -paddleHeight / 2) { ballDirectionY *= -1; } else if (diffY > paddleHeight / 2) { ballDirectionY *= -1; } } // Reflect ball left/right if hit side edge of brick let dx = diffX * diffDirectionX; let dy = diffY * diffDirectionY + ballRadius; ballDirectionX = dx; ballDirectionY = dy; } else { bricks[i].destroyed = true; } } } } function movePaddle() { if (event.type == 'touchmove') { let touchX = event.touches[0].clientX - paddleWidth / 2; if (touchX >= 0 && touchX <= canvas.width) { paddleX = touchX; } } else if (event.type == 'mousemove') { let mouseX = event.clientX - paddleWidth / 2; if (mouseX >= 0 && mouseX <= canvas.width) { paddleX = mouseX; } } } function gameOver() { ctx.save(); ctx.fillStyle = 'black'; ctx.textAlign = 'center'; ctx.font = '32px Arial'; ctx.fillText('Game Over!', canvas.width / 2, canvas.height / 2); ctx.restore(); }