A simple collision system for a Tetris Game + A strange idea

edited May 2016 in How To...

Hello.

I am making a Tetris game in processing and I was wondering how I would go about making a collision system for my game.

I figured that the collision system would also be tied to the display system of the game, considering I have a vague idea of how it would work.

I'm assuming an easy way to do this would be to use the pixel array as a way of checking whether blocks were next to each other or at the bottom. Keep in mind that the screen resolution is going to be with 35 as the size of the block and a height of 550.

I'm also guessing that having a block class that generates each shape when it is passed into will also help.

Is what I'm saying correct? If so, how would I code this? If not, what is a better solution?

Also, I'm planning of having a special gamemode for my tetris game where after a certain amount of time after a new block is generated (probably an arbitrary number, like 5 seconds) another block comes down which you have no control over until the block you control stops moving.

How would I go about doing this as well?

(a reply soon would be greatly appreciated as the project is due at the end of the working week - other aspects of the project are finished or are towards completion!)

Thanks.

Answers

  • Answer ✓

    I have seen different people go about making logic like this before.

    In general the idea is to keep a boolean array (or a double boolean array if you prefer to think that way) which represents whether or not a block is present in a cell. Lets say that false means that no block is occupying a cell and true means that a block is occupying a cell.

    As a block falls, you check if any of the cells directly below it are true / occupied, if it is then you know that the block must stop there. Say you have one of those 2x2 blocks falling, you would be checking the two cells directly below it as it falls to see if they are true / occupied.

    The reason to do it this way is to avoid testing collisions with numbers (more efficient). As for display, the boolean array gives enough information to represent the blocks visually but now the logic for display is not tied into the logic for collisions.

    If this all makes sense, then perhaps an integer array may be useful instead which works very similarly to the boolean array. 0 could represent no block occupying a cell and any other number could represent that a block is occupying a cell but the advantage is that you could associate the numbers with whatever colors you will need for display.

    Personally I don't think of this as object oriented, just tests on a boolean / integer array with the one block falling marked as the "active" one. Seeing as how when a line is filled in Tetris and sections of blocks are removed but not necessarily the entire block, this would make object oriented conditions unnecessarily difficult but not so for a boolean / integer array.

  • Answer ✓

    As said, movements in a Tetris game are highly constrained (no partial lateral block shift), so you don't need to do a pixel-level collision check (unlike a platform game, for example), but a simple check in a block-level grid is enough.

    In other terms, have data representing the entities (block & area) to do the collision and alignment logic, and manage the display from it.

  • Answer ✓

    In short, the area is the matrix: final boolean[][] area = new boolean[ROWS][COLS];.
    Each element represents either the presence or absence of a fixed-size tile square.

  • edited July 2014 Answer ✓

    hello,

    just a few remarks. There are also L and T shaped pieces. It is not easy to know which blocks in the falling piece are "down". Because other blocks within the piece are on the lower site, each time when you rotate.

    To avoid the hassle to determine which blocks within the current piece ("L") are on the lower site, you could (and that's the idea here) go upwards from the piles and check for a collision within the grid.

    Grids

    So you got 2 grids: The entire game grid A and one falling piece with a grid B:

    x

    x

    x

    x x x

    copy B into A temporarily, check for collision (is there a stone of the piece directly above one pile?) if so, copy B into A permanently, otherwise delete B from A, let it fall by one line and start again.

    I made a piece editor once, to create new pieces like (+ or . . or . : )

    the blocks within one piece don't have to be connected.

    Best, Chrisir ;-)

  • Thanks for the help.

    I've managed to cobble something that starts to resemble a collision system together here, but I'm getting 'Expecting EOF, got whatever' issues.

    I'm fixing some of these by putting them into methods, but this won't work for the movement system or the collision system as they actually have to return stuff.

    What can I do to fix this?

    Also, how do I do the generation of new blocks?

    //Collision System for Blicks
    //SDD Major Work
    //By ---------
    //Last Modified: 16/7/14
    
    boolean collide = false;
    
    int x = 22;
    int y = 10;
    
    //declaring arrays
    final int[][] ScreenDrawBackground = new int[22][10];
    final int[][] ScreenDrawPlayerBlock = new int [y][x];
    //initially setting the screen background and player block to all zeros
    
    void beginDraw() {
    for (int i = 0; i < ScreenDrawBackground.length; i++) {
        ScreenDrawBackground[i][i] = 0;
      } for (int i = 0; i < ScreenPlayerBlock.length; i++) {
        ScreenDrawBackground[i][i] = 0;
      }
    }
    //for line clearing
    void clear() {    <<<<<<-------Can't be a void as it needs to return score, but still
      if (ScreenDrawBackground[y-1][x] != o) {
        for (int i = y-1; i < ScreenDrawBackground.length - y; i++) {
          ScreenDrawBackground[i] = 0;
        }
        score = (1000 * y);
      }
    }
    
    //for moving a block
    if (keyPressed && (key = CODED)) {
      //Left
      if (keyCode = LEFT) {
        //check left
        if (ScreenDrawBackground[y][x-1] == 0) {
          x --;
        } else {
          collide = true; 
        }
      } else if (keyCode = RIGHT) {
         //check right
        if (ScreenDrawBackground[y][x+1] == 0) {
          x ++;
        } else {
          collide = true;
        }
      } else if (keyCode = DOWN) {
        //check down
        if (ScreenDrawBackground[y+1][x] == 0) {
          y ++;
        } else {
          collide = true;
        }
      }
    }
    
    //If a collision occurs
    if (collide = true) {
      //code for collision goes here. 
      //Essentially, the block is added to ScreenDrawBackground, like this:
      arrayCopy(ScreenDrawPlayerBlock, ScreenDrawBackground);
      //Then, ScreenDrawPlayerBlock is set to 0s.
      for (int i = 0; i < ScreenPlayerBlock.length; i++) {
        ScreenDrawBackground[i][i] = 0; 
      } //At this point, a new block is drawn on top of the screen.
      // This will be implemented tommorow as I have no idea how to do that.
    }
    
  • edited July 2014

    Just doing a quick look, I've spotted a bug at line #61:
    You're assigning the value true to variable collide rather than just checking for that! [..]

  • edited July 2014

    tetris was a topic here some weeks ago

    this is what I made back then (since you asked how to start a new block)

    it has no collision

    most of it is by other guys here in the forum

    // Object object1;
    int possX, possY, time;
    int unit = 25;
    boolean[] occupied = new boolean[10*20];
    
    Piece currPiece = new Piece(); 
    ArrayList<Piece> pieces = new ArrayList();
    
    
    void figure1() {
      fill(204, 102, 0);
      rect(possX * unit, possY * unit, unit, 4 * unit);
    }
    void figure2() {
      fill(204, 12, 100);
      rect(possX * unit, possY * unit, 2 * unit, 2 * unit);
    }
    void figure3() {
      fill(55, 102, 10);
      rect(possX * unit, possY * unit, unit, unit);
    }
    void setup() {
      size(25 * unit, 20 * unit);
      fill(0, 25, 0);
      //  object1 = new Object();
    
      String []arrString = new String [5];
    
      currPiece=new Piece();
      arrString[0] = "000000";
      arrString[1] = "000100";
      arrString[2] = "000100";
      arrString[3] = "001100";
      arrString[4] = "000000";
      currPiece.gridFill (arrString);
      currPiece.colPiece = color(0, 0, 255);
      pieces.add(currPiece);
    
      currPiece=new Piece();
      arrString[0] = "000000";
      arrString[1] = "001000";
      arrString[2] = "011100";
      arrString[3] = "000000";
      arrString[4] = "000000";
      currPiece.gridFill (arrString);
      currPiece.colPiece = color(255, 0, 0);
      pieces.add(currPiece);
    
      currPiece=new Piece();
      arrString[0] = "000000";
      arrString[1] = "000000";
      arrString[2] = "011110";
      arrString[3] = "000000";
      arrString[4] = "000000";
      currPiece.gridFill (arrString);
      currPiece.colPiece = color(255, 0, 0);
      pieces.add(currPiece);
    
      currPiece=new Piece();
      arrString[0] = "000000";
      arrString[1] = "000100";
      arrString[2] = "000100";
      arrString[3] = "000110";
      arrString[4] = "000000";
      currPiece.gridFill (arrString);
      currPiece.colPiece = color(0, 244, 255);
      pieces.add(currPiece);
    
      currPiece=new Piece();
      arrString[0] = "000000";
      arrString[1] = "000110";
      arrString[2] = "000110";
      arrString[3] = "000000";
      arrString[4] = "000000";
      currPiece.gridFill (arrString);
      currPiece.colPiece = color(255, 0, 0);
      pieces.add(currPiece);
    
      newPiece ();
    }
    
    void draw() {
      fill(255, 0, 0);
      text ("hit n for new piece; m rotate", width/2+30, 44);
      fall();
      display();
      currPiece.display();
    }
    
    void newPiece () {
      println ("new");
      currPiece = pieces.get(int(random(pieces.size())));
      possY=0;
    }
    
    void keyPressed() {
      if (key == CODED) {
        if (keyCode == LEFT && possX > 0 && !occupied[(possX-1)+possY*10]) possX--;
        if (keyCode == RIGHT && possX < 9 && !occupied[(possX+1)+possY*10]) possX++;
        if (keyCode == DOWN) drop();
      }
      else {
        if (key == 'm') spin(key);
        if (key == 'n') newPiece ();
      }
    }
    void fall() {
      if (millis() > time + 1000) {
        time = millis();
        possY++;
        if (possY < 19) {
          int index = possX + possY * 10;
          int bottomIndex = possX + (possY + 1) * 10;
          if (occupied[bottomIndex]) {
            // occupied[index] = true;
            possY = 0;
          }
        }
        else {
          //  occupied[possX+190] = true;
          time = millis();
          //occupiedY = 0;
        }
      }
    }
    void display() {
      for (int i = 0; i < 200; i++) {
        int x = i % 10;
        int y = i / 10;
        if (occupied[i]) 
          fill(255, 127, 127);
        else 
          fill(255);
        rect(x * unit, y * unit, unit, 3 * unit);
      }
      fill(127, 127, 255);
      rect(possX * unit, possY * unit, unit, unit);
    }
    void drop() {
      for (int i = 19; i >= 0; i--) {
        int index = possX+i*10;
        if (!occupied[index]) {
          occupied[index] = true;
          possY = 0;
          break;
        }
      }
    }
    void spin(char qa) {
      if (qa == 'm') {
        //rotate(0.25);
        currPiece.rotate();
      }
    }
    // ============================================
    class Piece {
    
      boolean [][]grid = new boolean [6][6];  
      color colPiece = color(0, 0, 255);
    
      // **************
      // no explicit constructor here yet 
      // **************
    
      void gridFill (String[] arrString) {
        for (int i = 0 ; i < arrString.length; i++) {
          for (int j = 0 ; j < arrString[0].length(); j++) {
            char currLetter = arrString [i].charAt(j);
            if (currLetter == '1') {
              grid [i][j] = true;
            }
            else {
              grid [i][j] = false;
            }
          }
        }
      }  // method
    
      void display() {
        for (int i = 0 ; i < grid.length; i++) {
          for (int j = 0 ; j < grid.length; j++) {
            //        int x = i % 10;
            //        int y = i / 10;
            if (  grid [i][j] )
            {
              fill(colPiece);
              rect(i * unit+possX*unit, j * unit+possY*unit, unit, unit);
            }
            else 
            {
              // fill(255);
            }
          }
        }
      } // method
    
      void rotate() {
        boolean [][]temp = new boolean [6][6];
        println ("rotate");
        // copy 
        for (int i = 0 ; i < grid.length; i++) {
          for (int j = 0 ; j < grid.length; j++) {
            temp [i][j]=grid [i][j];
          }
        }
        for (int i = 0 ; i < grid.length; i++) {
          for (int j = 0 ; j < grid.length; j++) {
            grid [5-j][i]=temp [i][j];
          }
        }
      }
      //
    }//class 
    
    //
    
  • edited July 2014

    line 61: what gotoloop is saying:

    to check for equalness use == so it's

    if (collide == true) {

    or just

    if (collide) {

    The sign = is merely for assinging a value, not for comparison

    Best, Chrisir ;-)

  • edited July 2014

    Thanks.

    What do you think is causing the 'Expecting EOF, found 'thing'' error?

  • Many times a missing semicolon or closing curly brace can cause that.
    I advise you to hit CTRL+T inside Processing's IDE. It aligns and indents the code.
    So it's easier to spot if there's anything amiss somewhere!

  • Alright, I'm getting closer now.

    //Collision System for Blicks
    //SDD Major Work
    //By ---------
    //Last Modified: 16/7/14
    
    
    int x = 22;
    int y = 10;
    int rot = 1; //for rotation
    public boolean nocollide = true;
    
    //declaring arrays
    final int[][] ScreenDrawBackground = new int[22][10];
    final int[][] ScreenDrawPlayerBlock = new int[4][2];
    //initially setting the screen background and player block to all zeros
    
    void beginDraw() {
      for (int i = 0; i < ScreenDrawBackground.length; i++) {
        ScreenDrawBackground[i][i] = 0;
      } 
      for (int i = 0; i < ScreenDrawPlayerBlock.length; i++) {
        ScreenDrawBackground[i][i] = 0;
      }
    }
    //for line clearing
    void clear() {
      if (ScreenDrawBackground[y-1][x] != 0) {
        for (int i = y-1; i < ScreenDrawBackground.length - y; i++) {
          ScreenDrawBackground[i][i] = 0;
        }
        score = (1000 * y);
      }
    }
    
    void createBlock() {
      //creating blocks
      int choice = int(random(1, 5));
      if (choice == 1) {
        ScreenDrawPlayerBlock[0][0] = 0;
        ScreenDrawPlayerBlock[0][1] = 3;
        ScreenDrawPlayerBlock[0][0] = 0;
        ScreenDrawPlayerBlock[0][1] = 4;
        ScreenDrawPlayerBlock[0][0] = 0;
        ScreenDrawPlayerBlock[0][1] = 5;
        ScreenDrawPlayerBlock[0][0] = 0;
        ScreenDrawPlayerBlock[0][1] = 6;
      } else if (choice == 2) {  
        ScreenDrawPlayerBlock[0][0] = 0;
        ScreenDrawPlayerBlock[0][1] = 4;
        ScreenDrawPlayerBlock[0][0] = 0;
        ScreenDrawPlayerBlock[0][1] = 5;
        ScreenDrawPlayerBlock[0][0] = 1;
        ScreenDrawPlayerBlock[0][1] = 4;
        ScreenDrawPlayerBlock[0][0] = 1;
        ScreenDrawPlayerBlock[0][1] = 5;
      } else if (choice == 3) {
        ScreenDrawPlayerBlock[0][0] = 0;
        ScreenDrawPlayerBlock[0][1] = 3;
        ScreenDrawPlayerBlock[0][0] = 0;
        ScreenDrawPlayerBlock[0][1] = 4;
        ScreenDrawPlayerBlock[0][0] = 1;
        ScreenDrawPlayerBlock[0][1] = 4;
        ScreenDrawPlayerBlock[0][0] = 1;
        ScreenDrawPlayerBlock[0][1] = 5;
      } else if (choice == 4) {
        ScreenDrawPlayerBlock[0][0] = 0;
        ScreenDrawPlayerBlock[0][1] = 3;
        ScreenDrawPlayerBlock[0][0] = 0;
        ScreenDrawPlayerBlock[0][1] = 4;
        ScreenDrawPlayerBlock[0][0] = 0;
        ScreenDrawPlayerBlock[0][1] = 5;
        ScreenDrawPlayerBlock[0][0] = 1;
        ScreenDrawPlayerBlock[0][1] = 4;
      } else if (choice == 5) {
        ScreenDrawPlayerBlock[0][0] = 0;
        ScreenDrawPlayerBlock[0][1] = 4;
        ScreenDrawPlayerBlock[0][0] = 1;
        ScreenDrawPlayerBlock[0][1] = 4;
        ScreenDrawPlayerBlock[0][0] = 2;
        ScreenDrawPlayerBlock[0][1] = 4;
        ScreenDrawPlayerBlock[0][0] = 2;
        ScreenDrawPlayerBlock[0][1] = 5;
      } else {
      }
    }
    
    
    //for moving a block
    void moveBlocks() {
      if (keyPressed && (key == CODED)) {
        //Left
        if (keyCode == LEFT) {
          //check left
          for (int i = 0; i < 4; i++) {
            int bx = ScreenDrawPlayerBlock[i][0]; 
            int by = ScreenDrawPlayerBlock[i][1];
            if (ScreenDrawBackground[by][bx-1] != 0) {
              nocollide = false;
            }
          }
          if (nocollide) {
            for (int i = 0; i < 4; i++) {
              ScreenDrawPlayerBlock[i][0]--;
            }
          }
        } else if (keyCode == RIGHT) {
          //check right
          for (int i = 0; i < 4; i++) {
            int bx = ScreenDrawPlayerBlock[i][0]; 
            int by = ScreenDrawPlayerBlock[i][1];
            if (ScreenDrawBackground[by][bx+1] != 0) {
              nocollide = false;
            }
          }
          if (nocollide) {
            for (int i = 0; i < 4; i++) {
              ScreenDrawPlayerBlock[i][0]++;
            }
          }
        } else if (keyCode == DOWN) {
          //check down
          if (ScreenDrawBackground[y+1][x] == 0) {
            y ++;
          } else {
            nocollide = false;
          }
        } else if (keyCode == UP) {
          //rotate 
          if (ScreenDrawBackground[y][x-1] == 0 && ScreenDrawBackground[y][x+1] == 0 && ScreenDrawBackground[y+1][x] == 0) {
            rot ++;
          }
        }
        delay(1000);
        ScreenDrawPlayerBlock[i][0]++;
      } //If a collision occurs
        if (nocollide == false) {
          //code for collision goes here. 
          //Essentially, the block is added to ScreenDrawBackground, like this:
          arrayCopy(ScreenDrawPlayerBlock, ScreenDrawBackground);
          //Then, ScreenDrawPlayerBlock is set to 0s.
          for (int i = 0; i < ScreenDrawPlayerBlock.length; i++) {
            ScreenDrawBackground[i][i] = 0;
          } //At this point, a new block is drawn on top of the screen.
           // Put New Block thing here
        }
      }
     //for rotation
    

    I guess I need at this point to figure out downwards collisions/preventing an out-of-bounds error, but also how to transfer the 'nocollide' to things outside the method, as well as figuring out how to only prevent movement rather than stopping the block. Does anyone have any suggestions for this?

  • edited July 2014

    Alright, I've gotten some real life help to create what is pretty much an almost-completed Game & Collision system.

    It's coded in Java, so it wasn't much work to convert it to processing.

    However, If I wanted to put this into the game itself, what would I do? As in, how would I fit this into the void setup/game as well as displaying the 2-d array? Each block is supposed to be 35 pixels wide.

    public boolean endGame = false;
    
    public static void main(argc, argv[]) {    <<<<------- Left in for accuracy stuff.
      //setup
      int score = 0;
      int board [][] = new int [24][12];
      boolean filled = false;
      int randNum;
    
      for (int i = 0; i < board.height(); i++) { //Sets the left side of the board to a value of 2, and the right side to a value of 3
        board[i][0] = 2;
        board[i][board.length()-1] = 3;
      }
    
      for (int i = 0; i < board.length(); i++) { //Sets the bottom of the board to a value of 4
        board[board.height()-1][i] = 4;
      }
    
      while (filled == false) {
        //Checking if the top of the board is being touched
        for (int i = 1; i < board.length()-1; i++) {
          if (board[1][i] != 0){
            filled = true;
            break;
          }
        }
    
        randNum = Math.random()*10;
    
        int[][] currBlock = createBlock(randNum);
    
        playGame(board, currBlock);
    
      }
    
    }
    
    int[][] createBlock(int randNum, int[][] board) {
      //Create the block;
    
      /*
      * No matter what type of block is created, we want to spawn the block at the the top of the board
      * So, we simply set the area where the block is being spawned on the board to 1s
      * If there already exists a 1 where the block is being spawned, we know then that the created block will 
        cause the pieces to touch the top
      * Therefore 
      */
    
      //Say we want to spawn a square on the board
    
      if (randNum == 1) {  //This will create a 'block shape' at the top of the board which will be manipulated in playGame()
        if (board[0][3] == 1 ||  //This will check if a block already exists where the new block is being spawned
            board[0][4] == 1 ||  //If a block already exists then end game
            board[0][5] == 1 ||
            board[0][6] == 1) {
          endGame = true;
        }
        board[0][3] = 1; //line
        board[0][4] = 1;
        board[0][5] = 1;
        board[0][6] = 1;
      }
    
      if (randNum == 2) {  
        if (board[0][5] == 1 ||  
            board[1][5] == 1 ||
            board[0][6] == 1 ||
            board[1][6] == 1) {
          endGame = true;
        }
        board[0][5] = 1; //square
        board[1][5] = 1;
        board[0][6] = 1;
        board[1][6] = 1;
      }
    
    if (randNum == 3) {  
        if (board[0][3] == 1 ||  
            board[0][4] == 1 ||
            board[1][4] == 1 ||
            board[1][5] == 1) {
          endGame = true;
        }
        board[0][3] = 1; //Z 
        board[0][4] = 1;
        board[1][4] = 1;
        board[1][5] = 1;
      }
    
      if (randNum == 4) {  
        if (board[0][3] == 1 ||  
            board[0][4] == 1 ||
            board[0][5] == 1 ||
            board[1][4] == 1) {
          endGame = true;
        }
        board[0][3] = 1;//T
        board[0][4] = 1;
        board[0][5] = 1;
        board[1][4] = 1;
      }
    
      if (randNum == 5) {  
        if (board[0][4] == 1 ||  
            board[1][4] == 1 ||
            board[2][4] == 1 ||
            board[3][5] == 1) {
          endGame = true;
        }
        board[0][4] = 1;//L
        board[1][4] = 1;
        board[2][4] = 1;
        board[3][5] = 1;
      }
      else{}
    
      return board;
    }
    
    public void playGame(board, block) {
      boolean canLeft = true; 
      boolean canRight = true;
      boolean bottom = false;
    
      while (bottom == false) {
    
        //Collision detection
        for (int i = 0; i < 24-1; i++) {
          if (board[i][1] == 1) {
            canLeft = false;
          }
    
          if (board[i][board.length()-2] == 1) {
            canRight = false;
          }
        }
    
        for (int i = 1; i < board.length()-2; i++) {
          if (board[24-2][i] == 1) {
            bottom = true;
          }
        }
    
        //Player controls
    
        if (keyPressed && (key == CODED)) {
        //Left
          if (keyCode == LEFT) {
            if (canLeft = true) {
              for (int i = 0; i < 10; i++) {
                if (i = 1) {
                  board[i][0]--;
                }
              }
             }
         } else if (keyCode == RIGHT) {
            if (canRight = true) {
            for (int i = 0; i < 10; i++) {
              if (i = 1) {
                board[i][0]++;
              }
            }
           }
         } else {}
    
        dropBlockByOne(board);
        playerControl(board);
    
        //If block is at the bottom, set it in stone
    
        if (bottom == true) {
          for (int i = 0; i < board.length(); i++) {
            for (int j = 0; j < board.height(); j++) {
              board[i][j] = 5;
            }
          }
    
          checkIfLineExists(board);
    
          return;
        }
      }
    }
    
    int[][] board(int[][] board) {
      for (int i = 0; i < board.length(); i++) {
        for (int j = 0; j < board.height(); j++) {
          if (board[i][j] == 1) {
            board[i+1][j] = 1;
            board[i][j] = 0;
          }
        }
      }
    
      return board;
    }
    
    int[][] checkIfLineExists(int[][] board) {
      //If the current line is entirely 1, then change to 0, copying every line above down 1, and set counter to 0
      //If counter is equal to the height of the board, then scan has finished, return the board as it stands
    
      int counter = 0;
      int y = 0;
    
      while (counter != board.height()) {
        int countLengthOfBoard = 0;
    
        for (int x = 1; x < board.length()-2; x++) {
          if (board[y][x] == 5) {
            countLengthOfBoard++;
          }
        }
    
        if (countLengthOfBoard == board.length()-1) {
          for (int x = 1; x < board.length()-2; x++) {
            board[y][x] = 0;
          }
          counter = 0;
          x = 0;
          y = 0;
        }
        else {
          x = 0;
          y++;
          counter++;
        }
      }
    }
    
  • edited July 2014

    I also plan on using this interface for the game, so here is that. Ignore terrible colours.

    picasion.com_8b6969c8744ef93c80c0fcbbb6bae36c

  • edited July 2014

    If you either store 0 or 1 into your 2D matrix array, declaring it as boolean instead would make it easier! ;)

    P.S.: public static void main(argc, argv[]) { seems a mix of C & Java code! :P

  • In your processing code it says in the 1st line collision of Blicks

    Do you mean bricks?

    Also it says SDD major works

    What does that mean? Please

  • edited July 2014

    I'd rather store it as an Integer.

    Blicks is the name of the game.

    SDD is Software Design Development, a school subject. This is a project for this. Yes, the help I have been getting from here is allowed since I haven't been able to ask anyone else for help in real life until now.

    So...I'm pretty sure I could do a For loop in which I find the numbers of the array and set various fills and rect()s, while I also set the background to the above image and having the score displayed as text. Is this the right method?

  • edited July 2014

    I'd rather store it as an Integer.

    At least lemme demonstrate why boolean[][] would be easier: O:-)

    if (board[i][j] == 1) would be just if (board[i][j]).
    if (board[i][j] == 0) would be just if (!board[i][j]).

    And invert the states would be board[i][j] ^= true;.
    Compare that to this 1 you'd have to use: board[i][j] = board[i][j] == 0? 1 : 0;.

    Now you can make a conscious choice between boolean[][] & int[][]! (*)

  • Oh right. I understand now. Unfortunately, I just realised that the boolean thing won't work because initially the sides and the bottom are set to different numbers (2 and 3 for the sides, 4 for the bottom, 5 for the settled blocks) so that it can prevent out-of-bounds errors (It can't accidentally delete the sides or bottom or top.)

    Regardless, do you think there is any way of doing collision with this system?

  • edited July 2014

    In a Tetris type game, collision is based on whether a tile is on or off! It's just 2 states!
    Outta-bounds is about any coordinates < 0 or >= length. No need for other states!

    Before each bottom tile of the piece descends 1 line, we gotta check whether the position right below it is turned off.
    Otherwise we gotta ourselves a collision. And the piece is finished and stays in place!

Sign In or Register to comment.