Improved piece rendering

This commit is contained in:
Filip Znachor 2023-04-25 17:30:35 +02:00
parent d72e9202af
commit 0d5c5a3f23
4 changed files with 117 additions and 78 deletions

View file

@ -43,6 +43,8 @@ public abstract class APiece {
public int moveCount = 0;
public double scale = 1;
/**
* Create new piece
* @param player player
@ -161,6 +163,10 @@ public abstract class APiece {
if(animate) animateMove(x, y, pos.x, pos.y);
moveCount++;
chessboard.removePiece(x, y);
APiece piece = chessboard.getPiece(pos);
if(piece != null) {
piece.remove();
}
x = pos.x;
y = pos.y;
chessboard.addPiece(this, x, y);
@ -185,7 +191,7 @@ public abstract class APiece {
* @return override X location
*/
public double getOverrideX() {
return overrideX;
return (overrideX-chessboard.startX)/chessboard.boardScale;
}
/**
@ -193,7 +199,17 @@ public abstract class APiece {
* @return override Y location
*/
public double getOverrideY() {
return overrideY;
return (overrideY-chessboard.startY)/chessboard.boardScale;
}
public double getRealX() {
if(overrideX != 0) return getOverrideX();
return chessboard.SQUARE_SIZE*x;
}
public double getRealY() {
if(overrideY != 0) return getOverrideY();
return chessboard.SQUARE_SIZE*y;
}
/**
@ -240,10 +256,17 @@ public abstract class APiece {
chessboard.showLastMove(lastMove);
}
public Rectangle getRepaintRectangle(double pieceX, double pieceY, double totalScale) {
public Rectangle getRepaintRectangle() {
return getRepaintRectangle(0);
}
public Rectangle getRepaintRectangle(int offsetY) {
int rectSize = (int) (chessboard.SQUARE_SIZE*chessboard.boardScale);
double x = getRealX()*chessboard.boardScale+chessboard.startX;
double y = getRealY()*chessboard.boardScale+chessboard.startY;
return new Rectangle(
(int) pieceX - 10, (int) pieceY - 10,
(int) (100*totalScale) + 20, (int) (100*totalScale) + 20
(int) x - 10, (int) y + offsetY - 10,
rectSize + 20, rectSize + 20
);
}
@ -280,10 +303,10 @@ public abstract class APiece {
}
public void animateMove(int fromX, int fromY, int toX, int toY) {
double startX = chessboard.startX + (fromX*chessboard.SQUARE_SIZE+20*chessboard.pieceScale)*chessboard.boardScale;
double startY = chessboard.startY + (fromY*chessboard.SQUARE_SIZE+20*chessboard.pieceScale)*chessboard.boardScale;
double endX = chessboard.startX + (toX*chessboard.SQUARE_SIZE+20*chessboard.pieceScale)*chessboard.boardScale;
double endY = chessboard.startY + (toY*chessboard.SQUARE_SIZE+20*chessboard.pieceScale)*chessboard.boardScale;
double startX = chessboard.startX + (fromX*chessboard.SQUARE_SIZE)*chessboard.boardScale;
double startY = chessboard.startY + (fromY*chessboard.SQUARE_SIZE)*chessboard.boardScale;
double endX = chessboard.startX + (toX*chessboard.SQUARE_SIZE)*chessboard.boardScale;
double endY = chessboard.startY + (toY*chessboard.SQUARE_SIZE)*chessboard.boardScale;
double stepX = (endX-startX)/100;
double stepY = (endY-startY)/100;
Timer timer = new Timer();
@ -292,7 +315,7 @@ public abstract class APiece {
double currentX = 0;
double currentY = 0;
public void run() {
chessboard.repaint(getRepaintRectangle(currentX, currentY, chessboard.boardScale*chessboard.pieceScale));
chessboard.repaint(getRepaintRectangle());
if(i > 100) {
timer.cancel();
setOverride(0, 0);
@ -301,10 +324,32 @@ public abstract class APiece {
currentY = i * stepY + startY;
setOverride(currentX, currentY);
}
chessboard.repaint(getRepaintRectangle(currentX, currentY, chessboard.boardScale*chessboard.pieceScale));
chessboard.repaint(getRepaintRectangle());
i++;
}
}, 5, 5);
}
public void remove() {
chessboard.removePiece(x, y);
Timer timer = new Timer();
scale = .99;
timer.scheduleAtFixedRate(new TimerTask() {
double decrement = .01;
public void run() {
scale -= decrement;
decrement *= 1.2;
if(scale < 0) {
timer.cancel();
scale = 0;
}
chessboard.repaint(getRepaintRectangle());
}
}, 5, 5);
}
public double getScale() {
return scale;
}
}

View file

@ -12,7 +12,7 @@ public class Chessboard extends JPanel {
/**
* Size of single square
*/
public final int SQUARE_SIZE = 100;
public final int SQUARE_SIZE = 140;
/**
* Count of squares on the board
@ -29,11 +29,6 @@ public class Chessboard extends JPanel {
*/
public double boardScale;
/**
* Scale of single piece
*/
public double pieceScale;
/**
* Top location of the board
*/
@ -60,12 +55,10 @@ public class Chessboard extends JPanel {
public boolean[][] lastMove = new boolean[SQUARE_COUNT][SQUARE_COUNT];
private Player player1;
private Player player2;
private Player activePlayer;
private Player otherPlayer;
public boolean blindMode = false;
/**
@ -190,7 +183,7 @@ public class Chessboard extends JPanel {
boolean isBlack = true;
g2.setStroke(new BasicStroke(10));
g2.setStroke(new BasicStroke(16));
for(int i=0; i<SQUARE_COUNT; i++) {
if(SQUARE_COUNT % 2 == 0) isBlack = !isBlack;
@ -204,62 +197,67 @@ public class Chessboard extends JPanel {
}
g2.setTransform(beforeSquares);
pieceScale = SQUARE_SIZE / 140.0;
double pieceOffset = 20*pieceScale;
for (int y = 0; y < pieces.length; y++) {
for (int x = 0; x < pieces[y].length; x++) {
if(pieces[y][x] != null && !pieces[y][x].isFloating()) {
if(blindMode && pieces[y][x].getPlayer() != activePlayer) continue;
double xOffset = pieceOffset + SQUARE_SIZE*x;
double yOffset = pieceOffset + SQUARE_SIZE*y;
g2.translate(xOffset, yOffset);
g2.scale(pieceScale, pieceScale);
pieces[y][x].paint(g2);
g2.setTransform(beforeSquares);
}
}
}
for (int y = 0; y < pieces.length; y++) {
for (int x = 0; x < pieces[y].length; x++) {
if(pieces[y][x] != null && pieces[y][x].isFloating()) {
g2.setTransform(beforeBoard);
g2.translate(pieces[y][x].getOverrideX(), pieces[y][x].getOverrideY());
g2.scale(pieceScale * boardScale, pieceScale * boardScale);
pieces[y][x].paint(g2);
}
}
}
for (APiece piece : removedPieces) {
if(!piece.isFloating()) continue;
g2.setTransform(beforeBoard);
g2.translate(piece.getOverrideX(), piece.getOverrideY());
g2.scale(pieceScale * boardScale, pieceScale * boardScale);
piece.paint(g2);
boolean isFloating = piece.isFloating();
double pScale = piece.getScale();
if(!isFloating && pScale == 1) continue;
g2.setTransform(beforeSquares);
paintPiece(g2, piece);
}
for (int y = 0; y < pieces.length; y++) {
for (int x = 0; x < pieces[y].length; x++) {
APiece piece = pieces[y][x];
if(piece != null && !piece.isFloating()) {
if(blindMode && piece.getPlayer() != activePlayer) continue;
g2.setTransform(beforeSquares);
paintPiece(g2, piece);
}
}
}
for (int y = 0; y < pieces.length; y++) {
for (int x = 0; x < pieces[y].length; x++) {
APiece piece = pieces[y][x];
if(piece != null && piece.isFloating()) {
g2.setTransform(beforeSquares);
paintPiece(g2, piece);
}
}
}
}
public void paintSquare(Graphics g, boolean isBlack) {
private void paintSquare(Graphics g, boolean isBlack) {
if(isBlack) g.setColor(Color.LIGHT_GRAY);
else g.setColor(Color.WHITE);
g.fillRect(0, 0, SQUARE_SIZE+1, SQUARE_SIZE+1);
}
public void paintHighlights(Graphics g, int x, int y) {
private void paintHighlights(Graphics g, int x, int y) {
if(lastMove != null && lastMove[y][x]) {
g.setColor(new Color(50, 50, 250, 30));
g.fillRect(0, 0, SQUARE_SIZE, SQUARE_SIZE);
}
if(possibleMoves != null && possibleMoves[y][x]) {
g.setColor(new Color(0, 0, 0, 40));
if(pieces[y][x] == null) g.fillOval(35, 35, 30, 30);
else g.drawRect(5, 5, 90, 90);
if(pieces[y][x] == null) g.fillOval(50, 50, 40, 40);
else g.drawRect(8, 8, SQUARE_SIZE-16, SQUARE_SIZE-16);
}
}
private void paintPiece(Graphics2D g2, APiece piece) {
g2.translate(20+piece.getRealX(), 20+piece.getRealY());
double pieceScale = piece.getScale();
if(pieceScale != 1) {
double offset = (1-pieceScale)*50;
g2.translate(offset, offset);
g2.scale(pieceScale, pieceScale);
}
piece.paint(g2);
}
/**
* Setup Graphics2D with anti-aliasing
* @param g Graphics instance
@ -323,8 +321,8 @@ public class Chessboard extends JPanel {
public boolean isEndangered(Player player, int x, int y) {
if(!isOnBoard(x, y)) return false;
boolean[][] coverageArea;
if(player == player1) coverageArea = player2.getCoverageArea();
else coverageArea = player1.getCoverageArea();
if(player == activePlayer) coverageArea = otherPlayer.getCoverageArea();
else coverageArea = activePlayer.getCoverageArea();
return coverageArea[y][x];
}
@ -341,12 +339,11 @@ public class Chessboard extends JPanel {
}
public void setPlayer1(Player player) {
player1 = player;
activePlayer = player;
}
public void setPlayer2(Player player) {
player2 = player;
otherPlayer = player;
}
public Player getActivePlayer() {
@ -354,11 +351,9 @@ public class Chessboard extends JPanel {
}
public void changeActivePlayer() {
if(activePlayer == player1) {
activePlayer = player2;
} else {
activePlayer = player1;
}
Player tempPlayer = activePlayer;
activePlayer = otherPlayer;
otherPlayer = tempPlayer;
generateCoverageAreas();
}
@ -368,13 +363,13 @@ public class Chessboard extends JPanel {
for (APiece[] pieces2 : pieces) {
for (APiece piece : pieces2) {
if(piece != null && piece != selected) {
if(piece.getPlayer() == player1) mergeCoverageAreas(player1Area, piece.getPossibleMoves(true));
if(piece.getPlayer() == player2) mergeCoverageAreas(player2Area, piece.getPossibleMoves(true));
if(piece.getPlayer() == activePlayer) mergeCoverageAreas(player1Area, piece.getPossibleMoves(true));
if(piece.getPlayer() == otherPlayer) mergeCoverageAreas(player2Area, piece.getPossibleMoves(true));
}
}
}
player1.setCoverageArea(player1Area);
player2.setCoverageArea(player2Area);
activePlayer.setCoverageArea(player1Area);
otherPlayer.setCoverageArea(player2Area);
}
private void mergeCoverageAreas(boolean[][] area1, boolean[][] area2) {

View file

@ -83,13 +83,11 @@ public class ChessboardMouseAdapter extends MouseAdapter {
Chessboard c = (Chessboard) me.getSource();
APiece piece = c.getSelectedPiece();
if (piece != null) {
int yOffset = Chess.menuBar.getHeight();
double totalScale = c.pieceScale * c.boardScale;
c.getRootPane().repaint(piece.getRepaintRectangle(piece.getOverrideX(), piece.getOverrideY() + yOffset, totalScale));
double pieceX = me.getX() - 50 * totalScale;
double pieceY = me.getY() - 50 * totalScale;
c.getRootPane().repaint(piece.getRepaintRectangle(Chess.menuBar.getHeight()));
double pieceX = me.getX() - c.SQUARE_SIZE/2 * c.boardScale;
double pieceY = me.getY() - c.SQUARE_SIZE/2 * c.boardScale;
piece.setOverride(pieceX, pieceY);
c.getRootPane().repaint(piece.getRepaintRectangle(pieceX, pieceY + yOffset, totalScale));
c.getRootPane().repaint(piece.getRepaintRectangle(Chess.menuBar.getHeight()));
}
}

View file

@ -63,7 +63,8 @@ public class Pawn extends APiece {
for (int directionX : new int[]{-1, 1}) {
if(checkEnPassant(directionX) && pos.x == x+directionX) {
chessboard.removePiece(x+directionX, y);
APiece piece = chessboard.getPiece(new PiecePosition(x+directionX, y));
if(piece != null) piece.remove();
}
}