Hello, so today i Use some Ai and I made a block blast.
here is the index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Block Blast Clone</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<h1>Block Blast Clone</h1>
<div id="info">
Score: <span id="score">0</span>
</div>
<div id="game">
<div id="board"></div>
<div>
<div id="pieces"></div>
<button id="newPiecesBtn">New Pieces</button>
</div>
</div>
<script>
const BOARD_SIZE = 10;
const boardEl = document.getElementById('board');
const piecesEl = document.getElementById('pieces');
const scoreEl = document.getElementById('score');
const newPiecesBtn = document.getElementById('newPiecesBtn');
let board = [];
let score = 0;
let currentPieces = [];
let draggedPiece = null;
const SHAPES = [
[[0,0]],
[[0,0],[0,1]],
[[0,0],[1,0]],
[[0,0],[0,1],[0,2]],
[[0,0],[1,0],[2,0]],
[[0,0],[0,1],[1,0],[1,1]],
[[0,0],[1,0],[1,1]],
[[0,1],[1,0],[1,1],[1,2]]
];
function initBoard() {
board = [];
boardEl.innerHTML = '';
for (let r = 0; r < BOARD_SIZE; r++) {
const row = [];
for (let c = 0; c < BOARD_SIZE; c++) {
row.push(0);
const cell = document.createElement('div');
cell.className = 'cell';
cell.dataset.row = r;
cell.dataset.col = c;
// Allow dropping
cell.addEventListener('dragover', e => e.preventDefault());
cell.addEventListener('drop', e => handleDrop(r, c));
boardEl.appendChild(cell);
}
board.push(row);
}
updateBoardUI();
}
function updateBoardUI() {
const cells = boardEl.querySelectorAll('.cell');
cells.forEach(cell => {
const r = parseInt(cell.dataset.row, 10);
const c = parseInt(cell.dataset.col, 10);
cell.classList.toggle('filled', board[r][c] === 1);
});
scoreEl.textContent = score;
}
function randomPiece() {
const shape = SHAPES[Math.floor(Math.random() * SHAPES.length)];
return { shape };
}
function generatePieces() {
currentPieces = [randomPiece(), randomPiece(), randomPiece()];
renderPieces();
}
function renderPieces() {
piecesEl.innerHTML = '';
currentPieces.forEach((piece, index) => {
if (!piece) return;
const { shape } = piece;
const rows = Math.max(...shape.map(p => p[0])) + 1;
const cols = Math.max(...shape.map(p => p[1])) + 1;
const pieceDiv = document.createElement('div');
pieceDiv.className = 'piece';
pieceDiv.style.gridTemplateColumns = `repeat(${cols}, 20px)`;
pieceDiv.style.gridTemplateRows = `repeat(${rows}, 20px)`;
// Enable dragging
pieceDiv.draggable = true;
pieceDiv.addEventListener('dragstart', () => {
draggedPiece = { piece, index };
});
for (let r = 0; r < rows; r++) {
for (let c = 0; c < cols; c++) {
const cellDiv = document.createElement('div');
const isFilled = shape.some(p => p[0] === r && p[1] === c);
if (isFilled) {
cellDiv.className = 'piece-cell';
} else {
cellDiv.style.width = '20px';
cellDiv.style.height = '20px';
}
pieceDiv.appendChild(cellDiv);
}
}
piecesEl.appendChild(pieceDiv);
});
}
function canPlacePiece(piece, baseRow, baseCol) {
for (const [dr, dc] of piece.shape) {
const r = baseRow + dr;
const c = baseCol + dc;
if (r < 0 || r >= BOARD_SIZE || c < 0 || c >= BOARD_SIZE) return false;
if (board[r][c] === 1) return false;
}
return true;
}
function placePiece(piece, baseRow, baseCol) {
for (const [dr, dc] of piece.shape) {
const r = baseRow + dr;
const c = baseCol + dc;
board[r][c] = 1;
}
clearLines();
score += piece.shape.length;
updateBoardUI();
}
function clearLines() {
let cleared = 0;
for (let r = 0; r < BOARD_SIZE; r++) {
if (board[r].every(cell => cell === 1)) {
cleared++;
for (let c = 0; c < BOARD_SIZE; c++) board[r][c] = 0;
}
}
for (let c = 0; c < BOARD_SIZE; c++) {
let full = true;
for (let r = 0; r < BOARD_SIZE; r++) {
if (board[r][c] === 0) full = false;
}
if (full) {
cleared++;
for (let r = 0; r < BOARD_SIZE; r++) board[r][c] = 0;
}
}
if (cleared > 0) score += cleared * 10;
}
function handleDrop(row, col) {
if (!draggedPiece) return;
const { piece, index } = draggedPiece;
if (canPlacePiece(piece, row, col)) {
placePiece(piece, row, col);
currentPieces[index] = null;
renderPieces();
}
draggedPiece = null;
}
newPiecesBtn.addEventListener('click', () => {
generatePieces();
});
initBoard();
generatePieces();
</script>
</body>
</html>
here is the style.css
/* ===== General Page Styling ===== */
body {
font-family: "Fredoka One", Arial, sans-serif;
background: linear-gradient(135deg, #ffecd2, #fcb69f);
color: #333;
display: flex;
flex-direction: column;
align-items: center;
margin: 0;
padding: 20px;
}
h1 {
font-size: 42px;
color: #ff6f61;
text-shadow: 3px 3px #ffffff;
margin-bottom: 10px;
}
/* ===== Game Layout ===== */
#game {
display: flex;
gap: 30px;
margin-top: 10px;
}
#info {
margin-top: 10px;
font-size: 22px;
font-weight: bold;
color: #ff6f61;
}
/* ===== Board Styling ===== */
#board {
display: grid;
grid-template-columns: repeat(10, 40px);
grid-template-rows: repeat(10, 40px);
gap: 4px;
background: #ffe6d9;
padding: 10px;
border-radius: 20px;
box-shadow: 0 8px 20px rgba(0,0,0,0.15);
}
.cell {
width: 40px;
height: 40px;
background: #ffd1b3;
border-radius: 10px;
transition: background 0.2s, transform 0.2s;
}
.cell.filled {
background: #ff8b3d;
animation: pop 0.25s ease-out;
}
/* Ghost preview */
.cell.ghost {
background: rgba(255, 255, 255, 0.5);
border: 2px dashed #ff8b3d;
}
/* ===== Pieces Section ===== */
#pieces {
display: flex;
flex-direction: column;
gap: 20px;
}
.piece {
display: inline-grid;
gap: 4px;
background: #ffe6d9;
padding: 10px;
border-radius: 16px;
cursor: grab;
transition: transform 0.2s, box-shadow 0.2s;
box-shadow: 0 6px 12px rgba(0,0,0,0.15);
}
.piece:hover {
transform: scale(1.08);
}
.piece:active {
transform: scale(1.15);
box-shadow: 0 0 20px #ff8b3d;
}
.piece-cell {
width: 28px;
height: 28px;
background: #ff6f61;
border-radius: 8px;
box-shadow: inset 0 4px 6px rgba(255,255,255,0.6),
inset 0 -4px 6px rgba(0,0,0,0.15);
}
/* ===== Buttons ===== */
button {
margin-top: 10px;
padding: 10px 18px;
border-radius: 12px;
border: none;
cursor: pointer;
background: #ff6f61;
color: #fff;
font-weight: bold;
font-size: 18px;
box-shadow: 0 6px 12px rgba(0,0,0,0.15);
transition: background 0.2s, transform 0.2s;
}
button:hover {
background: #ff8b3d;
transform: scale(1.05);
}
/* ===== Animations ===== */
@keyframes pop {
0% { transform: scale(0.6); }
60% { transform: scale(1.25); }
100% { transform: scale(1); }
}
here u can see how its look like
