Blok Blaze - Buatan Sendiri
by PixelHero77235 lines8.4 KB
<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Blok Blaze - Buatan Sendiri</title>
<script src="https://cdn.tailwindcss.com"></script>
<style type="text/tailwindcss">
@layer utilities {
.grid-cell {
@apply border border-gray-700/40;
}
.block-color {
@apply rounded-sm shadow-md;
}
}
</style>
</head>
<body class="bg-slate-900 text-white min-h-screen flex flex-col items-center py-6 px-4">
<h1 class="text-[clamp(2rem,4vw,3rem)] font-bold text-orange-400 mb-2">🔥 Blok Blaze</h1>
<p class="text-gray-300 mb-6">Susun & hancurkan garis penuh | ⬅️➡️ ⬇️ putar ⬆️</p>
<div class="flex gap-6 flex-wrap justify-center">
<!-- Papan Main -->
<canvas id="papan" width="300" height="600" class="border-4 border-orange-500/60 rounded-lg bg-slate-800"></canvas>
<!-- Panel Samping -->
<div class="flex flex-col gap-5">
<div class="bg-slate-800 p-4 rounded-lg border border-orange-400/40">
<p class="text-lg">Skor: <span id="skor" class="font-bold text-orange-300 text-xl">0</span></p>
</div>
<div class="bg-slate-800 p-4 rounded-lg border border-orange-400/40">
<p class="text-sm mb-2 text-gray-300">Berikutnya:</p>
<canvas id="berikutnya" width="80" height="80"></canvas>
</div>
<button id="tombolMulai" class="bg-orange-500 hover:bg-orange-600 transition-all font-bold py-3 px-6 rounded-lg text-lg">
MULAI / ULANG
</button>
<div class="text-sm text-gray-400 mt-2">
← → : Geser<br>
↑ : Putar<br>
↓ : Turun cepat
</div>
</div>
</div>
<script>
// === PENGATURAN UKURAN ===
const BARIS = 20;
const KOLOM = 10;
const UKURAN_KOTAK = 30;
// Warna balok sama seperti gaya Blok Blaze
const WARNA = [
null,
'#FF5722', '#2196F3', '#4CAF50', '#FFC107',
'#9C27B0', '#00BCD4', '#F44336'
];
// Bentuk balok standar
const BENTUK = [
[[1,1,1,1]], // I
[[2,2],[2,2]], // O
[[0,3,0],[3,3,3]], // T
[[0,4,4],[4,4,0]], // S
[[5,5,0],[0,5,5]], // Z
[[6,0,0],[6,6,6]], // J
[[0,0,7],[7,7,7]] // L
];
// Ambil elemen kanvas
const kanvas = document.getElementById('papan');
const konteks = kanvas.getContext('2d');
const kanvasBerikutnya = document.getElementById('berikutnya');
const konteksBerikutnya = kanvasBerikutnya.getContext('2d');
const teksSkor = document.getElementById('skor');
const tombolMulai = document.getElementById('tombolMulai');
let papan = [];
let skor = 0;
let selesai = false;
let balokSekarang, balokNanti;
let jeda;
// === Siapkan papan kosong ===
function kosongkanPapan() {
papan = Array(BARIS).fill().map(() => Array(KOLOM).fill(0));
}
// === Gambar kotak satu per satu ===
function gambarKotak(x, y, warna, konteksGambar = konteks, ukuran = UKURAN_KOTAK) {
konteksGambar.fillStyle = WARNA[warna];
konteksGambar.fillRect(x * ukuran, y * ukuran, ukuran - 1, ukuran - 1);
}
// === Gambar seluruh papan ===
function gambarPapan() {
konteks.clearRect(0, 0, kanvas.width, kanvas.height);
for (let b = 0; b < BARIS; b++) {
for (let k = 0; k < KOLOM; k++) {
if (papan[b][k]) gambarKotak(k, b, papan[b][k]);
}
}
// Gambar balok yang sedang jatuh
balokSekarang.bentuk.forEach((baris, bi) => {
baris.forEach((nilai, ki) => {
if (nilai) gambarKotak(balokSekarang.x + ki, balokSekarang.y + bi, nilai);
});
});
}
// === Buat balok baru ===
function buatBalok() {
balokSekarang = balokNanti || ambilAcak();
balokNanti = ambilAcak();
balokSekarang.x = Math.floor(KOLOM / 2) - Math.floor(balokSekarang.bentuk[0].length / 2);
balokSekarang.y = 0;
if (tabrakan(balokSekarang)) {
selesai = true;
}
gambarBerikutnya();
}
function ambilAcak() {
return { bentuk: BENTUK[Math.floor(Math.random() * BENTUK.length)] };
}
// === Gambar balok yang akan datang ===
function gambarBerikutnya() {
konteksBerikutnya.clearRect(0, 0, kanvasBerikutnya.width, kanvasBerikutnya.height);
const ukKecil = 18;
balokNanti.bentuk.forEach((baris, bi) => {
baris.forEach((nilai, ki) => {
if (nilai) {
konteksBerikutnya.fillStyle = WARNA[nilai];
konteksBerikutnya.fillRect(ki * ukKecil + 10, bi * ukKecil + 10, ukKecil - 1, ukKecil - 1);
}
});
});
}
// === Cek tabrakan ===
function tabrakan(balok) {
return balok.bentuk.some((baris, bi) => {
return baris.some((nilai, ki) => {
if (!nilai) return false;
let nx = balok.x + ki;
let ny = balok.y + bi;
return nx < 0 || nx >= KOLOM || ny >= BARIS || (ny >= 0 && papan[ny][nx]);
});
});
}
// === Tempel balok ke papan ===
let tempel = () => {
balokSekarang.bentuk.forEach((baris, bi) => {
baris.forEach((nilai, ki) => {
if (nilai) papan[balokSekarang.y + bi][balokSekarang.x + ki] = nilai;
});
});
hapusGarisPenuh();
buatBalok();
};
// === Hapus garis penuh & tambah skor ===
function hapusGarisPenuh() {
let barisHapus = 0;
papan = papan.filter(baris => {
if (baris.every(sel => sel !== 0)) {
barisHapus++;
return false;
}
return true;
});
while (papan.length < BARIS) papan.unshift(Array(KOLOM).fill(0));
skor += barisHapus * 100;
teksSkor.innerText = skor;
}
// === Putar balok ===
function putar(balok) {
let ubah = balok.bentuk[0].map((_, i) => balok.bentuk.map(b => b[i]).reverse());
let asli = balok.bentuk;
balok.bentuk = ubah;
if (tabrakan(balok)) balok.bentuk = asli;
}
// === Gerakan otomatis ===
function gerakTurunOtomatis() {
balokSekarang.y++;
if (tabrakan(balokSekarang)) {
balokSekarang.y--;
tempel();
}
}
// === Kontrol Keyboard ===
document.addEventListener('keydown', e => {
if (selesai) return;
if (e.key === 'ArrowLeft') { balokSekarang.x--; if(tabrakan(balokSekarang)) balokSekarang.x++; }
if (e.key === 'ArrowRight') { balokSekarang.x++; if(tabrakan(balokSekarang)) balokSekarang.x--; }
if (e.key === 'ArrowDown') gerakTurunOtomatis();
if (e.key === 'ArrowUp') putar(balokSekarang);
gambarPapan();
});
// === Mulai / Ulang ===
tombolMulai.addEventListener('click', () => {
kosongkanPapan();
skor = 0;
selesai = false;
teksSkor.innerText = '0';
buatBalok();
if (jeda) clearInterval(jeda);
jeda = setInterval(() => {
if (!selesai) {
gerakTurunOtomatis();
gambarPapan();
} else {
clearInterval(jeda);
konteks.fillStyle = 'rgba(0,0,0,0.7)';
konteks.fillRect(0,0,kanvas.width,kanvas.height);
konteks.fillStyle = '#fff';
konteks.font = 'bold 22px sans-serif';
konteks.fillText('GAME SELESAI!', 40, 280);
}
}, 700);
});
</script>
</body>
</html>
Game Source: Blok Blaze - Buatan Sendiri
Creator: PixelHero77
Libraries: none
Complexity: complex (235 lines, 8.4 KB)
The full source code is displayed above on this page.
Remix Instructions
To remix this game, copy the source code above and modify it. Add a ARCADELAB header at the top with "remix_of: blok-blaze-buatan-sendiri-pixelhero77" to link back to the original. Then publish at arcadelab.ai/publish.