Cintillo Institucional

Página en revisión

Código en Processing, tomado de: http://www.danepieri.com/tetris_play.html

// Controls:
// Arrow keys for left, right, down, rotate
// Spacebar to drop piece


//import processing.opengl.*;
PFont Hira;



Board myBoard;
Board.BoardBlock[][] myBoardBlock;
fallingPiece myPiece;
int numRows = 15;
int numCol = 10;
int brickSize = 25;
int offset = 20;
int numRowsCleared;
boolean gameIsOver = false;

void setup(){
  size(440,415);
  stroke(100);

  Hira = loadFont("Ziggurat.vlw");
  myBoard = new Board();
  myBoardBlock = new Board.BoardBlock[10][15];
    
    for (int i=0; i<numCol; i++){
    for (int j=0; j<numRows; j++){
      myBoardBlock[i][j] = myBoard.new BoardBlock(i,j);
    }
  }
  
  myPiece = new fallingPiece((int)random(6.99999));
}


void draw(){
  background(200);
  myBoard.renderBoard();
  myBoard.clearFullRows();
  myBoard.displayScore();
  myBoard.displayGameOver();
  myPiece.animate();
}





// ======= Falling Piece Class ===============
// ===========================================
class fallingPiece{
  int pieceUsed;
  int posCreating;
  color pieceCol;
  int[][] brickPos = new int[4][2]; // [0]=x  [1]=y 
  
  // These boolean arrays are used to create the pieces
  // however after that a piece is just a set of 4 x and y values
  // so really it is four pieces. 

  boolean[][] I_PIECE = {
    { true,  true,  true,  true   }
  };

  boolean[][] J_PIECE = {
    { true, false, false  } ,
    {  true, true,  true    } 
  };

  boolean[][] L_PIECE = {
    {  false, false, true      },
    {  true,  true,  true  }
  };

  boolean[][] O_PIECE = {
    { true, true  },
    { true, true }
  };

  boolean[][] S_PIECE = {
    { false, true, true },
    { true,  true, false    }
  };

  boolean[][] T_PIECE = {
    { false, true, false   },
    {  true,  true, true  }
  };

  boolean[][] Z_PIECE = {
    {  true,  true, false   } ,
    {  false, true, true   }
  };

  color[] pieceColors = {
    color(0,240,240),color(0,0,240), color(240,160,0), 
    color(240,240,0), color(0,240,0), color(160,0,240), color(240,0,0)                                      };

  boolean[][][] allPieces = {
    I_PIECE, J_PIECE, L_PIECE, O_PIECE, S_PIECE, T_PIECE, Z_PIECE
  };

    // Pieces are rotated according to their relationship to the center brick
  int[] centerPiece = {
    1, 2, 1, 1, 2, 2, 2                                      };

  // Constructor
  fallingPiece(int pieceUsed){  
    int[][] brickPosTemp = new int[4][2];
    this.pieceUsed = pieceUsed;
    pieceCol = pieceColors[pieceUsed];

    for (int j=0; j<allPieces[pieceUsed][0].length; j++){
      for (int i=0; i<allPieces[pieceUsed].length; i++){

        if(allPieces[pieceUsed][i][j]){
          brickPosTemp[posCreating%4][0] = (numCol/2)-1 + i;
          brickPosTemp[posCreating%4][1] =  j;
          if (myBoardBlock[brickPosTemp[posCreating%4][0]][brickPosTemp[posCreating%4][1]].isTaken() == true){
            myBoard.gameOver();
            break;
          }
          posCreating ++;
        }
      }
      if (gameIsOver == true){
        break;
      }
    }
    if (gameIsOver == false){
      for (int i=0; i<brickPos.length; i++){
        brickPos[i][0] = brickPosTemp[i][0];
        brickPos[i][1] = brickPosTemp[i][1];
      }
    }
  }



  // Functions
  void render(){
    strokeWeight(1);


    for (int i=0; i<brickPos.length; i++){
      fill(pieceCol);
      rect(
      brickPos[i][0]*brickSize+offset, 
      brickPos[i][1]*brickSize+offset, 
      brickSize,brickSize);
    } 
  } 

  void animate(){
    if(gameIsOver == false){
      if(frameCount%(max(10,(25-numRowsCleared))) == 0 && this.canItMove()){
        this.moveY();
      }
      if(keyPressed){
        if (key == CODED){
          if(keyCode == RIGHT && this.canItMoveR()){
            this.moveRight();
            keyPressed = false;
          }
          else if(keyCode == LEFT && this.canItMoveL()){
            this.moveLeft();
            keyPressed = false;
          }
          else if(keyCode == DOWN && this.canItMove()){
            this.moveY();
            keyPressed = false;
          }
          else if(keyCode == UP){
            this.rotate();
            keyPressed = false;
          }
        }
        else if(key == ' '){
          while (myPiece.canItMove()){
            this.moveY();
          }
          keyPressed = false;
        }
      }
      this.render();
    }
  }


  void moveY(){
    for (int i=0; i<brickPos.length; i++){
      brickPos[i][1] ++; 
    }
  }

  void moveRight(){
    for (int i=0; i<brickPos.length; i++){
      brickPos[i][0] ++; 
    }
  }


  void moveLeft(){
    for (int i=0; i<brickPos.length; i++){
      brickPos[i][0] --; 
    }
  }


  boolean canItMove(){
    for (int i=0; i<brickPos.length; i++){

      if(brickPos[i][1] == numRows-1){
        this.freezeBlock();
        return false;
      }
      if(myBoardBlock[brickPos[i][0]][brickPos[i][1]+1].isTaken() == true){
        this.freezeBlock();
        return false;
      } 
    }
    return true;
  }


  boolean canItMoveL(){
    for (int i=0; i<brickPos.length; i++){
      if(brickPos[i][0] == 0){
        return false;
      }
      if(myBoardBlock[brickPos[i][0]-1][brickPos[i][1]].isTaken() == true){
        return false;
      } 
    }
    return true;
  }


  boolean canItMoveR(){
    for (int i=0; i<brickPos.length; i++){
      if(brickPos[i][0] == numCol-1){
        return false;
      }
      if(myBoardBlock[brickPos[i][0]+1][brickPos[i][1]].isTaken() == true){
        return false;
      } 
    }
    return true;
  }


  boolean canItRotate(int x, int y){
    if (x > numCol-1
      || x < -1
      || y > numRows-1
      || myBoardBlock[x][y].isTaken() == true 
      ){
      return false;
    }
    return true;
  }


  void freezeBlock(){
    for (int i=0; i<brickPos.length; i++){
      myBoardBlock[brickPos[i][0]][brickPos[i][1]].take();
      myBoardBlock[brickPos[i][0]][brickPos[i][1]].col = pieceColors[pieceUsed];
    }
    myPiece = new fallingPiece((int)random(6.9999));
  }


  void rotate(){
    int[][] brickPosTemp = new int[4][2];
    boolean isItGoingToRotate = true;

    for (int i=0; i<brickPos.length; i++){
      if( i != centerPiece[pieceUsed] && pieceUsed != 3){
        int xDifference;
        int yDifference;
        int temp;

        xDifference = brickPos[i][0] - brickPos[centerPiece[pieceUsed]][0];
        yDifference = brickPos[i][1] - brickPos[centerPiece[pieceUsed]][1];

        xDifference *= -1;
        
        // rotate and check if new position is taken
        brickPosTemp[i][1] = brickPos[centerPiece[pieceUsed]][1] + xDifference;
        brickPosTemp[i][0] = brickPos[centerPiece[pieceUsed]][0] + yDifference;  
        if(canItRotate(brickPosTemp[i][0], brickPosTemp[i][1]) == false){
          isItGoingToRotate = false;
          break;
        }   
      }
    }
    
    // Actually rotate
    if (isItGoingToRotate == true){
      for (int i=0; i<brickPos.length; i++){
        if( i != centerPiece[pieceUsed] && pieceUsed != 3){
          brickPos[i][1] = brickPosTemp[i][1];
          brickPos[i][0] = brickPosTemp[i][0];
        }
      }
    }
    isItGoingToRotate = true;
  }


} 







// ============== Board Class ================
// ===========================================
public class Board{
  int score = 0;

  // constructor
  Board(){
  
  }

  void clearFullRows(){
    int numFullRows = 0;
    for (int i=0; i<numRows; i++){
      if(myBoardBlock[0][i].isTaken() == true && myBoardBlock[1][i].isTaken() == true && myBoardBlock[2][i].isTaken() == true 
        && myBoardBlock[3][i].isTaken() == true && myBoardBlock[4][i].isTaken() == true && myBoardBlock[5][i].isTaken() == true 
        && myBoardBlock[6][i].isTaken() == true && myBoardBlock[7][i].isTaken() == true && myBoardBlock[8][i].isTaken() == true 
        && myBoardBlock[9][i].isTaken() == true)  {
        numFullRows ++;
        //println("full" + numFullRows);
        for (int j=0; j<numCol; j++){
          myBoardBlock[j][i].take();

          for (int k = i; k>0; k--){
            myBoardBlock[j][k].taken = myBoardBlock[j][k-1].taken;
            myBoardBlock[j][k].col = myBoardBlock[j][k-1].col;
          }
        }
      }
    }
    if (numFullRows == 4){
      score += 800;      // Tetris!!
    }
    else if(numFullRows > 0){
      score = score + (numFullRows * 100);
      numRowsCleared += numFullRows;
    }
    numFullRows = 0;
  }


  void renderBoard(){    
    for (int i=0; i<10; i++){
      for (int j=0; j<15; j++){
        myBoardBlock[i][j].render();
      }
    } 
    noFill();
    strokeWeight(1);
    rect(offset,offset, brickSize*numCol, brickSize*numRows);
  }


  void gameOver(){
    gameIsOver = true;
   // println("Game Over");
  }


  void newGame(){
    score = 0;
    gameIsOver = false;
    for (int i=0; i<numCol; i++){
      for (int j=0; j<numRows; j++){
        myBoardBlock[i][j].taken = false;
        myBoardBlock[i][j].col = color(150,150,230);
      }
    }
    myPiece = new fallingPiece((int)random(6.9999));
    //println("New Game");
  }

  void displayScore(){
    textFont(Hira,25);
    strokeWeight(1);
    fill(255);
    text("Score:", width-120,70); 
    rect(width-130,85, 100,30);
    fill(150);
    text(score, width-125,110);
  }


  void displayGameOver(){
    if (gameIsOver == true){
      int bX = 70;
      int bY = 125;
      int bWidth = 140;
      int bHeight = 32;

      fill(220,100);
      rect(offset,offset, brickSize*numCol, brickSize*numRows);
      textFont(Hira,25);
      strokeWeight(1);
      fill(255);
      text("Game Over!", 70,70);

      noStroke();
      fill(20,30,200);
      rect(bX,bY, bWidth,bHeight);
      fill(255,200);
      text("New Game", 75,150);
      stroke(100);

      // Click for new game
      if(mouseX > bX && mouseX < bX + bWidth && 
        mouseY > bY && mouseX < bY + bHeight){
        if(mousePressed){
          myBoard.newGame();
        }
      }
    }
  }


  // ============ Board Block sub class ===============
  public class BoardBlock extends Board{
    color col;
    int x;
    int y;
    boolean taken;

    // Constructor
    BoardBlock(int x, int y){
      col = color(150,150,230);
      this.x = offset+ x*25;
      this.y = offset+ y*25;
      this.taken = false;
    }

    // Accessor 
    
    boolean isTaken(){
     return taken; 
    }
    
    // Setter
    
    void take(){
      this.taken = true;
    }
    
    
    void render(){
      fill(col);
      if(taken){
        strokeWeight(1);
      }
      else{
        strokeWeight(1);
      }
      rect(x,y, brickSize,brickSize);
    }
  }
}

hlpd/curso_arduino/uni00303/tetris (última edición 2011-05-30 21:20:30 efectuada por _desactivada_csoto)