Search⌘ K
AI Features

Tetrominoes

Explore how Tetrominoes, the Tetris game pieces made of four blocks, are defined and managed in JavaScript. Understand their shapes, colors, positioning on the board, and how to draw and update them within a game canvas, preparing you to implement moving pieces in your Tetris game.

A piece in Tetris is a shape consisting of four blocks moving as a unit. They are often called tetrominoes and come in seven different patterns and colors. The names I, J, L, O, S, T, and Z resemble their shape.

The seven Tetris pieces
The seven Tetris pieces

Tetromino matrix

We represent the J tetromino as a matrix where the number two represents the colored cells. We add a row of zeros to get a center to rotate around:

[2, 0, 0],  
[2, 2, 2],  
[0, 0, 0];

The tetrominoes spawn horizontally, with J, L, and T spawning flat-side first.

We will be using tetrominoes frequently, so we can make it into a class called Piece.

Piece class

The piece class has to know its position on the board, its color, and its shape. To be able to draw itself on the board, the piece class needs a reference to the canvas context.

For starters, we can hard-code the values of our piece in the piece class’s constructor:

Javascript (babel-node)
class Piece {
constructor(ctx) {
this.ctx = ctx;
this.color = 'blue';
this.shape = [
[2, 0, 0],
[2, 2, 2],
[0, 0, 0]
];
// Starting position.
this.x = 3;
this.y = 0;
}
}

Drawing the tetromino

To draw the tetromino on the board, we loop through the cells of the shape. If the value in the cell is greater than zero, we color that block:

   X →
Y [2, 0, 0]
↓ [2, 2, 2]
  [0, 0, 0]

So, we can color the [x, y] coordinates, like so:

[0, 0]
[0, 1], [1, 1], [2, 1]

However, we need to also keep track of where on the board the tetromino is at the moment. This is what the piece’s coordinates help us track.

[this.x, this.y] is the left-upper position of the shape:

  X →
Y [0, 0, 0,  0, 0, 0,  0, 0, 0, 0]
↓ [0, 0, 0, [2, 0, 0], 0, 0, 0, 0]
  [0, 0, 0, [2, 2, 2], 0, 0, 0, 0]
  [0, 0, 0, [0, 0, 0], 0, 0, 0, 0] 

// this.x = 3, this.y = 1

Therefore, [this.x + x, this.y + y] is the position of the block on the board. This is how we know what positions on the board we should color blue:

[4, 1]
[4, 2], [5, 2], [5, 3]

Now, that we have thought about the logical problem, the code implementation is easier:

Javascript (babel-node)
class Piece {
draw() {
this.ctx.fillStyle = this.color;
this.shape.forEach((row, y) => {
row.forEach((value, x) => {
if (value > 0) {
this.ctx.fillRect(this.x + x, this.y + y, 1, 1);
}
});
});
}
}

Initialization

Let’s create a tetromino on the board when we initialize it. To make it visible, we use the draw method of the Piece class:

Javascript (babel-node)
class Board {
constructor(ctx) {
this.ctx = ctx;
this.grid = this.getEmptyBoard();
this.piece = new Piece(ctx);
}
}

We need to clear the drawing area of the piece’s old representation with clearRect(). Using the width and height of the canvas, we can clean it between paints.

Here, we can use object destructuring to make the code cleaner:

Javascript (babel-node)
function draw() {
const { width, height } = ctx.canvas;
ctx.clearRect(0, 0, width, height);
board.piece.draw();
}

Try out the code and see the blue tetromino appear when pressing play.