Игра «Тетрис»

Классический вариант игры «Тетрис»

Файл index.html

<!DOCTYPE html>
<html>
  <head>
    <title>Tetris</title>
    <style>
      canvas {
        border: 1px solid black;
      }
    </style>
  </head>
  <body>
    <canvas id="canvas" width="240" height="400"></canvas>
    <script src="tetris.js"></script>
  </body>
</html>

Файл tetris.js

const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");

const ROWS = 20;
const COLS = 10;
const BLOCK_SIZE = 20;

const colors = [
  "#000000",
  "#FF0000",
  "#00FF00",
  "#0000FF",
  "#FFFF00",
  "#00FFFF",
  "#FF00FF",
  "#C0C0C0",
];

const shapes = [
  [
    [1, 1],
    [1, 1],
  ],
  [
    [0, 2, 0],
    [2, 2, 2],
  ],
  [
    [0, 3, 3],
    [3, 3, 0],
  ],
  [
    [4, 4, 0],
    [0, 4, 4],
  ],
  [
    [5, 5, 5, 5],
  ],
  [
    [0, 6, 0, 0],
    [0, 6, 0, 0],
    [0, 6, 0, 0],
    [0, 6, 0, 0],
  ],
  [
    [0, 0, 7],
    [7, 7, 7],
    [0, 0, 0],
  ],
];

let board = [];
let currentShape = null;
let currentX = 0;
let currentY = 0;
let score = 0;

function newShape() {
  const shapeIndex = Math.floor(Math.random() * shapes.length);
  const shape = shapes[shapeIndex];
  currentShape = [];
  for (let i = 0; i < shape.length; i++) {
    currentShape[i] = [];
    for (let j = 0; j < shape[i].length; j++) {
      currentShape[i][j] = shape[i][j];
    }
  }
  currentX = Math.floor((COLS - currentShape[0].length) / 2);
  currentY = 0;
}

function init() {
  for (let i = 0; i < ROWS; i++) {
    board[i] = [];
    for (let j = 0; j < COLS; j++) {
      board[i][j] = 0;
    }
  }
  newShape();
  draw();
}

function drawBlock(x, y, color) {
  ctx.fillStyle = colors[color];
  ctx.fillRect(x * BLOCK_SIZE, y * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE);
  ctx.strokeStyle = "#000000";
  ctx.strokeRect(x * BLOCK_SIZE, y * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE);
}

function draw() {
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  for (let i = 0; i < ROWS; i++) {
    for (let j = 0; j < COLS; j++) {
      if (board[i][j]) {
        drawBlock(j, i, board[i][j]);
      }
    }
  }
  for (let i = 0; i < currentShape.length; i++) {
    for (let j = 0; j < currentShape[i].length; j++) {
      if (currentShape[i][j]) {
        drawBlock(currentX + j, currentY + i, currentShape[i][j]);
      }
    }
  }
  ctx.fillStyle = "#000000";
  ctx.font = "20px Arial";
  ctx.fillText(`Score: ${score}`, 10, 30);
}

function moveDown() {
  if (canMove(0, 1)) {
    currentY++;
  } else {
    freeze();
    clearLines();
    newShape();
  }
  draw();
}

function canMove(dx, dy) {
  for (let i = 0; i < currentShape.length; i++) {
    for (let j = 0; j < currentShape[i].length; j++) {
      if (currentShape[i][j]) {
        const newX = currentX + j + dx;
        const newY = currentY + i + dy;
        if (newX < 0 || newX >= COLS || newY >= ROWS) {
          return false;
        }
        if (newY < 0) {
          continue;
        }
        if (board[newY][newX]) {
          return false;
        }
      }
    }
  }
  return true;
}

function freeze() {
  for (let i = 0; i < currentShape.length; i++) {
    for (let j = 0; j < currentShape[i].length; j++) {
      if (currentShape[i][j]) {
        board[currentY + i][currentX + j] = currentShape[i][j];
      }
    }
  }
}

function clearLines() {
  let linesCleared = 0;
  for (let i = ROWS - 1; i >= 0; i--) {
    let rowFilled = true;
    for (let j = 0; j < COLS; j++) {
      if (board[i][j] === 0) {
        rowFilled = false;
        break;
      }
    }
    if (rowFilled) {
      for (let k = i; k > 0; k--) {
        for (let j = 0; j < COLS; j++) {
          board[k][j] = board[k - 1][j];
        }
      }
      linesCleared++;
      i++;
    }
  }
  if (linesCleared > 0) {
    score += linesCleared * 10;
  }
}

document.addEventListener("keydown", (event) => {
  switch (event.keyCode) {
    case 37:
      if (canMove(-1, 0)) {
        currentX--;
        draw();
      }
      break;
    case 38:
      rotate();
      draw();
      break;
    case 39:
      if (canMove(1, 0)) {
        currentX++;
        draw();
      }
      break;
    case 40:
      moveDown();
      break;
  }
});

function rotate() {
  const newShape = [];
  for (let i = 0; i < currentShape[0].length; i++) {
    newShape[i] = [];
    for (let j = 0; j < currentShape.length; j++) {
      newShape[i][j] = currentShape[currentShape.length - 1 - j][i];
    }
  }
  currentShape = newShape;
  if (!canMove(0, 0)) {
    currentShape = oldShape;
  }
}

init();
setInterval(moveDown, 500);

2 Comments

  1. Hey there! Do you know if they make any plugins to assist with Search
    Engine Optimization? I’m trying to get my site to rank for some targeted keywords but I’m not
    seeing very good results. If you know of any please share.
    Kudos! I saw similar art here: Eco product

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *