4
\$\begingroup\$

recently i have finished my first bigger Android project. I made a little Tetris App. enter image description here

Here is a picture of my app in emulator: My Tetris has following functions: 1. fast drop down 2. play tetris music 3. start/pause button 4. Gameover Screen 5. View which shows next Piece 6 "Levels" if you reach a particular score, level will be increase and pieces drops faster down 7. saving and loading highscore

I post the most important part of my code, if you need more code please see my git repo(https://github.com/Linus1905/Android-Tetris).

Piece.java:

public class Piece {

public int colorCode;
public int x1, y1;
public int x2, y2;
public int x3, y3;
public int x4, y4;
private Piece piece;

/*
creates a copy Instances of Piece
*/

  public Piece(Piece piece) {
  this.piece = piece;
  this.x1= piece.x1; this.x2= piece.x2;
  this.x3= piece.x3; this.x4= piece.x4;
  this.y1= piece.y1; this.y2= piece.y2;
  this.y3= piece.y3; this.y4= piece.y4;
 }
  /*
  creates a Piece depending on colorCode
  */
  public Piece(int f) {
    switch (f) { // Square
        case 1:
            x1 = 0; y1 = 7;
            x2 = 0; y2 = 8;
            x3 = 1; y3 = 7;
            x4 = 1; y4 = 8;

            colorCode = 1;
            break;

        case 2:    // z Piece
            x1 = 0;y1 = 7;
            x2 = 0;y2 = 8;
            x3 = 1;y3 = 8;
            x4 = 1;y4 = 9;

            colorCode = 2;
            break;

        case 3: // I Piece
            x1 = 0;y1 = 6;
            x2 = 0;y2 = 7;
            x3 = 0;y3 = 8;
            x4 = 0;y4 = 9;

            colorCode = 3;
            break;

        case 4: // T Piece
            x1 = 0;y1 = 8;
            x2 = 1;y2 = 7;
            x3 = 1;y3 = 8;
            x4 = 1;y4 = 9;

            colorCode = 4;
            break;

        case 5: // S Piece
            x1 = 0;y1 = 7;
            x2 = 0;y2 = 8;
            x3 = 1;y3 = 6;
            x4 = 1;y4 = 7;

            colorCode = 5;
            break;

        case 6:  // J Piece
            x1 = 0;y1 = 7;
            x2 = 0;y2 = 8;
            x3 = 0;y3 = 9;
            x4 = 1;y4 = 9;

            colorCode = 6;
            break;

        case 7:  //  L Piece
            x1 = 0;y1 = 7;
            x2 = 0;y2 = 8;
            x3 = 0;y3 = 9;
            x4 = 1;y4 = 7;

            colorCode = 7;
            break;
    }
}

public void move(int x, int y) {
    x1 = x1 + x;
    y1 = y1 + y;
    x2 = x2 + x;
    y2 = y2 + y;
    x3 = x3 + x;
    y3 = y3 + y;
    x4 = x4 + x;
    y4 = y4 + y;
}

 /*
 turns piece around x1|y1 coordinates
 */
public void turnPiece() {
    int tmp_x1, tmp_y1;
    int tmp_x2, tmp_y2;
    int tmp_x3, tmp_y3;

    tmp_x1 = turn_AroundX1(y2);
    tmp_y1 = turn_AroundY1(x2);
    x2 = tmp_x1;
    y2 = tmp_y1;

    tmp_x2 = turn_AroundX1(y3);
    tmp_y2 = turn_AroundY1(x3);
    x3 = tmp_x2;
    y3 = tmp_y2;

    tmp_x3 = turn_AroundX1(y4);
    tmp_y3 = turn_AroundY1(x4);
    x4 = tmp_x3;
    y4 = tmp_y3;
}

public int turn_AroundX1(int y) {
    return x1 + y - y1;
}

public int turn_AroundY1(int x) {
    return y1 - x + x1;
}

public int getMinXCoordinate(int x1, int x2, int x3, int x4) {
    return Math.min(Math.min(x1,x2),Math.min(x3,x4));
 }
}

GameBoard.java :

import android.graphics.Color;
import android.graphics.Point;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Random;

public class GameBoard {

 private final int boardHeight =30;
 private final int boardWidth=16;
 private int gameBoard[][]=new int[boardHeight][boardWidth];
 private final Random random = new Random();
 private ArrayList<Piece> pieceList = new ArrayList<Piece>();
 private  final int number_of_Pieces = 7;

public GameBoard() {
    pieceList.add(new Piece(random.nextInt(number_of_Pieces)+1));
    pieceList.add(new Piece(random.nextInt(number_of_Pieces)+1));
 }

/*
returns Color of x,y gameBoard cell
 */

 public int codeToColor(int x, int y) {

     if(gameBoard[x][y]==0) return Color.parseColor("#FFFF00");  // Yellow
     if(gameBoard[x][y]==1) return Color.parseColor("#00FF00"); ; // Square Green
     if(gameBoard[x][y]==2) return Color.parseColor("#FF00FF"); ; //  zpiece Magenta
     if(gameBoard[x][y]==3) return Color.parseColor("#0000FF"); ;  // ipiece Blue
     if(gameBoard[x][y]==4) return Color.parseColor("#00FFFF"); ;  // tpiece Cyan
     if(gameBoard[x][y]==5) return Color.parseColor("#ffbf00"); ;  // spiece Orange
     if(gameBoard[x][y]==6) return Color.parseColor("#BEBEBE"); ;  // jpiece gray
     if(gameBoard[x][y]==7) return Color.parseColor("#FF0000"); ; // lpiece Red

     return -1;
 }

public void clearGameBoard() {
    for(int i=0; i<boardHeight; i++) {
        for(int j=0; j<boardWidth; j++) {
            gameBoard[i][j]= 0;
        }
    }
}

public  ArrayList<Piece> getPieceList(){
    return pieceList;
}

public Piece getCurrentPiece()  {
          return pieceList.get(pieceList.size() - 2);
 }

public Piece getNextPiece() {
     return pieceList.get(pieceList.size()-1);
}

 private void placePiece(Piece currentPiece) {
     gameBoard[currentPiece.x1][currentPiece.y1] = currentPiece.colorCode;
     gameBoard[currentPiece.x2][currentPiece.y2] = currentPiece.colorCode;
     gameBoard[currentPiece.x3][currentPiece.y3] = currentPiece.colorCode;
     gameBoard[currentPiece.x4][currentPiece.y4] = currentPiece.colorCode;
}

private void deletePiece(Piece currentPiece) {
    gameBoard[currentPiece.x1][currentPiece.y1] = 0;
    gameBoard[currentPiece.x2][currentPiece.y2] = 0;
    gameBoard[currentPiece.x3][currentPiece.y3] = 0;
    gameBoard[currentPiece.x4][currentPiece.y4] = 0;
}

/*
checks if Piece can move in direction x|y
copy Piece and try to move it, return true
if it can move
 */

private boolean piece_Can_Move(Piece currentPiece, int x, int y) {
    int tmp =0;
    /*
    copy piece coordinates
     */
    Point p1 = new Point(currentPiece.x1, currentPiece.y1);
    Point p2 = new Point(currentPiece.x2, currentPiece.y2);
    Point p3 = new Point(currentPiece.x3, currentPiece.y3);
    Point p4 = new Point(currentPiece.x4, currentPiece.y4);

    Point tmp1 = new Point(currentPiece.x1+x, currentPiece.y1+y);
    Point tmp2 = new Point(currentPiece.x2+x, currentPiece.y2+y);
    Point tmp3 = new Point(currentPiece.x3+x, currentPiece.y3+y);
    Point tmp4 = new Point(currentPiece.x4+x, currentPiece.y4+y);

    ArrayList<Point> tmpPieceCoordinates = new ArrayList<Point>();

    tmpPieceCoordinates.add(tmp1);
    tmpPieceCoordinates.add(tmp2);
    tmpPieceCoordinates.add(tmp3);
    tmpPieceCoordinates.add(tmp4);


    for(Point p : tmpPieceCoordinates ) {

        if(p.x< boardHeight && p.y>=0 && p.y< boardWidth && gameBoard[p.x][p.y]==0) {
            tmp++;
        }

        else if(p.equals(p1) || p.equals(p2) || p.equals(p3) || p.equals(p4)) {
            tmp++;
        }
    }

    if(tmp==4) {
        return true;
    }
    return false;
}

 /*
 copy current Piece and check if it can rotate
 if true return true
  */

private boolean piece_Can_Rotate(Piece currentPiece) {
    int tmp =0;
    ArrayList<Point> tmpPieceCoordinates = new ArrayList<Point>();

    Piece tmpStein = new Piece(currentPiece);

    Point p1 = new Point(currentPiece.x1, currentPiece.y1);
    Point p2 = new Point(currentPiece.x2, currentPiece.y2);
    Point p3 = new Point(currentPiece.x3, currentPiece.y3);
    Point p4 = new Point(currentPiece.x4, currentPiece.y4);

    tmpStein.turnPiece();

    Point tmp1 = new Point(tmpStein.x1, tmpStein.y1);
    Point tmp2 = new Point(tmpStein.x2, tmpStein.y2);
    Point tmp3 = new Point(tmpStein.x3, tmpStein.y3);
    Point tmp4 = new Point(tmpStein.x4, tmpStein.y4);

    tmpPieceCoordinates .add(tmp1);
    tmpPieceCoordinates .add(tmp2);
    tmpPieceCoordinates .add(tmp3);
    tmpPieceCoordinates .add(tmp4);

    for(Point p : tmpPieceCoordinates  ) {

        if(p.x< boardHeight && p.x>=0 && p.y>=0 && p.y< boardWidth && gameBoard[p.x][p.y]==0) {
            tmp++;
        }

        else if(p.equals(p1) || p.equals(p2) || p.equals(p3) || p.equals(p4)) {
            tmp++;
        }
    }

    if(tmp==4) {  /* all four little squares are correct*/
        return true;
    }
    return false;
}

private  boolean can_Move_Left(Piece currentPiece) {
    if(piece_Can_Move(currentPiece, 0, -1)==true) {
        return true;
    }
    return false;
}

private boolean can_Move_Right(Piece currentPiece){
    if(piece_Can_Move(currentPiece, 0,1) == true) {
        return true;
    }
    return false;
}

public boolean can_Move_Down(Piece currentPiece) {
    if(piece_Can_Move(currentPiece, 1,0)==true) {
        return true;
    }
    return false;
}


private void movePiece(Piece currentPiece, int x, int y)   {
    deletePiece(currentPiece);
    currentPiece.move(x, y);
    placePiece(currentPiece);
}

public void moveRight(Piece currentPiece){
       if(can_Move_Right(currentPiece)==true) {
           movePiece(currentPiece, 0, 1);
       }
}

public  void moveLeft(Piece currentPiece){
  if(can_Move_Left(currentPiece)==true) {
      movePiece(currentPiece, 0, -1);
    }
}

public  void moveDown(Piece currentPiece) {
    if(can_Move_Down(currentPiece)==true) {
        movePiece(currentPiece, 1, 0);
    }
}

public void fastDrop(Piece currentPiece) {
    deletePiece(currentPiece);

    while(can_Move_Down(currentPiece)==true) {
        moveDown(currentPiece);
     }
    placePiece(currentPiece);
}

/*
turn all pieces until square piece
 */

public void rotatePiece(Piece currentPiece) {

     if(piece_Can_Rotate(currentPiece)==true && currentPiece.colorCode!=1) {
         deletePiece(currentPiece);
         currentPiece.turnPiece();
         placePiece(currentPiece);
     }
         placePiece(currentPiece);
 }

public int clearRows() {

    int deletedRowIndex;
    int deletedRows=0;
    ArrayList<Integer> arrayList = new ArrayList<Integer>();

    for (int i = 0; i < boardHeight; i++) {
        for (int j = boardWidth - 1; j >= 0; j--) {

            if (gameBoard[i][j]==0) { // Row not full
                break;
            }
            if (j == 0) {
                deletedRowIndex = i;
                arrayList.add(deletedRowIndex);
                deletedRows++;
                deleteRow(deletedRowIndex);
            }
        }
    }

    if (deletedRows >= 1) {
        int highestRow = Collections.min(arrayList); // highest Row which can be cleared
        int[][] gameBoardCopy = new int[highestRow][boardWidth];

        for (int i = 0; i < gameBoardCopy.length; i++) {
            for (int j = 0; j < gameBoardCopy[1].length; j++) {
                gameBoardCopy[i][j] = gameBoard[i][j];
            }
        }

        for (int i = 0; i < gameBoardCopy.length; i++) {
            for (int j = 0; j < gameBoardCopy[1].length; j++) {
                gameBoard[i+deletedRows][j] = gameBoardCopy[i][j];
            }
        }
    }
    return deletedRows;
}

public void deleteRow(int r){
        for (int i = 0; i < boardWidth; i++) {
            gameBoard[r][i] =0;
        }
}

public boolean checkGameOver(Piece spielStein) {
   if(can_Move_Down(spielStein) == false && spielStein.getMinXCoordinate(
   spielStein.x1, spielStein.x2, spielStein.x3, spielStein.x4)<=1) {
       return true;
   }
return false;
}

public  int getBoardHeight() {
    return this.boardHeight;
}

public int getBoardWidth() {
    return this.boardWidth;
}
}

Tetris.java:

public class Tetris extends View implements View.OnClickListener{

private MediaPlayer mediaPlayer;
private GameBoard gameBoard;
private MainActivity mainActivity;
private ImageButton rotateButton;
private ImageButton rightButton;
private ImageButton downButton;
private ImageButton leftButton;
private  Timer timer = new Timer();
private Random random = new Random();
private  ArrayList<Piece> pieceList;
private NextPieceView nextPieceView;
private TextView currentLevelTextView;
private TextView highscoreLevelTextView;
private TextView currentPunkteTextView;
private Points points;
private final int score=10;
private int timerPeriod =250;
private int level=0;
private boolean pause;

 public Tetris(Context context, NextPieceView nextPieceView, GameBoard 
    gameBoard) {
    super(context);

    this.mainActivity = (MainActivity) context;
    this.nextPieceView=nextPieceView;
    this.gameBoard =  gameBoard;
    pause = mainActivity.getPause();
    pieceList = gameBoard.getPieceList();
    mediaPlayer = mainActivity.getMediaPlayer();
    points = new Points(context);

    currentLevelTextView = mainActivity.getCurrentLevelTextView();
    highscoreLevelTextView = mainActivity.getHighscoreLevelTextView();
    currentPunkteTextView = mainActivity.getPointTextView();

    currentLevelTextView.append("0");
    currentPunkteTextView.append("0");
    highscoreLevelTextView.append(""+points.loadHighscore());

    rotateButton = mainActivity.getRotateButton();
    rightButton = mainActivity.getRightButton();
    downButton = mainActivity.getDownButton();
    leftButton = mainActivity.getLeftButton();

    rotateButton .setOnClickListener(this);
    rightButton.setOnClickListener(this);
    downButton.setOnClickListener(this);
    leftButton.setOnClickListener(this);
    gameLoop();
}

public void gameLoop() {

timer.schedule(new TimerTask() {

    @Override
    public void run() {
        mainActivity.runOnUiThread(new TimerTask() {

            @Override
            public void run() {

               if(gameOver()==false && mainActivity.getPause()==false ) {

                       gameBoard.moveDown(gameBoard.getCurrentPiece());

                    if (gameBoard.can_Move_Down(gameBoard.getCurrentPiece()) == false) {
                        int deletedRows = gameBoard.clearRows();
                        gameBoard.clearRows();
                        pieceList.remove(gameBoard.getCurrentPiece());
                        pieceList.add(new Piece(random.nextInt(7) + 1));
                        nextPieceView.invalidate();

                        if (deletedRows> 0) {
                            points.setCurrentPoints(points.getCurrentPoints() + deletedRows * score);
                            int p = points.getCurrentPoints();
                            points.setLevel();

                            currentPunkteTextView.setText("Points:" +" "+ p);
                            currentLevelTextView.setText("Level" +" "+ points.getLevel());

                            if (points.getLevel() > points.loadHighscore()) {
                                points.writeHighscore();
                                highscoreLevelTextView.setText("Highscore:" +" "+ points.getLevel());
                            }
                        }

                        if(points.getLevel()>level) {
                           level++;
                           timerPeriod = timerPeriod - (points.getLevel()*20);
                           timer.cancel();
                           timer = new Timer();
                           gameLoop();
                        }
                    }
                    invalidate();
                }
            }
        });
     }
 }, 0, timerPeriod);
}

public boolean gameOver() {

    if( gameBoard.checkGameOver(gameBoard.getCurrentPiece())==true ) {
        timer.cancel();
        pieceList.clear();
        gameBoard.clearGameBoard();
        mainActivity.setPause(true);
        mediaPlayer.stop();
        showGameOverScreen();
        return true;
}
return false;
}

 public void showGameOverScreen() {
 Intent intent = new Intent(this.getContext(), GameOverScreen.class);
 getContext().startActivity(intent);
}

 /*
 change colorCode to spezific Color and paint on Gameboard
 */
@Override
protected void onDraw(Canvas canvas) {

    super.onDraw(canvas);
    Paint p = new Paint();

    for (int x = 0; x < gameBoard.getBoardHeight(); x++) {
        for (int y = 0; y < gameBoard.getBoardWidth(); y++) {

          int color  = gameBoard.codeToColor(x,y);
          p.setColor(color);
          canvas.drawRect(y*30, x*30, y*30+30, x*30+30,p);
        }
    }
}

/*
control falling pieces with buttons
 */

@Override
public void onClick(View v) {
   if(mainActivity.getPause()==false) {

    switch(v.getId()) {
        case R.id.rightButton:
            gameBoard.moveRight(gameBoard.getCurrentPiece());
            invalidate();
            break;
        case R.id.downButton:
            gameBoard.fastDrop(gameBoard.getCurrentPiece());
            invalidate();
            break;
        case R.id.leftButton:
            gameBoard.moveLeft(gameBoard.getCurrentPiece());
            invalidate();
            break;
        case R.id.rotateButton:
            gameBoard.rotatePiece(gameBoard.getCurrentPiece());
            invalidate();
            break;
       }
     }
   }
 }

MainActivity:

import android.graphics.Color;
import android.media.MediaPlayer;
import android.net.Uri;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.RelativeLayout;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {

private Button buttonStart;
private ImageButton rotateButton;
private ImageButton rightButton;
private ImageButton downButton;
private ImageButton leftButton;

private TextView pointTextView;
private TextView highscoreLevelTextView;
private TextView currentLevelTextView;
private Tetris tetris;
private NextPieceView nextPieceView;
private boolean pause = true;
private MediaPlayer mediaPlayer;
private int stopMediaplayer;
private GameBoard gameBoard = new GameBoard();

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
   mediaPlayer = new MediaPlayer();
    try {
        mediaPlayer.setDataSource( this, Uri.parse("android.resource://com.example.admin.tetris/raw/tetrismusik"));
        mediaPlayer.prepare();
    } catch (Exception e) {e.printStackTrace();}


    buttonStart = (Button) findViewById(R.id.buttonstart);
    rotateButton = (ImageButton) findViewById(R.id.rotateButton);
    rightButton = (ImageButton) findViewById(R.id.rightButton);
    downButton = (ImageButton) findViewById(R.id.downButton);
    leftButton = (ImageButton) findViewById(R.id.leftButton);
    pointTextView = (TextView) findViewById(R.id.textViewPunkte);
    highscoreLevelTextView= (TextView) findViewById(R.id.textViewHighscore);
    currentLevelTextView = (TextView) findViewById(R.id.levelText);

    nextPieceView = new NextPieceView(this, gameBoard);
    RelativeLayout.LayoutParams params1 = new RelativeLayout.LayoutParams(300,300);
    nextPieceView.setLayoutParams(params1);
    RelativeLayout relativeSteinAnzeige = (RelativeLayout) findViewById(R.id.relativelayout1);
    nextPieceView.setBackgroundColor(Color.YELLOW);
    relativeSteinAnzeige.addView(nextPieceView);

    tetris = new Tetris(this,nextPieceView, gameBoard);
    RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(480, 900);
    tetris.setLayoutParams(params);
    RelativeLayout relativeTetris = (RelativeLayout) findViewById(R.id.relativelayout);
    tetris.setBackgroundColor(Color.YELLOW);
    relativeTetris.addView(tetris);
    buttonStart.setOnClickListener(new View.OnClickListener() {

       int tmp=0;
        @Override
        public void onClick(View v) {
            stopMediaplayer = mediaPlayer.getCurrentPosition();
             tmp++;

            if(buttonStart.getText().equals("Start")) {
                buttonStart.setText("Pause");
                pause = false;

                if(tmp==1) {
                    mediaPlayer.start();
                    mediaPlayer.setLooping(true);
                } else if(tmp>1) {
                    mediaPlayer.seekTo(stopMediaplayer);
                    mediaPlayer.start();
                }
            }

            else if(buttonStart.getText().equals("Pause")) {
                buttonStart.setText("Start");
                pause = true;
                mediaPlayer.pause();
            }

        }
    });
}

@Override
public void onRestart() {
    super.onRestart();
    pause = false;
    mediaPlayer.seekTo(stopMediaplayer);
    mediaPlayer.start();
}

@Override
public void onPause() {
    super.onPause();
    pause = true;
    mediaPlayer.stop();
    mediaPlayer.pause();
    stopMediaplayer = mediaPlayer.getCurrentPosition();
}

@Override
public void onDestroy() {
    super.onDestroy();
    finish();
}


public ImageButton getRightButton() { return rightButton;}
public ImageButton getDownButton() { return downButton;}
public ImageButton getLeftButton() { return leftButton;}
public ImageButton getRotateButton() { return rotateButton; }

public boolean getPause() {  return pause;}
public void setPause(boolean pause) { this.pause=pause;}
public TextView getHighscoreLevelTextView() { return highscoreLevelTextView; 
}
public TextView getPointTextView() { return pointTextView; }
public TextView getCurrentLevelTextView() { return currentLevelTextView;}
public MediaPlayer getMediaPlayer() {  return mediaPlayer; }
 }

All help and suggestions would be really appreciated

\$\endgroup\$
  • \$\begingroup\$ No Suggestions? Should i improve my Post? \$\endgroup\$ – Marten Jun 21 '18 at 7:51
  • 1
    \$\begingroup\$ just give it time. Some reviews take more time to write. Larger questions take longer to read and understand. Although with that much code more explaination of what is happening in the code would facilitate a faster/better response. \$\endgroup\$ – bruglesco Jun 21 '18 at 18:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.