tetris klaar

This commit is contained in:
martijn.diersmann@pm.me
2026-09-26 20:38:55 +02:00
commit 4c1f670e9f
16 changed files with 1565 additions and 0 deletions
+141
View File
@@ -0,0 +1,141 @@
'use strict';
/* Tekenen van een blokje met simpele 3D-schaduwen */
function drawCell(ctx, px, py, size, color) {
ctx.fillStyle = color;
ctx.fillRect(px, py, size, size);
ctx.fillStyle = 'rgba(255,255,255,0.22)';
ctx.fillRect(px, py, size, size * 0.28);
ctx.fillRect(px, py, size * 0.28, size);
ctx.fillStyle = 'rgba(0,0,0,0.25)';
ctx.fillRect(px, py + size * 0.72, size, size * 0.28);
ctx.fillRect(px + size * 0.72, py, size * 0.28, size);
}
/* Ghost piece: alleen een omlijning, half transparant */
function drawGhostCell(ctx, px, py, size, color) {
ctx.save();
ctx.globalAlpha = 0.45;
ctx.strokeStyle = color;
ctx.lineWidth = Math.max(2, size * 0.12);
ctx.strokeRect(px + 3, py + 3, size - 6, size - 6);
ctx.restore();
}
/* Het hoofd-bord */
function drawBoard(canvas, game) {
const ctx = canvas.getContext('2d');
const size = CONSTANTS.CELL;
const W = CONSTANTS.COLS * size;
const H = CONSTANTS.ROWS * size;
ctx.clearRect(0, 0, W, H);
// achtergrond met subtiel verloop
const grad = ctx.createLinearGradient(0, 0, 0, H);
grad.addColorStop(0, '#121722');
grad.addColorStop(1, '#070a11');
ctx.fillStyle = grad;
ctx.fillRect(0, 0, W, H);
// gridlijnen
ctx.strokeStyle = 'rgba(255,255,255,0.05)';
ctx.lineWidth = 1;
for (let c = 1; c < CONSTANTS.COLS; c++) {
ctx.beginPath();
ctx.moveTo(c * size, 0);
ctx.lineTo(c * size, H);
ctx.stroke();
}
for (let r = 1; r < CONSTANTS.ROWS; r++) {
ctx.beginPath();
ctx.moveTo(0, r * size);
ctx.lineTo(W, r * size);
ctx.stroke();
}
// vastgezette blokken
for (let r = 0; r < CONSTANTS.ROWS; r++) {
for (let c = 0; c < CONSTANTS.COLS; c++) {
const color = game.board[r][c];
if (color) drawCell(ctx, c * size, r * size, size, color);
}
}
// flitsende rijen tijdens het wissen
if (game.flashLines.length) {
ctx.fillStyle = 'rgba(255,255,255,0.75)';
for (const r of game.flashLines) {
ctx.fillRect(0, r * size, W, size);
}
}
// ghost + actief blok
if (game.piece && !game.over) {
if (!game.locking) {
const ghostY = game.ghostY();
if (ghostY !== game.piece.y) {
const m = game.piece.matrix;
for (let r = 0; r < m.length; r++) {
for (let c = 0; c < m[r].length; c++) {
if (!m[r][c]) continue;
drawGhostCell(ctx, (game.piece.x + c) * size, (ghostY + r) * size, size, game.piece.color);
}
}
}
const m = game.piece.matrix;
for (let r = 0; r < m.length; r++) {
for (let c = 0; c < m[r].length; c++) {
if (!m[r][c]) continue;
const py = (game.piece.y + r) * size;
if (py < 0) continue; // boven het bord: niet tekenen
drawCell(ctx, (game.piece.x + c) * size, py, size, game.piece.color);
}
}
}
}
}
/* Kleine preview (hold) */
function drawHold(canvas, type) {
const ctx = canvas.getContext('2d');
const cell = CONSTANTS.PREVIEW_CELL;
ctx.clearRect(0, 0, canvas.width, canvas.height);
if (!type) return;
const shape = SHAPES[type];
const w = shape[0].length * cell;
const h = shape.length * cell;
const ox = (canvas.width - w) / 2;
const oy = (canvas.height - h) / 2;
for (let r = 0; r < shape.length; r++) {
for (let c = 0; c < shape[r].length; c++) {
if (!shape[r][c]) continue;
drawCell(ctx, ox + c * cell, oy + r * cell, cell, CONSTANTS.COLORS[type]);
}
}
}
/* Volgende blokken onder elkaar */
function drawNext(canvas, game) {
const ctx = canvas.getContext('2d');
const cell = CONSTANTS.PREVIEW_CELL;
ctx.clearRect(0, 0, canvas.width, canvas.height);
const list = game.preview;
const band = canvas.height / CONSTANTS.PREVIEW_COUNT;
for (let i = 0; i < list.length; i++) {
const type = list[i];
const shape = SHAPES[type];
const w = shape[0].length * cell;
const h = shape.length * cell;
const ox = (canvas.width - w) / 2;
const oy = i * band + (band - h) / 2;
for (let r = 0; r < shape.length; r++) {
for (let c = 0; c < shape[r].length; c++) {
if (!shape[r][c]) continue;
drawCell(ctx, ox + c * cell, oy + r * cell, cell, CONSTANTS.COLORS[type]);
}
}
}
}