/** * Moves this piece to a new position on the board. * * @param newRow The destination row. * @param newColumn The destination column. * @return <code>false</code> if the destination is not a legal board position, or if the piece is * already moving. */ public boolean moveTo(int newRow, int newColumn) { if (!board.isLegalPosition(newRow, newColumn)) return false; if (moving) return false; int startX = board.columnToX(column); int startY = board.rowToY(row); int finishX = board.columnToX(newColumn); int finishY = board.rowToY(newRow); int changeInX = finishX - startX; int changeInY = finishY - startY; Rectangle oldRect = getRectangle(); Rectangle newRect = new Rectangle(oldRect); // compensate for squares being slightly different sizes oldRect.width += 2; newRect.width += 2; oldRect.height += 2; newRect.height += 2; // Move smoothly towards new position moving = true; board.moveToTop(this); int deltaRow = Math.abs(row - newRow); int deltaColumn = Math.abs(column - newColumn); int distance = Math.max(deltaRow, deltaColumn) + Math.min(deltaRow, deltaColumn) / 2; int numberOfSteps = distance * FRAME_RATE / getSpeed(); for (int i = 1; i <= numberOfSteps; i++) { oldRect.x = x; oldRect.y = y; x = startX + (i * changeInX) / numberOfSteps; y = startY + (i * changeInY) / numberOfSteps; newRect.x = x; newRect.y = y; board.getJPanel().paintImmediately(oldRect.union(newRect)); // redraw(oldRect.union(newRect)); try { Thread.sleep(PAUSE_MS); } catch (InterruptedException e) { /* Deliberately empty */ } } moving = false; if (canMoveTo(newRow, newColumn)) { changePosition(newRow, newColumn); } redraw(oldRect.union(newRect)); return true; }
/** * Continues dragging a piece. * * @see java.awt.event.MouseMotionListener#mouseDragged(java.awt.event.MouseEvent) */ @Override public void mouseDragged(MouseEvent e) { int x; int y; if (pieceBeingDragged == null) return; // Don't allow drag outside board boundaries int maxX = board.columnToX(board.getColumns() - 1); int maxY = board.rowToY(board.getRows() - 1); x = e.getX() - board.getCellWidth() / 2; if (x < 0) { x = 0; } else { if (x > maxX) x = maxX; } y = e.getY() - board.getCellHeight() / 2; if (y < 0) { y = 0; } else { if (y > maxY) y = maxY; } pieceBeingDragged.x = x; pieceBeingDragged.y = y; // Track mouse movement pieceBeingDragged.setChanged(); pieceBeingDragged.notifyObservers(); }
/** * Change the position of this piece on the board. * * @param newRow The new row for this piece. * @param newColumn The new column for this piece. */ private void changePosition(int newRow, int newColumn) { if (!atLegalPosition()) return; int oldRow = row; int oldColumn = column; board.changePositionOnBoard(this, oldRow, oldColumn, newRow, newColumn); row = newRow; column = newColumn; x = board.columnToX(column); y = board.rowToY(row); redraw(); }
/** * For internal use only! * * @param board The board on which to place this piece. * @param row The row number. * @param column The column number. */ final void placeHelper(Board board, int row, int column) { // When a piece is placed on a board, both the piece and // the board must be updated. This method is called from // Board.place to update the piece. this.board = board; this.row = row; this.column = column; x = board.columnToX(column); y = board.rowToY(row); addObserver(board); redraw(getRectangle()); }
/** * Returns the rectangle in which this piece should be painted. * * @return The rectangle in which to paint this piece. */ protected Rectangle getRectangle() { int leftEdge = getX() + 1; int topEdge = getY() + 1; int width; int height; if (moving) { width = board.getCellWidth() - 1; height = board.getCellHeight() - 1; } else { width = board.columnToX(column + 1) - leftEdge; height = board.rowToY(row + 1) - topEdge; } return new Rectangle(leftEdge, topEdge, width, height); }
/** * Returns the y-coordinate at which this piece will be painted. * * @return The y-coordinate. */ protected int getY() { return moving ? y : board.rowToY(row); }