package checkers; import java.awt.AlphaComposite; import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Point; import java.awt.RenderingHints; import java.util.Collections; import java.util.List; import javax.swing.JPanel; /** * Component displaying state of the board */ public class BoardView extends JPanel { static class CurrentMoveState { Point piece = new Point(); Point position = new Point(); Point offset = new Point(); List<Move> possibleMoves = Collections.emptyList(); } private static final long serialVersionUID = -1441037602815044777L; Board board; CurrentMoveState currentMove = null; public BoardView(Board b) { setBoard(b); final int size = 32; setPreferredSize(new Dimension(size * Board.width, size * Board.height)); setSize(getPreferredSize()); setBackground(Color.red); } public synchronized void animateMove(final Move move) { currentMove = new CurrentMoveState(); currentMove.piece = move.p0; currentMove.offset = new Point(0, 0); currentMove.position = new Point(); int frames = 30; for(int i = 0; i < frames; i++) { currentMove.position.x = (move.p0.x * (frames - i) + move.p1.x * i) * 32 / frames; currentMove.position.y = (move.p0.y * (frames - i) + move.p1.y * i) * 32 / frames; repaint(); try { Thread.sleep(1000 / 60); } catch(InterruptedException e) { break; } } currentMove = null; } @Override public void paint(Graphics g) { if(g instanceof Graphics2D) ((Graphics2D)g).setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); final Color evenColor = new Color(0xfece9e); final Color oddColor = new Color(0xd08c47); for(int y = 0; y < Board.height; y++) { for(int x = 0; x < Board.width; x++) { if(((x ^ y) & 1) == 0) g.setColor(evenColor); else g.setColor(oddColor); g.fillRect(x * 32, y * 32, 32, 32); } } for(int y = 0; y < Board.height; y++) { for(int x = 0; x < Board.width; x++) { if(currentMove==null || currentMove.piece.x != x || currentMove.piece.y != y) drawPiece(g, x * 32, y * 32, board.get(x, y)); } } if(currentMove != null) { if(g instanceof Graphics2D) { ((Graphics2D)g).setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.2f)); if(currentMove.possibleMoves != null) for(Move m : currentMove.possibleMoves) { drawPiece(g, m.p1.x * 32, m.p1.y * 32, board.get(currentMove.piece.x, currentMove.piece.y)); } ((Graphics2D)g).setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER)); } drawPiece(g, currentMove.position.x + currentMove.offset.x, currentMove.position.y + currentMove.offset.y, board.get(currentMove.piece.x, currentMove.piece.y)); } } private void drawPiece(Graphics g, Color fg, Color bg, int piece) { final int m = 2; final int p = 6; g.setColor(bg); g.fillOval(m, m, 31 - m * 2, 31 - m * 2); g.setColor(fg); g.drawOval(m, m, 31 - m * 2, 31 - m * 2); g.drawOval(p, p, 31 - p * 2, 31 - p * 2); if(piece == 2) { g.drawLine(12, 16, 19, 16); g.drawLine(12, 15, 19, 15); g.drawLine(15, 12, 15, 19); g.drawLine(16, 12, 16, 19); } } private void drawPiece(Graphics g, int x, int y, int piece) { g.translate(x, y); switch(Utils.sign(piece)) { case 0: break; case 1: drawPiece(g, Color.BLACK, Color.WHITE, Math.abs(piece)); break; case -1: drawPiece(g, Color.WHITE, Color.BLACK, Math.abs(piece)); break; } g.translate(-x, -y); } public void setBoard(Board board) { this.board = board; currentMove = null; repaint(); } public Board getBoard() { return board; } }