1

I'm a student and I was given the task of creating a retro arcade game on Processing (pong, space invaders, breakout, tetris etc.) but with a twist. The twist I thought was to create a Tetris Tower Stacker, which is like Tetris but instead of controlling the falling tetrominoes, we're just catching them using a platform that we can move from left to right. This eventually leads to a tower made out of tetris pieces. Example sketch

I may have chosen something that's a bit too hard for my current level (mega beginner). I managed to create the tetris code by watching tutorials, and it works fine with no issues, but I'm having trouble adding the platform. Even if I manage to add the platform, how will I make it collide with the pieces? I could really use some advice.

Here is my code so far that is just Tetris (written in Processing):

int[][] board = new int[40][40]; // 40 columns, 40 rows
int cols = 40;
int rows = 40;
color col = color(random(70, 255), random(70, 255), random(70, 255));
int[][][] pieces = {
  {{1, 1, 1, 1}}, // I
  {{1, 1, 0}, {0, 1, 1}}, // Z
  {{0, 1, 1}, {1, 1, 0}}, // S
  {{1, 1}, {1, 1}}, // O
  {{1, 1, 1}, {0, 1, 0}}, // T
  {{0, 1, 0}, {1, 1, 1}}, // L
  {{1, 0, 0}, {1, 1, 1}}   // J
};
int[][] currentPiece;
int currentX, currentY;
int score = 0;
int lines = 0;
int timer = 0;
int level = 1;

void setup() {
  size(800, 800);
  frameRate(100); //to make the game a bit faster
  currentPiece = pieces[int(random(7))];
  currentX = int(random(39));
  currentY = 0;
}

void draw() {
  background(255);
  drawBoard();
  drawPieceFunction();
  drawText();
}

void keyPressed() {
  if (keyCode == LEFT) {
    if (!checkCollision(currentPiece, currentX-1, currentY)) {
      currentX--;
    }
  } else if (keyCode == RIGHT) {
    if (!checkCollision(currentPiece, currentX+1, currentY)) {
      currentX++;
    }
  } else if (keyCode == UP) {
    rotatePiece();
  } else if (keyCode == DOWN) {
    if (!checkCollision(currentPiece, currentX, currentY+1)) {
      currentY++;
    }
  }
}

void drawBoard() {
  for (int x = 0; x < cols; x++) {
    for (int y = 0; y < rows; y++) {
      if (board[x][y] != 0) {
        fill(0);
        rect(x*20, y*20, 20, 20);
      }
    }
  }
}

void drawPiece(int[][] piece, int x, int y) {
  for (int px = 0; px < piece.length; px++) {
    for (int py = 0; py < piece[0].length; py++) {
      if (piece[px][py] != 0) {
        fill(col);
        rect((x+px)*20, (y+py)*20, 20, 20);
      }
    }
  }
}

boolean checkCollision(int[][] piece, int x, int y) {
  for (int px = 0; px < piece.length; px++) {
    for (int py = 0; py < piece[0].length; py++) {
      if (piece[px][py] != 0) {
        if (x+px < 0 || x+px >= cols || y+py >= rows || board[x+px][y+py] != 0) {
          return true;
        }
      }
    }
  }
  return false;
}

void rotatePiece() {
  int[][] newPiece = new int[currentPiece[0].length][currentPiece.length];
  for (int x = 0; x < currentPiece.length; x++) {
    for (int y = 0; y < currentPiece[0].length; y++) {
      newPiece[y][currentPiece.length-1-x] = currentPiece[x][y];
    }
  }
  if (!checkCollision(newPiece, currentX, currentY)) {
    currentPiece = newPiece;
  }
}

void addToBoard(int[][] piece, int x, int y) {
  for (int px = 0; px < piece.length; px++) {
    for (int py = 0; py < piece[0].length; py++) {
      if (piece[px][py] != 0) {
        board[x+px][y+py] = piece[px][py];
      }
    }
  }
}

void clearLines() {
  int numLines = 0;
  for (int y = 0; y < rows; y++) {
    boolean full = true;
    for (int x = 0; x < cols; x++) {
      if (board[x][y] == 0) {
        full = false;
      }
    }
    if (full) {
      for (int yy = y; yy > 0; yy--) {
        for (int x = 0; x < rows; x++) {
          board[x][yy] = board[x][yy-1];
        }
      }
      numLines++;
    }
  }
  if (numLines > 0) {
    score += 100*numLines*numLines;
    lines += numLines;
    if (lines >= 10) {  // level up after 10 lines
      level++;
      lines -= 10;
    }
  }
}
void drawText() {  //draws the score, lines, level texts on the screen
  textAlign(LEFT);
  textSize(18);
  fill(112, 128, 144);
  text("Score: " + score, 10, height-40);
  text("Lines: " + lines, 10, height-15);
  text("Level: " + level, width-70, height-15);
}

void drawPieceFunction() {
  drawPiece(currentPiece, currentX, currentY);
  if (timer % (30 - level*2) == 0) {  // speed up over time
    currentY++;
    if (checkCollision(currentPiece, currentX, currentY)) {  // if collision, add piece to board and start new piece
      addToBoard(currentPiece, currentX, currentY-1);
      clearLines();
      currentPiece = pieces[int(random(7))];
      currentX = int(random(39));
      currentY = 0;
      if (checkCollision(currentPiece, currentX, currentY)) {  // if new piece collides, game over
        textSize(64);
        textAlign(CENTER);
        fill(112, 128, 144);
        text("Game Over", width/2, height/2);
        noLoop();
      }
    }
  }
  timer++;
}
cdy
  • 11
  • 3

1 Answers1

0

I'm assuming this code is just Tetris right now. If so, these would be my steps for creating this game.

  1. I would start by adding the pong slider at the bottom, make it follow the mouse or moveable with arrow keys.

  2. Then add a check for collision between the slider and falling pieces. If they collide, add the shape of the piece to the slider so they act as one.

  3. When a new piece is added to the slider shape, check if there is a line complete, and if so, follow the usual Tetris rules.

Right now, your program is built such that a piece is added to the board and is stationary, I think you should change it so that the slider is what you are adding pieces to and have it act as one moveable graphic component. Hope that helps!

CodingNinja
  • 245
  • 1
  • 12
  • Thank you for your comment! It really helped me get closer to my goal! I managed to add the pong slider, and made it controllable by left-right arrow keys. But I couldn't figure out how to make it collide with the falling pieces. Right now, the program throws the error "ArrayIndexOutOfBoundsException: Index 17 out of bounds for length 9", probably because the slider is only made of 9 blocks, and doesn't have enough space to accomodate the new pieces. It might be a totally different issue though, as I'm pretty new to programming. – cdy Feb 24 '23 at 20:44