Pengantar Game Breakout dan JavaScript
Game Breakout adalah game klasik di mana pemain mengendalikan paddle untuk memantulkan bola dan menghancurkan balok-balok di atas layar. Dalam tutorial ini, Anda akan belajar membuat game Breakout menggunakan JavaScript dan elemen
canvas
HTML5.
JavaScript sangat cocok untuk membuat game sederhana berbasis web karena kemampuannya mengontrol grafis dan interaksi pengguna secara real-time.
Persiapan Lingkungan dan Tools
Anda hanya memerlukan browser modern dan editor teks untuk mulai membuat game ini. Berikut beberapa rekomendasi:
-
Browser seperti Google Chrome, Firefox, atau Edge
-
Editor teks seperti VS Code, Sublime Text, atau Atom
-
Pengetahuan dasar HTML, CSS, dan JavaScript
Anda juga bisa menggunakan layanan online seperti
CodePen
atau
JSFiddle
untuk langsung mencoba kode.
Membuat Struktur HTML dan Canvas
Langkah pertama adalah membuat file HTML dengan elemen
canvas
yang akan menjadi area permainan.
<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Game Breakout</title>
<style>
canvas {
background: #222;
display: block;
margin: 0 auto;
border: 2px solid #555;
}
</style>
</head>
<body>
<canvas id="gameCanvas" width="480" height="320"></canvas>
<script src="breakout.js"></script>
</body>
</html>
File ini membuat canvas 480x320 piksel dengan latar gelap dan border. File JavaScript eksternal
breakout.js
akan berisi logika game.
Membuat Paddle (Batang Pemukul)
Paddle adalah batang yang dikendalikan pemain untuk memantulkan bola. Kita akan menggambar paddle di canvas dan mengatur posisinya.
// breakout.js
const canvas = document.getElementById("gameCanvas");
const ctx = canvas.getContext("2d");
const paddleHeight = 10;
const paddleWidth = 75;
let paddleX = (canvas.width - paddleWidth) / 2;
function drawPaddle() {
ctx.beginPath();
ctx.rect(paddleX, canvas.height - paddleHeight - 10, paddleWidth, paddleHeight);
ctx.fillStyle = "#0095DD";
ctx.fill();
ctx.closePath();
}
function draw() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
drawPaddle();
}
draw();
Fungsi
drawPaddle()
menggambar paddle berwarna biru di bagian bawah canvas. Fungsi
draw()
membersihkan canvas dan menggambar paddle.
Membuat Bola dan Gerakannya
Selanjutnya kita buat bola yang akan bergerak dan memantul di dalam canvas.
// breakout.js (lanjutan)
const ballRadius = 10;
let x = canvas.width / 2;
let y = canvas.height - 30;
let dx = 2;
let dy = -2;
function drawBall() {
ctx.beginPath();
ctx.arc(x, y, ballRadius, 0, Math.PI * 2);
ctx.fillStyle = "#FF4500";
ctx.fill();
ctx.closePath();
}
function draw() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
drawBall();
drawPaddle();
x += dx;
y += dy;
// Pantulan bola di sisi kiri dan kanan
if (x + dx > canvas.width - ballRadius || x + dx < ballRadius) {
dx = -dx;
}
// Pantulan bola di sisi atas
if (y + dy < ballRadius) {
dy = -dy;
}
// Pantulan bola di paddle
else if (
y + dy > canvas.height - paddleHeight - 10 - ballRadius &&
x > paddleX &&
x < paddleX + paddleWidth
) {
dy = -dy;
}
// Bola jatuh ke bawah (game over)
else if (y + dy > canvas.height - ballRadius) {
alert("Game Over!");
document.location.reload();
}
}
setInterval(draw, 10);
Bola berwarna oranye akan bergerak dan memantul di sisi canvas dan paddle. Jika bola melewati paddle ke bawah, game akan berakhir dan halaman reload.
Membuat Bricks (Balok) dan Deteksi Tabrakan
Sekarang kita buat balok-balok yang akan dihancurkan bola. Kita juga akan menambahkan deteksi tabrakan bola dengan balok.
// breakout.js (lanjutan)
const brickRowCount = 5;
const brickColumnCount = 7;
const brickWidth = 55;
const brickHeight = 20;
const brickPadding = 10;
const brickOffsetTop = 30;
const brickOffsetLeft = 30;
let bricks = [];
for (let c = 0; c < brickColumnCount; c++) {
bricks[c] = [];
for (let r = 0; r < brickRowCount; r++) {
bricks[c][r] = { x: 0, y: 0, status: 1 };
}
}
function drawBricks() {
for (let c = 0; c < brickColumnCount; c++) {
for (let r = 0; r < brickRowCount; r++) {
if (bricks[c][r].status === 1) {
let brickX = c * (brickWidth + brickPadding) + brickOffsetLeft;
let brickY = r * (brickHeight + brickPadding) + brickOffsetTop;
bricks[c][r].x = brickX;
bricks[c][r].y = brickY;
ctx.beginPath();
ctx.rect(brickX, brickY, brickWidth, brickHeight);
ctx.fillStyle = "#32CD32";
ctx.fill();
ctx.closePath();
}
}
}
}
function collisionDetection() {
for (let c = 0; c < brickColumnCount; c++) {
for (let r = 0; r < brickRowCount; r++) {
let b = bricks[c][r];
if (b.status === 1) {
if (
x > b.x &&
x < b.x + brickWidth &&
y > b.y &&
y < b.y + brickHeight
) {
dy = -dy;
b.status = 0;
score++;
if (score === brickRowCount * brickColumnCount) {
alert("Selamat! Anda Menang!");
document.location.reload();
}
}
}
}
}
}
let score = 0;
function draw() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
drawBricks();
drawBall();
drawPaddle();
collisionDetection();
x += dx;
y += dy;
if (x + dx > canvas.width - ballRadius || x + dx < ballRadius) {
dx = -dx;
}
if (y + dy < ballRadius) {
dy = -dy;
} else if (
y + dy > canvas.height - paddleHeight - 10 - ballRadius &&
x > paddleX &&
x < paddleX + paddleWidth
) {
dy = -dy;
} else if (y + dy > canvas.height - ballRadius) {
alert("Game Over!");
document.location.reload();
}
drawScore();
}
function drawScore() {
ctx.font = "16px Arial";
ctx.fillStyle = "#fff";
ctx.fillText("Skor: " + score, 8, 20);
}
setInterval(draw, 10);
Balok berwarna hijau akan digambar di atas. Bola akan memantul dan menghilangkan balok saat terkena. Skor akan bertambah dan game selesai saat semua balok hancur.
Menambahkan Skor dan Level
Kita sudah menambahkan skor dasar. Sekarang kita akan menambahkan level yang meningkat saat semua balok hancur.
// breakout.js (lanjutan)
let level = 1;
function resetBricks() {
for (let c = 0; c < brickColumnCount; c++) {
for (let r = 0; r < brickRowCount; r++) {
bricks[c][r].status = 1;
}
}
}
function draw() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
drawBricks();
drawBall();
drawPaddle();
collisionDetection();
x += dx;
y += dy;
if (x + dx > canvas.width - ballRadius || x + dx < ballRadius) {
dx = -dx;
}
if (y + dy < ballRadius) {
dy = -dy;
} else if (
y + dy > canvas.height - paddleHeight - 10 - ballRadius &&
x > paddleX &&
x < paddleX + paddleWidth
) {
dy = -dy;
} else if (y + dy > canvas.height - ballRadius) {
alert("Game Over!");
document.location.reload();
}
drawScore();
drawLevel();
}
function drawScore() {
ctx.font = "16px Arial";
ctx.fillStyle = "#fff";
ctx.fillText("Skor: " + score, 8, 20);
}
function drawLevel() {
ctx.font = "16px Arial";
ctx.fillStyle = "#fff";
ctx.fillText("Level: " + level, canvas.width - 80, 20);
}
function collisionDetection() {
for (let c = 0; c < brickColumnCount; c++) {
for (let r = 0; r < brickRowCount; r++) {
let b = bricks[c][r];
if (b.status === 1) {
if (
x > b.x &&
x < b.x + brickWidth &&
y > b.y &&
y < b.y + brickHeight
) {
dy = -dy;
b.status = 0;
score++;
if (score === brickRowCount * brickColumnCount * level) {
level++;
resetBricks();
score = 0;
dx += 0.5;
dy = -dy - 0.5;
}
}
}
}
}
}
setInterval(draw, 10);
Level akan bertambah dan kecepatan bola meningkat setiap kali semua balok hancur. Skor dan level ditampilkan di canvas.
Menambahkan Kontrol Keyboard dan Mouse
Agar paddle bisa dikendalikan, kita tambahkan event listener untuk keyboard dan mouse.
// breakout.js (lanjutan)
let rightPressed = false;
let leftPressed = false;
document.addEventListener("keydown", keyDownHandler, false);
document.addEventListener("keyup", keyUpHandler, false);
document.addEventListener("mousemove", mouseMoveHandler, false);
function keyDownHandler(e) {
if (e.key === "Right" || e.key === "ArrowRight") {
rightPressed = true;
} else if (e.key === "Left" || e.key === "ArrowLeft") {
leftPressed = true;
}
}
function keyUpHandler(e) {
if (e.key === "Right" || e.key === "ArrowRight") {
rightPressed = false;
} else if (e.key === "Left" || e.key === "ArrowLeft") {
leftPressed = false;
}
}
function mouseMoveHandler(e) {
const relativeX = e.clientX - canvas.offsetLeft;
if (relativeX > 0 && relativeX < canvas.width) {
paddleX = relativeX - paddleWidth / 2;
}
}
function draw() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
drawBricks();
drawBall();
drawPaddle();
collisionDetection();
if (rightPressed && paddleX < canvas.width - paddleWidth) {
paddleX += 7;
} else if (leftPressed && paddleX > 0) {
paddleX -= 7;
}
x += dx;
y += dy;
if (x + dx > canvas.width - ballRadius || x + dx < ballRadius) {
dx = -dx;
}
if (y + dy < ballRadius) {
dy = -dy;
} else if (
y + dy > canvas.height - paddleHeight - 10 - ballRadius &&
x > paddleX &&
x < paddleX + paddleWidth
) {
dy = -dy;
} else if (y + dy > canvas.height - ballRadius) {
alert("Game Over!");
document.location.reload();
}
drawScore();
drawLevel();
}
setInterval(draw, 10);
Paddle dapat digerakkan dengan tombol panah kiri/kanan dan juga dengan mouse. Ini membuat permainan lebih interaktif dan mudah dikendalikan.
Menyelesaikan Game dan Menambahkan Fitur Tambahan
Anda bisa menambahkan fitur tambahan seperti nyawa (lives), suara, animasi, dan tampilan UI yang lebih menarik. Berikut contoh menambahkan nyawa:
// breakout.js (lanjutan)
let lives = 3;
function drawLives() {
ctx.font = "16px Arial";
ctx.fillStyle = "#fff";
ctx.fillText("Nyawa: " + lives, canvas.width - 80, 40);
}
function draw() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
drawBricks();
drawBall();
drawPaddle();
collisionDetection();
if (rightPressed && paddleX < canvas.width - paddleWidth) {
paddleX += 7;
} else if (leftPressed && paddleX > 0) {
paddleX -= 7;
}
x += dx;
y += dy;
if (x + dx > canvas.width - ballRadius || x + dx < ballRadius) {
dx = -dx;
}
if (y + dy < ballRadius) {
dy = -dy;
} else if (
y + dy > canvas.height - paddleHeight - 10 - ballRadius &&
x > paddleX &&
x < paddleX + paddleWidth
) {
dy = -dy;
} else if (y + dy > canvas.height - ballRadius) {
lives--;
if (!lives) {
alert("Game Over!");
document.location.reload();
} else {
x = canvas.width / 2;
y = canvas.height - 30;
dx = 2;
dy = -2;
paddleX = (canvas.width - paddleWidth) / 2;
}
}
drawScore();
drawLevel();
drawLives();
}
setInterval(draw, 10);
Dengan menambahkan nyawa, pemain mendapat kesempatan lebih dari satu kali gagal sebelum game berakhir.
Sumber Belajar dan Source Code Lengkap
Berikut beberapa sumber belajar dan repository yang bisa Anda gunakan untuk memperdalam dan mendapatkan source code lengkap game Breakout ini:
Anda dapat mengunduh source code lengkap game Breakout ini dari repository berikut:
Download Source Code di GitHub