From: gumartinm Date: Fri, 18 Nov 2011 02:39:37 +0000 (+0100) Subject: Just rest to finish the score and levels. X-Git-Url: https://git.gumartinm.name/?a=commitdiff_plain;h=add31df585e851479580cb3bc83ed30caada989e;p=JavaForFun Just rest to finish the score and levels. Besides I want to improve the code and use java.concurrent --- diff --git a/AndroidTetris/src/de/android/androidtetris/CurrentPiece.java b/AndroidTetris/src/de/android/androidtetris/CurrentPiece.java new file mode 100644 index 0000000..11bbbd0 --- /dev/null +++ b/AndroidTetris/src/de/android/androidtetris/CurrentPiece.java @@ -0,0 +1,152 @@ +/** + * + */ +package de.android.androidtetris; + +import java.util.HashMap; +import java.util.Map; + +/** + * This enum stores every piece and the square related to that piece. + * + * @author gusarapo + * + */ +public enum CurrentPiece { + /*The tower piece*/ + I(0) { + @Override + void fill() { + size[1][0]=Tile.RED; + size[1][1]=Tile.RED; + size[1][2]=Tile.RED; + size[1][3]=Tile.RED; + } + }, + /*The box piece*/ + O(1) { + @Override + void fill() { + size[1][1]=Tile.BLUE; + size[1][2]=Tile.BLUE; + size[2][1]=Tile.BLUE; + size[2][2]=Tile.BLUE; + } + }, + /*The pyramid piece*/ + T(2) { + @Override + void fill() { + size[1][1]=Tile.YELLOW; + size[0][2]=Tile.YELLOW; + size[1][2]=Tile.YELLOW; + size[2][2]=Tile.YELLOW; + } + }, + /*The left leaner piece*/ + Z(3) { + @Override + void fill() { + size[0][1]=Tile.CYAN; + size[1][1]=Tile.CYAN; + size[1][2]=Tile.CYAN; + size[2][2]=Tile.CYAN; + } + }, + /*The right leaner piece*/ + S(4) { + @Override + void fill() { + size[2][1]=Tile.GREEN; + size[1][1]=Tile.GREEN; + size[1][2]=Tile.GREEN; + size[0][2]=Tile.GREEN; + } + }, + /*The left knight piece*/ + L(5) { + @Override + void fill() { + size[1][1]=Tile.MAGENTA; + size[2][1]=Tile.MAGENTA; + size[2][2]=Tile.MAGENTA; + size[2][3]=Tile.MAGENTA; + } + }, + /*The right knight piece*/ + J(6) { + @Override + void fill() { + size[2][1]=Tile.WHITE; + size[1][1]=Tile.WHITE; + size[1][2]=Tile.WHITE; + size[1][3]=Tile.WHITE; + } + }; + + + //Every piece is contained in a square. This is the square's width. + public static final int WIDTH = 4; + //Every piece is contained in a square. This is the square's height. + public static final int HEIGHT = 4; + //Stores the x coordinate (the position of this piece on the grid) + public int x; + //Stores the y coordinate (the position of this piece on the grid) + public int y; + //Every piece is contained in a square. + public final Tile[][] size = new Tile[WIDTH][HEIGHT]; + //Stores the argument of the enum constant (passed to the constructor) JLS§8.9.1 + public final int pieceNumber; + //Map with every enum constant. Class variable initializer. JLS§12.4.2 Executed in textual order. + private static final Map pieceMap = new HashMap(); + + + //Static initializer. JLS§12.4.2 Executed in textual order. + static { + for (CurrentPiece piece : CurrentPiece.values()) + { + pieceMap.put(piece.pieceNumber, piece); + } + } + + + /** + * Because we have enum constants with arguments we have to create this constructor. + * It initializes the piece with the right values. + * + * @param pieceNumber It is the argument of the enum constant + */ + private CurrentPiece (final int pieceNumber) + { + this.pieceNumber = pieceNumber; + + //Pre-Initialization of matrix size + for (int i=0; i< WIDTH; i++) + for (int j=0; j< HEIGHT; j++) + size[i][j]= Tile.NOCOLOR; + + this.x = 0; + this.y = 0; + //It depends on what kind of piece, we have to fill the square in the right way. + this.fill(); + } + + + /** + * This method is used to retrieve the enum piece related to its number + * + * @param pieceNumber The piece number is associated to the argument of the enum constant. + * @return the enum whose argument of the enum constant matches the pieceNumber. + */ + public static final CurrentPiece getPiece (final int pieceNumber) + { + return pieceMap.get(pieceNumber); + } + + + /** + * This method is intended to be overridden by every piece to fill the square which contains the piece's shape. + */ + abstract void fill(); + +} diff --git a/AndroidTetris/src/de/android/androidtetris/DrawView.java b/AndroidTetris/src/de/android/androidtetris/DrawView.java index 3817971..209072e 100644 --- a/AndroidTetris/src/de/android/androidtetris/DrawView.java +++ b/AndroidTetris/src/de/android/androidtetris/DrawView.java @@ -26,8 +26,8 @@ public class DrawView extends SurfaceView { private AndroidTetrisThread thread; private Bitmap[] tileArray; private Tile[][] mapMatrix; - private Piece prePiece; - private Piece currentPiece; + private PrePiece prePiece; + private CurrentPiece currentPiece; class AndroidTetrisThread extends Thread { @@ -91,12 +91,12 @@ public class DrawView extends SurfaceView { this.newGame(); - currentPiece = newBlock(); + currentPiece = newCurrentBlock(); currentPiece.x = MAPWIDTH/2-2; - currentPiece.y = -1; - prePiece = newBlock(); - prePiece.x=MAPWIDTH+2; - prePiece.y=GREY/4; + currentPiece.y = -1; + prePiece = newPreBlock(); + prePiece.x = MAPWIDTH+2; + prePiece.y = GREY/4; // register our interest in hearing about changes to our surface //SurfaceHolder holder = getHolder(); @@ -162,20 +162,26 @@ public class DrawView extends SurfaceView { //start out the map for(int x=0;x< MAPWIDTH;x++) { - for(int y=0;y< MAPHEIGHT+1;y++) + for(int y=0; y<= MAPHEIGHT;y++) { mapMatrix[x][y]=Tile.BLACK; } } } - protected Piece newBlock() + private CurrentPiece newCurrentBlock() { Random random = new Random(); - - Piece piece = Piece.getPiece(random.nextInt(7)%7); - return piece; + return CurrentPiece.getPiece(random.nextInt(7)%7); + } + + + private PrePiece newPreBlock() + { + Random random = new Random(); + + return PrePiece.getPiece(random.nextInt(7)%7); } protected void drawTile(Canvas canvas, int color, int x, int y) @@ -193,21 +199,21 @@ public class DrawView extends SurfaceView { drawTile(canvas, Tile.GRAY.getColor(), x, y); //draw the pre-piece - for(int x=0; x<4; x++) - for(int y=0; y<4; y++) + for(int x=0; x < PrePiece.WIDTH; x++) + for(int y=0; y< PrePiece.HEIGHT; y++) if(prePiece.size[x][y] != Tile.NOCOLOR) - drawTile(canvas, prePiece.size[x][y].getColor(), prePiece.x+x, prePiece.y +y); + drawTile(canvas, prePiece.size[x][y].getColor(), prePiece.x + x, prePiece.y +y); //draw grid - for(int x=0; x< MAPWIDTH; x++) - for(int y=0; y< MAPHEIGHT; y++) + for(int x=0; x < MAPWIDTH; x++) + for(int y=0; y < MAPHEIGHT; y++) drawTile(canvas, mapMatrix[x][y].getColor(), x, y); //draw the current block - for(int x=0; x<4; x++) - for(int y=0; y<4; y++) + for(int x=0; x < CurrentPiece.WIDTH; x++) + for(int y=0; y < CurrentPiece.HEIGHT; y++) if(currentPiece.size[x][y] != Tile.NOCOLOR) - drawTile(canvas, currentPiece.size[x][y].getColor(), currentPiece.x+x, currentPiece.y +y); + drawTile(canvas, currentPiece.size[x][y].getColor(), currentPiece.x + x, currentPiece.y +y); } protected void move (int x, int y) @@ -216,12 +222,54 @@ public class DrawView extends SurfaceView { { if (y == 1) { - currentPiece = prePiece; - currentPiece.x = MAPWIDTH/2-2; - currentPiece.y = -1; - prePiece = newBlock(); - prePiece.x=MAPWIDTH+2; - prePiece.y=GREY/4; + if (currentPiece.y == -1) + { + //GAMEOVER + //start out the map + for(int xx=0;xx< MAPWIDTH;xx++) + { + for(int yy=0; yy<= MAPHEIGHT;yy++) + { + mapMatrix[xx][yy]=Tile.BLACK; + } + } + currentPiece = newCurrentBlock(); + currentPiece.x = MAPWIDTH/2-2; + currentPiece.y = -1; + prePiece = newPreBlock(); + prePiece.x = MAPWIDTH+2; + prePiece.y = GREY/4; + } + else + { + //Add block to Grid + for(int i=0; i0; y--) + mapMatrix[x][y]=mapMatrix[x][y-1]; + } + + + private boolean collisionTest(int cx, int cy) { int newx = currentPiece.x + cx; int newy = currentPiece.y + cy; //Check grid boundaries - for(int x=0; x<4; x++) - for(int y=0; y<4; y++) + for(int x=0; x= MAPHEIGHT) || (newy + y < 0) || (newx + x >= MAPWIDTH) || (newx + x < 0)) return true; //Check collisions with other blocks for(int x=0; x< MAPWIDTH; x++) for(int y=0; y< MAPHEIGHT; y++) - if(x >= newx && x < newx + 4) - if(y >= newy && y < newy +4) + if(x >= newx && x < newx + CurrentPiece.WIDTH) + if(y >= newy && y < newy + CurrentPiece.HEIGHT) if(mapMatrix[x][y] != Tile.BLACK) if(currentPiece.size[x - newx][y - newy] != Tile.NOCOLOR) return true; return false; } + /** + * TODO: reuse the collisionTest method for this one (the are the same thing with just a few changes) + * Sorry I am too tired to rewrite the methods right now. + */ + private void rotateBlock() { + Tile[][] temporal = new Tile[CurrentPiece.WIDTH][CurrentPiece.HEIGHT]; + + //Copy and rotate current piece to the temporary array + for(int x=0; x= MAPHEIGHT) || (currentPiece.y + y < 0) || + (currentPiece.x + x >= MAPWIDTH) || (currentPiece.x + x < 0)) + return; + + //Check collisions with other blocks + for(int x=0; x< MAPWIDTH; x++) + for(int y=0; y< MAPHEIGHT; y++) + if(x >= currentPiece.x && x < currentPiece.x + CurrentPiece.WIDTH) + if(y >= currentPiece.y && y < currentPiece.y + CurrentPiece.HEIGHT) + if(mapMatrix[x][y] != Tile.BLACK) + if(temporal[x - currentPiece.x][y - currentPiece.y] != Tile.NOCOLOR) + return; + + //Rotate is allowed + for(int x=0; x pieceMap = new HashMap(); - - - //Static initializer. JLS§12.4.2 Executed in textual order. - static { - for (Piece piece : Piece.values()) - { - pieceMap.put(piece.pieceNumber, piece); - } - } - - - /** - * Because we have enum constants with arguments we have to create this constructor. - * It initializes the piece with the right values. - * - * @param pieceNumber It is the argument of the enum constant - */ - private Piece (final int pieceNumber) - { - this.pieceNumber = pieceNumber; - - //Pre-Initialization of matrix size - for (int i=0; i< WIDTH; i++) - for (int j=0; j< HEIGHT; j++) - size[i][j]= Tile.NOCOLOR; - - //It depends on what kind of piece, we have to fill the square in the right way. - this.fill(); - } - - - /** - * This method is used to retrieve the enum piece related to its number - * - * @param pieceNumber The piece number is associated to the argument of the enum constant. - * @return the enum whose argument of the enum constant matches the pieceNumber. - */ - public static final Piece getPiece (final int pieceNumber) - { - return pieceMap.get(pieceNumber); - } - - - /** - * This method is intended to be overridden by every piece to fill the square which contains the piece's shape. - */ - abstract void fill(); - -} diff --git a/AndroidTetris/src/de/android/androidtetris/PrePiece.java b/AndroidTetris/src/de/android/androidtetris/PrePiece.java new file mode 100644 index 0000000..da3dbe0 --- /dev/null +++ b/AndroidTetris/src/de/android/androidtetris/PrePiece.java @@ -0,0 +1,152 @@ +/** + * + */ +package de.android.androidtetris; + +import java.util.HashMap; +import java.util.Map; + +/** + * This enum stores every piece and the square related to that piece. + * + * @author gusarapo + * + */ +public enum PrePiece { + /*The tower piece*/ + I(0) { + @Override + void fill() { + size[1][0]=Tile.RED; + size[1][1]=Tile.RED; + size[1][2]=Tile.RED; + size[1][3]=Tile.RED; + } + }, + /*The box piece*/ + O(1) { + @Override + void fill() { + size[1][1]=Tile.BLUE; + size[1][2]=Tile.BLUE; + size[2][1]=Tile.BLUE; + size[2][2]=Tile.BLUE; + } + }, + /*The pyramid piece*/ + T(2) { + @Override + void fill() { + size[1][1]=Tile.YELLOW; + size[0][2]=Tile.YELLOW; + size[1][2]=Tile.YELLOW; + size[2][2]=Tile.YELLOW; + } + }, + /*The left leaner piece*/ + Z(3) { + @Override + void fill() { + size[0][1]=Tile.CYAN; + size[1][1]=Tile.CYAN; + size[1][2]=Tile.CYAN; + size[2][2]=Tile.CYAN; + } + }, + /*The right leaner piece*/ + S(4) { + @Override + void fill() { + size[2][1]=Tile.GREEN; + size[1][1]=Tile.GREEN; + size[1][2]=Tile.GREEN; + size[0][2]=Tile.GREEN; + } + }, + /*The left knight piece*/ + L(5) { + @Override + void fill() { + size[1][1]=Tile.MAGENTA; + size[2][1]=Tile.MAGENTA; + size[2][2]=Tile.MAGENTA; + size[2][3]=Tile.MAGENTA; + } + }, + /*The right knight piece*/ + J(6) { + @Override + void fill() { + size[2][1]=Tile.WHITE; + size[1][1]=Tile.WHITE; + size[1][2]=Tile.WHITE; + size[1][3]=Tile.WHITE; + } + }; + + + //Every piece is contained in a square. This is the square's width. + public static final int WIDTH = 4; + //Every piece is contained in a square. This is the square's height. + public static final int HEIGHT = 4; + //Stores the x coordinate (the position of this piece on the grid) + public int x; + //Stores the y coordinate (the position of this piece on the grid) + public int y; + //Every piece is contained in a square. + public final Tile[][] size = new Tile[WIDTH][HEIGHT]; + //Stores the argument of the enum constant (passed to the constructor) JLS§8.9.1 + public final int pieceNumber; + //Map with every enum constant. Class variable initializer. JLS§12.4.2 Executed in textual order. + private static final Map pieceMap = new HashMap(); + + + //Static initializer. JLS§12.4.2 Executed in textual order. + static { + for (PrePiece piece : PrePiece.values()) + { + pieceMap.put(piece.pieceNumber, piece); + } + } + + + /** + * Because we have enum constants with arguments we have to create this constructor. + * It initializes the piece with the right values. + * + * @param pieceNumber It is the argument of the enum constant + */ + private PrePiece (final int pieceNumber) + { + this.pieceNumber = pieceNumber; + + //Pre-Initialization of matrix size + for (int i=0; i< WIDTH; i++) + for (int j=0; j< HEIGHT; j++) + size[i][j]= Tile.NOCOLOR; + + this.x = 0; + this.y = 0; + //It depends on what kind of piece, we have to fill the square in the right way. + this.fill(); + } + + + /** + * This method is used to retrieve the enum piece related to its number + * + * @param pieceNumber The piece number is associated to the argument of the enum constant. + * @return the enum whose argument of the enum constant matches the pieceNumber. + */ + public static final PrePiece getPiece (final int pieceNumber) + { + return pieceMap.get(pieceNumber); + } + + + /** + * This method is intended to be overridden by every piece to fill the square which contains the piece's shape. + */ + abstract void fill(); + +}