How to Build Tetris with Phaser 3


How do you build Tetris with Phaser for beginners?

You can build Tetris with Phaser for beginners by combining a 10x20 grid array, tetromino shape matrices, and simple collision logic inside a single HTML file that uses the official Phaser 3 CDN Phaser Learn. By the end of this guide you will have a playable, guideline-flavored Tetris clone running in your browser with no build tools and no physics engine.

Controls: arrow keys move and rotate, space hard-drops, C holds, Z/X rotate; touch buttons appear on mobile.

How This Guide Was Built

This guide relies on official documentation and community reference materials rather than hands-on testing of the embedded game Wikipedia Tetris Guideline Phaser Learn. We verified the game history, guideline mechanics, scoring rules, the Phaser 3 CDN version, and the recommended scale modes against these sources. This guide is based on official documentation and community reference materials — we did not run the game hands-on in testing; it is a code walkthrough. Last verified: August 2026.

Why Tetris: A 40-Year History Lesson

Tetris was created by Alexey Pajitnov, a Soviet software engineer, in 1984-1985 at the Dorodnitsyn Computing Center of the Academy of Sciences; the name combines “tetra” (Greek for “four”) and “tennis” Wikipedia. The 1989 Game Boy version, published by Nintendo, popularized Tetris worldwide Wikipedia.

Tetris Rules: The Guideline in Plain English

The Tetris Guideline specifies a 10x20 playfield and seven tetrominoes with distinct colors: I cyan, O yellow, T purple, S green, Z red, J blue, and L orange Tetris Guideline. The 7-bag randomizer shuffles all seven tetrominoes and deals them one at a time, preventing long droughts of any piece Random Generator. Players can hold one piece for later use, preview the next pieces, and rotate using SRS wall kicks SRS.

Setting Up Phaser 3 in a Single HTML File

You set up Phaser 3 in a single HTML file by adding the CDN script tag pinned to phaser@3.90.0 and defining a minimal game config Phaser Learn ScaleManager docs. Use Phaser.Scale.FIT with CENTER_BOTH so the canvas scales responsively without distortion and stays centered on any screen.

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <script src="https://cdn.jsdelivr.net/npm/phaser@3.90.0/dist/phaser.min.js"></script>
</head>
<body>
  <script>
    const config = {
      type: Phaser.AUTO,
      width: 480,
      height: 560,
      parent: 'game',
      backgroundColor: '#000000',
      scale: {
        mode: Phaser.Scale.FIT,
        autoCenter: Phaser.Scale.CENTER_BOTH
      },
      scene: {
        create: create
      }
    };
    const game = new Phaser.Game(config);
    function create() {
      // game logic goes here
    }
  </script>
</body>
</html>

Data Structures: The Board Array and Tetromino Matrices

The board array is a 20-row by 10-column grid of zeros and colored values representing locked pieces Tetris Guideline. Each tetromino is a matrix of rotation states, and the SHAPES object maps each piece type to its four rotations.

const COLS = 10;
const ROWS = 20;
const board = [];
for (let r = 0; r < ROWS; r++) {
  board[r] = new Array(COLS).fill(0);
}

const SHAPES = {
  I: [
    [[0,0,0,0], [1,1,1,1], [0,0,0,0], [0,0,0,0]],
    [[0,0,1,0], [0,0,1,0], [0,0,1,0], [0,0,1,0]]
  ],
  O: [
    [[2,2], [2,2]]
  ],
  T: [
    [[0,1,0], [1,1,1], [0,0,0]],
    [[0,1,0], [0,1,1], [0,1,0]],
    [[0,0,0], [1,1,1], [0,1,0]],
    [[0,1,0], [1,1,0], [0,1,0]]
  ],
  S: [
    [[0,1,1], [1,1,0], [0,0,0]],
    [[0,1,0], [0,1,1], [0,0,1]]
  ],
  Z: [
    [[1,1,0], [0,1,1], [0,0,0]],
    [[0,0,1], [0,1,1], [0,1,0]]
  ],
  J: [
    [[1,0,0], [1,1,1], [0,0,0]],
    [[0,1,1], [0,1,0], [0,1,0]],
    [[0,0,0], [1,1,1], [0,0,1]],
    [[0,1,0], [0,1,0], [1,1,0]]
  ],
  L: [
    [[0,0,1], [1,1,1], [0,0,0]],
    [[0,1,0], [0,1,0], [0,1,1]],
    [[0,0,0], [1,1,1], [1,0,0]],
    [[1,1,0], [0,1,0], [0,1,0]]
  ]
};

Rotation Math and Wall Kicks

Rotation math transposes the matrix and reverses each row to produce a 90-degree clockwise turn, and SRS-style wall kicks try small offset adjustments to keep pieces legal near walls SRS. The simplified kick array tries offsets in order: [0,0], [-1,0], [1,0], [0,-1], then combinations.

function rotate(matrix) {
  const N = matrix.length;
  const result = [];
  for (let i = 0; i < N; i++) {
    result[i] = [];
    for (let j = 0; j < N; j++) {
      result[i][j] = matrix[N - j - 1][i];
    }
  }
  return result;
}

const KICK_OFFSETS = [
  [0, 0], [-1, 0], [1, 0], [0, -1],
  [-1, -1], [1, -1]
];

Movement, Drop, and Locking

Movement, drop, and locking rely on keyboard input processed each frame, a gravity timer based on delta time, and collision checks against the board array Tetris Guideline. When a piece can no longer fall, it locks into the board and a new tetromino spawns.

function isValidMove(board, piece, offsetX, offsetY) {
  for (let r = 0; r < piece.matrix.length; r++) {
    for (let c = 0; c < piece.matrix[r].length; c++) {
      if (piece.matrix[r][c] === 0) continue;
      const newX = piece.x + c + offsetX;
      const newY = piece.y + r + offsetY;
      if (newX < 0 || newX >= COLS || newY >= ROWS) return false;
      if (newY >= 0 && board[newY][newX]) return false;
    }
  }
  return true;
}

function mergeToBoard(board, piece) {
  for (let r = 0; r < piece.matrix.length; r++) {
    for (let c = 0; c < piece.matrix[r].length; c++) {
      if (piece.matrix[r][c]) {
        board[piece.y + r][piece.x + c] = piece.matrix[r][c];
      }
    }
  }
}

Line Clearing, Scoring, and Levels

Line clearing removes full rows and shifts everything above down, while scoring awards 100, 300, 500, or 800 points for clearing 1, 2, 3, or 4 lines respectively Scoring Marathon. Soft drops add 1 point per cell, hard drops add 2 points per cell, and levels increase every 10 lines, speeding up gravity.

function clearLines() {
  let linesCleared = 0;
  outer: for (let y = ROWS - 1; y >= 0; y--) {
    for (let x = 0; x < COLS; x++) {
      if (!board[y][x]) continue outer;
    }
    const row = board.splice(y, 1)[0].fill(0);
    board.unshift(row);
    linesCleared++;
    y++;
  }
  if (linesCleared > 0) {
    const points = [0, 100, 300, 500, 800][linesCleared];
    score += points * level;
    lines += linesCleared;
    level = Math.floor(lines / 10) + 1;
  }
}

Using AI Tools to Build Tetris

Using AI tools to build Tetris works best when you describe the board array and tetromino matrices first, then ask the assistant to generate rotation math and collision logic step by step Phaser Learn. AI assistants excel at boilerplate like game config and input handling, but you must verify collision and locking logic yourself since those details are easy to get wrong.

Frequently Asked Questions

Why does my tetromino rotate into a wall?

Your tetromino rotates into a wall because rotation alone can push a piece outside legal bounds, which is why SRS wall kicks try small offset adjustments after each turn SRS. Add a kick loop that checks isValidMove with each offset in order and accepts the first one that succeeds, falling back to the original rotation if none work.

Do I need a physics engine for Tetris?

No physics engine is needed for grid-based puzzle games — Tetris is pure array logic Tetris Guideline. Every collision, rotation, and lock check happens against a 2D board array, so Phaser’s Arcade or Matter systems only add unnecessary overhead to what is already solvable with simple matrix math.

How do I add a hold feature later?

You add a hold feature by storing one tetromino in a separate variable and swapping it with the current piece when the player presses hold Tetris Guideline. Make sure to reset the held piece’s position, prevent holding twice in a row, and update your next-piece queue so the flow of tetrominoes stays consistent.

Where to Go Next

After building this Tetris clone, explore our other published games for more Phaser examples and step-by-step walkthroughs. You might also enjoy our Phaser platformer tutorial to learn character movement, or read Phaser vs PixiJS vs Three.js comparison to pick your next rendering tool. For a bigger challenge, try building a DOOM raycaster with vanilla JavaScript.