In this tutorial, we will learn how to develop an advanced JavaScript Breakout game.
We will develop this game with plain JavaScript, HTML, and CSS.
Breakout! Game
Game where you control a paddle with the arrow keys to bounce a ball up to break bricks. This app uses the HTML5 canvas element and API
Project Specifications
- Draw elements on canvas
- Use canvas paths to draw shapes
- Add animation with requestAnimationFrame(cb)
- Move paddle on arrow key press
- Add collision detection
- Keep score
- Add rules button with slider
JavaScript Breakout Game Development
Create a folder called JavaScript-Breakout as the project workspace and we will create all the project files inside this folder.
1. index.html
Let's create index.html and add the following code to it:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta http-equiv="X-UA-Compatible" content="ie=edge" /> <link rel="stylesheet" href="style.css" /> <title>Breakout!</title> </head> <body> <h1>Breakout!</h1> <button id="rules-btn" class="btn rules-btn">Show Rules</button> <div id="rules" class="rules"> <h2>How To Play:</h2> <p> Use your right and left keys to move the paddle to bounce the ball up and break the blocks. </p> <p>If you miss the ball, your score and the blocks will reset.</p> <button id="close-btn" class="btn">Close</button> </div> <canvas id="canvas" width="800" height="600"></canvas> <script src="script.js"></script> </body> </html>
2. script.js
Let's create a JavaScript file named script.js and add the following JavaScript code to it:
const rulesBtn = document.getElementById('rules-btn'); const closeBtn = document.getElementById('close-btn'); const rules = document.getElementById('rules'); const canvas = document.getElementById('canvas'); const ctx = canvas.getContext('2d'); let score = 0; const brickRowCount = 9; const brickColumnCount = 5; const delay = 500; //delay to reset the game // Create ball props const ball = { x: canvas.width / 2, y: canvas.height / 2, size: 10, speed: 4, dx: 4, dy: -4, visible: true }; // Create paddle props const paddle = { x: canvas.width / 2 - 40, y: canvas.height - 20, w: 80, h: 10, speed: 8, dx: 0, visible: true }; // Create brick props const brickInfo = { w: 70, h: 20, padding: 10, offsetX: 45, offsetY: 60, visible: true }; // Create bricks const bricks = []; for (let i = 0; i < brickRowCount; i++) { bricks[i] = []; for (let j = 0; j < brickColumnCount; j++) { const x = i * (brickInfo.w + brickInfo.padding) + brickInfo.offsetX; const y = j * (brickInfo.h + brickInfo.padding) + brickInfo.offsetY; bricks[i][j] = { x, y, ...brickInfo }; } } // Draw ball on canvas function drawBall() { ctx.beginPath(); ctx.arc(ball.x, ball.y, ball.size, 0, Math.PI * 2); ctx.fillStyle = ball.visible ? '#0095dd' : 'transparent'; ctx.fill(); ctx.closePath(); } // Draw paddle on canvas function drawPaddle() { ctx.beginPath(); ctx.rect(paddle.x, paddle.y, paddle.w, paddle.h); ctx.fillStyle = paddle.visible ? '#0095dd' : 'transparent'; ctx.fill(); ctx.closePath(); } // Draw score on canvas function drawScore() { ctx.font = '20px Arial'; ctx.fillText(`Score: ${score}`, canvas.width - 100, 30); } // Draw bricks on canvas function drawBricks() { bricks.forEach(column => { column.forEach(brick => { ctx.beginPath(); ctx.rect(brick.x, brick.y, brick.w, brick.h); ctx.fillStyle = brick.visible ? '#0095dd' : 'transparent'; ctx.fill(); ctx.closePath(); }); }); } // Move paddle on canvas function movePaddle() { paddle.x += paddle.dx; // Wall detection if (paddle.x + paddle.w > canvas.width) { paddle.x = canvas.width - paddle.w; } if (paddle.x < 0) { paddle.x = 0; } } // Move ball on canvas function moveBall() { ball.x += ball.dx; ball.y += ball.dy; // Wall collision (right/left) if (ball.x + ball.size > canvas.width || ball.x - ball.size < 0) { ball.dx *= -1; // ball.dx = ball.dx * -1 } // Wall collision (top/bottom) if (ball.y + ball.size > canvas.height || ball.y - ball.size < 0) { ball.dy *= -1; } // console.log(ball.x, ball.y); // Paddle collision if ( ball.x - ball.size > paddle.x && ball.x + ball.size < paddle.x + paddle.w && ball.y + ball.size > paddle.y ) { ball.dy = -ball.speed; } // Brick collision bricks.forEach(column => { column.forEach(brick => { if (brick.visible) { if ( ball.x - ball.size > brick.x && // left brick side check ball.x + ball.size < brick.x + brick.w && // right brick side check ball.y + ball.size > brick.y && // top brick side check ball.y - ball.size < brick.y + brick.h // bottom brick side check ) { ball.dy *= -1; brick.visible = false; increaseScore(); } } }); }); // Hit bottom wall - Lose if (ball.y + ball.size > canvas.height) { showAllBricks(); score = 0; } } // Increase score function increaseScore() { score++; if (score % (brickRowCount * brickColumnCount) === 0) { ball.visible = false; paddle.visible = false; //After 0.5 sec restart the game setTimeout(function () { showAllBricks(); score = 0; paddle.x = canvas.width / 2 - 40; paddle.y = canvas.height - 20; ball.x = canvas.width / 2; ball.y = canvas.height / 2; ball.visible = true; paddle.visible = true; },delay) } } // Make all bricks appear function showAllBricks() { bricks.forEach(column => { column.forEach(brick => (brick.visible = true)); }); } // Draw everything function draw() { // clear canvas ctx.clearRect(0, 0, canvas.width, canvas.height); drawBall(); drawPaddle(); drawScore(); drawBricks(); } // Update canvas drawing and animation function update() { movePaddle(); moveBall(); // Draw everything draw(); requestAnimationFrame(update); } update(); // Keydown event function keyDown(e) { if (e.key === 'Right' || e.key === 'ArrowRight') { paddle.dx = paddle.speed; } else if (e.key === 'Left' || e.key === 'ArrowLeft') { paddle.dx = -paddle.speed; } } // Keyup event function keyUp(e) { if ( e.key === 'Right' || e.key === 'ArrowRight' || e.key === 'Left' || e.key === 'ArrowLeft' ) { paddle.dx = 0; } } // Keyboard event handlers document.addEventListener('keydown', keyDown); document.addEventListener('keyup', keyUp); // Rules and close event handlers rulesBtn.addEventListener('click', () => rules.classList.add('show')); closeBtn.addEventListener('click', () => rules.classList.remove('show'));
3. style.css
Let's create a CSS file named style.css and add the following CSS code to it:
* { box-sizing: border-box; } body { background-color: #0095dd; display: flex; flex-direction: column; align-items: center; justify-content: center; font-family: Arial, Helvetica, sans-serif; min-height: 100vh; margin: 0; } h1 { font-size: 45px; color: #fff; } canvas { background: #f0f0f0; display: block; border-radius: 5px; } .btn { cursor: pointer; border: 0; padding: 10px 20px; background: #000; color: #fff; border-radius: 5px; } .btn:focus { outline: 0; } .btn:hover { background: #222; } .btn:active { transform: scale(0.98); } .rules-btn { position: absolute; top: 30px; left: 30px; } .rules { position: absolute; top: 0; left: 0; background: #333; color: #fff; min-height: 100vh; width: 400px; padding: 20px; line-height: 1.5; transform: translateX(-400px); transition: transform 1s ease-in-out; } .rules.show { transform: translateX(0); }
Open index.html in Browser
Let's open the index.html file in the browser and you will be able to see the following screen:
More Free JavaScript Projects with Source Code
- JavaScript Tic Tac Toe Game
- JavaScript Project - Modal Box
- JavaScript Project - Modal Box
- JavaScript Project - Password Generator
- JavaScript Project - Weather App
- JavaScript Project - Todo App
- JavaScript Project - Notes App
- JavaScript Project - Movie App
- JavaScript Project - Drawing App
- JavaScript Project - Countdown Timer
- Breakout Game with JavaScript, HTML, and CSS
- Exchange Rate Project with JavaScript, HTML, and CSS
- Expense Tracker Project with JavaScript, HTML, and CSS
- Form Validator with JavaScript, HTML, and CSS
- LyricsSearch App with JavaScript, HTML and CSS
- Movie Seat Booking Project with JavaScript, HTML, and CSS
Comments
Post a Comment