/** Draws the game */ @Override protected void paintComponent(Graphics g) { super.paintComponent(g); final Graphics2D g2 = (Graphics2D) g; /** Draw all the non-falling blocks on the board. Non-OUTSIDE blocks have rounded corners. */ for (int row = 0; row < board.getHeight(); row++) { for (int column = 0; column < board.getWidth(); column++) { if (board.getSquareType(row, column) != SquareType.OUTSIDE) { Shape tetrominoBlock = new RoundRectangle2D.Double( column * SQUARE_WIDTH, row * SQUARE_HEIGHT, SQUARE_WIDTH, SQUARE_HEIGHT, 5, 5); g2.setColor(SQUARE_COLOR.get(board.getSquareType(row, column))); g2.fill(tetrominoBlock); g2.draw(tetrominoBlock); } else { Shape tetrominoBlock = new Rectangle2D.Double( column * SQUARE_WIDTH, row * SQUARE_HEIGHT, SQUARE_WIDTH, SQUARE_HEIGHT); g2.setColor(SQUARE_COLOR.get(board.getSquareType(row, column))); g2.fill(tetrominoBlock); g2.draw(tetrominoBlock); } } } Poly tempPoly = board.getFalling(); if (tempPoly != null) { for (int row = 0; row < tempPoly.getSize(); row++) { for (int column = 0; column < tempPoly.getSize(); column++) { if (tempPoly.getSquareType(row, column) != SquareType.EMPTY) { Shape tetrominoBlock = new RoundRectangle2D.Double( (column + board.getFallingPosX()) * SQUARE_WIDTH, (row + board.getFallingPosY()) * SQUARE_HEIGHT, SQUARE_WIDTH, SQUARE_HEIGHT, 5, 5); g2.setColor(SQUARE_COLOR.get(tempPoly.getSquareType(row, column))); g2.fill(tetrominoBlock); g2.draw(tetrominoBlock); } } } } }
/** * Handles the events for keypresses * * @param e the pressed key */ public void keyPressed(KeyEvent e) { if (activePentomino != null) { // Keys for moveing the pentomino sideways if (e.getKeyCode() == KeyEvent.VK_LEFT || e.getKeyCode() == KeyEvent.VK_RIGHT) { // Initialize direction to 0 to make sure we don't get null pointer exception // or do something weird with the movement int direction = 0; if (e.getKeyCode() == KeyEvent.VK_LEFT) direction = -1; if (e.getKeyCode() == KeyEvent.VK_RIGHT) direction = 1; // +1 right, -1 left // Check if we are allowed to actually move the pentomino to the new position boolean legalMove = true; for (Point p : activePentomino.getLocation()) { int newX = (int) (p.getX() + pentominoLocation.getX() + direction); int newY = (int) (p.getY() + pentominoLocation.getY()); // Check only if the pentomino is not above the board if (newY >= 0) { // Check that we are horizontally within the board and not trying to overlap another // piece if (newX < 0 || newX >= gameBoard.getBoard().length || gameBoard.getBoard()[newX][newY] != -1) legalMove = false; } } // Check passed so we do the actual movement of the pentomino if (legalMove) { pentominoLocation.setLocation( (pentominoLocation.getX() + direction), pentominoLocation.getY()); predictDrop(); updateMatrix(); } } // Key for rotating the pentomino if (e.getKeyCode() == KeyEvent.VK_UP) { // Create a temporary pentomino to check if the rotated position free Pentomino tmpPentomino = activePentomino.copy(); tmpPentomino.rotate(); boolean legalMove = true; // For reach block of the position check that it's free and within the grid // ignoring the check if we're above the grid for (Point p : tmpPentomino.getLocation()) { int newX = (int) (p.getX() + pentominoLocation.getX()); int newY = (int) (p.getY() + pentominoLocation.getY()); if (newY > 0) { if (newY >= gameBoard.getBoard()[0].length || newX < 0 || newX >= gameBoard.getBoard().length || gameBoard.getBoard()[newX][newY] != -1) { legalMove = false; } } } // If the check passed then simply do the rotation if (legalMove) { activePentomino.rotate(); predictDrop(); } // Update the matrix so we don't have lag in display updateMatrix(); } // Key for speeding up the fall if (e.getKeyCode() == KeyEvent.VK_DOWN) { // If next position is available, put the current pentomino to it if (nextDropLegal(activePentomino, gameBoard.getBoard(), pentominoLocation)) { pentominoLocation.setLocation(pentominoLocation.getX(), pentominoLocation.getY() + 1); } // Update to avoid lag updateMatrix(); } // Key for entirely dropping the pentomino if (e.getKeyCode() == KeyEvent.VK_ENTER) { // We make the pentomino fall as many times as it can while (nextDropLegal(activePentomino, gameBoard.getBoard(), pentominoLocation)) { pentominoLocation.setLocation(pentominoLocation.getX(), pentominoLocation.getY() + 1); } // Update to avoid lag updateMatrix(); } // Key for flipping the pentomino if (e.getKeyCode() == KeyEvent.VK_SPACE) { // Create a temporary pentomino for checking the flipped position Pentomino tmpPentomino = activePentomino.copy(); tmpPentomino.reflect(); // Check that each position in the temporary pentomino is available and within the matrix boolean legalMove = true; for (Point p : tmpPentomino.getLocation()) { int newX = (int) (p.getX() + pentominoLocation.getX()); int newY = (int) (p.getY() + pentominoLocation.getY()); if (newY < 0 || newY >= gameBoard.getBoard()[0].length || newX < 0 || newX >= gameBoard.getBoard().length || gameBoard.getBoard()[newX][newY] != -1) { legalMove = false; } } // Flip the pentomino if check is passed if (legalMove) { activePentomino.reflect(); predictDrop(); } // Update to avoid lag updateMatrix(); } // Key for storing the currently falling pentomino if (e.getKeyCode() == KeyEvent.VK_SHIFT) { // If we haven't stored after fixing the pentomino to the grid if (storageable) { // Change the active and stored pentomino and set the location to the top of the screen pentominoLocation = new Point(gameBoard.getWidth() / 2, 0); Pentomino tmp = activePentomino; activePentomino = storagedPentomino; storagedPentomino = tmp; storageable = false; // Get new prediction predictDrop(); // Update to avoid lag updateMatrix(); } } // Key for a chect for testing purposes if (e.getKeyCode() == KeyEvent.VK_X) { // If pressed enough, add score cheat++; if (cheat > 10) { cheat = 0; addScore(12); } } } }