Tiny Tetris Processing Clone (For Desktop, not Phones/Mobile)

This tiny Tetris clone, in just under 100 lines of Processing (~5500 characters) utilizes two classes, one to represent the Block and another to represent the Board. Unlike some of our other projects, this was written to a fixed size (500×500 pixels canvas size), and it requires a keyboard to play. [raw] [/raw] You can edit and run this code on the KTBYTE Coder
TetrisBoard tt = new TetrisBoard();
void setup() { size(500,500);  rectMode(CORNER); textSize(20);  }
void draw() {
  background(100); tt.display();
  if(!tt.gameover) {
    if(frameCount%max(20 - tt.level,0)==0 && !tt.moveCheck(1,0,0,true)) switch(tt.clearLines()) {
      case 0:break; case 1:tt.score+=40*(tt.level+1); break; case 2:tt.score+=100*(tt.level+1); break; 
      case 3:tt.score+=300*(tt.level+1); break; case 4:tt.score+=1200*(tt.level+1); break;
    }    
  }else{ fill(0); text("GAMEOVER\nPress A Key",60,10); if(keyPressed) tt=new TetrisBoard(); }
  fill(255,200,200); text("Score: "+tt.score+"\n"+"Level: "+tt.level, 260,50);
}
void keyPressed() {
  if(key==' ')                   while(tt.moveCheck(1,0,0,false)){}  else if(key != CODED) return;
  if(keyCode==UP)    tt.moveCheck(0,0,-1,false); else if(keyCode==LEFT)  tt.moveCheck(0,-1,0,false);
  if(keyCode==RIGHT) tt.moveCheck(0,1,0,false);  else if(keyCode==DOWN)  tt.moveCheck(1,0,0,false);
}
class TetrisBoard {
  int hiddenrows=2,linesCleared=0,w=10,h=22,xoffset=5,yoffset=10,Blkwidth=24,score=0,level=0;
  int[][] board = new int[h][w];
  boolean gameover = false;
  Blk held;
  TetrisBoard() { getNewBlk(); }
  void getNewBlk() {
    int r = (int)random(0,7); if(r==0) held = Blk.oBlk(); 
    if(r==1) held = Blk.iBlk(); if(r==2) held = Blk.sBlk(); if(r==3) held = Blk.zBlk(); 
    if(r==4) held = Blk.jBlk(); if(r==5) held = Blk.lBlk(); if(r==6) held = Blk.tBlk();
    if(!held.canPlaceIntoBoard(board)) gameover = true; else held.copyIntoBoard(board); 
  }
  int clearLines() {
    held.removeFromBoard(board);
    int out = 0; for(int j=h-1;j>=0;j--) {
      boolean line = true; for(int i=0;i<w;i++) if(board[j][i]==0) line = false; if(line) { for(int a=j;a>=0;a--) for(int b=0;b<w;b++) board[a][b]=a>0?board[a-1][b]:0;
        j++; out++; linesCleared++;
      }
    }
    held.copyIntoBoard(board); level = linesCleared / 10; 
    return out;
  }  
  boolean moveCheck(int dr, int dc, int drotate, boolean spawnNewIfFail) {
    held.removeFromBoard(board); held.rotate(drotate); held.r+=dr; held.c+=dc;
    if(!held.canPlaceIntoBoard(board)) {
      held.r-=dr; held.c-=dc; held.rotate(-drotate); held.copyIntoBoard(board);
      if(spawnNewIfFail) getNewBlk(); return false;
    }
    held.copyIntoBoard(board); return true;
  }
  color getcol(int v) {
    return new color[]{color(255),color(255,0,0),color(100,100,0),color(0,255,0),
                       color(0,255,255),color(255,0,255),color(0,0,255),color(255,100,0)}[v];
  }
  void display() {
    for(int j=hiddenrows;j<h;j++) for(int i=0;i<w;i++) {
      fill(getcol(board[j][i]));
      rect(i*Blkwidth+xoffset,(j-hiddenrows)*Blkwidth+yoffset,Blkwidth,Blkwidth);
    }
  }
}
static class Blk { //centered on row 0 column 0
  int[][][] b = new int[4][4][4]; //rotate, r, c
  int colCode, rot, r, c=2; //start at col 2
  static Blk oBlk(){return new Blk(new int[][][]{{{0,0,0,0},{0,1,1,0},{0,1,1,0},{0,0,0,0}}},1);}
  static Blk iBlk(){return new Blk(new int[][][]{{{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}}},2);}
  static Blk sBlk(){return new Blk(new int[][][]{{{0,0,0,0},{0,0,1,1},{0,1,1,0},{0,0,0,0}}
                                               ,{ {0,0,1,0},{0,0,1,1},{0,0,0,1},{0,0,0,0}}},3);} 
  static Blk zBlk(){return new Blk(new int[][][]{{{0,0,0,0},{0,1,1,0},{0,0,1,1},{0,0,0,0}}
                                               ,{ {0,0,0,1},{0,0,1,1},{0,0,1,0},{0,0,0,0}}},4);}
  static Blk lBlk(){return new Blk(new int[][][]{{{0,0,0,0},{0,1,1,1},{0,1,0,0},{0,0,0,0}}
                                               ,{ {0,0,1,0},{0,0,1,0},{0,0,1,1},{0,0,0,0}},
                                                 {{0,0,0,1},{0,1,1,1},{0,0,0,0},{0,0,0,0}}
                                               ,{ {0,1,1,0},{0,0,1,0},{0,0,1,0},{0,0,0,0}}},5);}
  static Blk jBlk(){return new Blk(new int[][][]{{{0,0,0,0},{0,1,1,1},{0,0,0,1},{0,0,0,0}}
                                               ,{ {0,0,1,1},{0,0,1,0},{0,0,1,0},{0,0,0,0}},
                                                 {{0,1,0,0},{0,1,1,1},{0,0,0,0},{0,0,0,0}}
                                               ,{ {0,0,1,0},{0,0,1,0},{0,1,1,0},{0,0,0,0}}},6);}
  static Blk tBlk(){return new Blk(new int[][][]{{{0,0,0,0},{0,1,1,1},{0,0,1,0},{0,0,0,0}}
                                               ,{ {0,0,1,0},{0,0,1,1},{0,0,1,0},{0,0,0,0}},
                                                 {{0,0,1,0},{0,1,1,1},{0,0,0,0},{0,0,0,0}}
                                               ,{ {0,0,1,0},{0,1,1,0},{0,0,1,0},{0,0,0,0}}},7);}
  void rotate(int drot) { rot = (rot + drot + b.length) % b.length; }
  Blk(int[][][] ps, int colCode) {
    this.colCode = colCode;
    for(int i=0;i<b.length;i++) for(int j=0;j<ps[i%ps.length].length;j++) 
      for(int k=0;k<ps[i%ps.length][j].length;k++) b[i][j][k] = ps[i%ps.length][j][k];
  }
  void removeFromBoard(int[][] board) {      copyIntoBoard(board, 0, false); }
  void copyIntoBoard(int[][] board) {        copyIntoBoard(board, colCode, false);  }
  boolean canPlaceIntoBoard(int[][] board) { return copyIntoBoard(board, 0, true); }
  boolean copyIntoBoard(int[][] board, int col, boolean checkMode) {
    for(int j=0;j<b[rot].length;j++) for(int i=0;i<b[rot][j].length;i++) if(b[rot][j][i] != 0)
      if(j+r<board.length&&i+c<board[j+r].length&&i+c>=0&&(board[j+r][i+c]==0||!checkMode)) {
        if(!checkMode) board[j+r][i+c]=col;
      }else if(checkMode) return false;
    return true;
  }  
}

Leave a Reply

Your email address will not be published. Required fields are marked *