Added movement animations

This commit is contained in:
Filip Znachor 2023-04-22 23:40:41 +02:00
parent 4fbfa03219
commit c27f764bc0
7 changed files with 80 additions and 28 deletions

View file

@ -1,6 +1,8 @@
import java.awt.*;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Path2D;
import java.util.Timer;
import java.util.TimerTask;
/**
* Abstract piece class
@ -147,6 +149,17 @@ public abstract class AbstractPiece implements IPiece {
* @param pos piece position
*/
public void setPosition(PiecePosition pos) {
setPosition(pos, true);
}
/**
* Set piece's new position
* @param pos piece position
* @param animate animate piece's move
*/
public void setPosition(PiecePosition pos, boolean animate) {
if(animate) animateMove(x, y, pos.x, pos.y);
moveCount++;
chessboard.removePiece(x, y);
x = pos.x;
y = pos.y;
@ -217,12 +230,22 @@ public abstract class AbstractPiece implements IPiece {
}
public void move(PiecePosition pos) {
move(pos, true);
}
public void move(PiecePosition pos, boolean animate) {
boolean[][] lastMove = new boolean[chessboard.SQUARE_COUNT][chessboard.SQUARE_COUNT];
lastMove[y][x] = true;
lastMove[pos.y][pos.x] = true;
setPosition(pos);
setPosition(pos, animate);
chessboard.showLastMove(lastMove);
moveCount++;
}
public Rectangle getRepaintRectangle(double pieceX, double pieceY, double totalScale) {
return new Rectangle(
(int) pieceX - 10, (int) pieceY - 10,
(int) (100*totalScale) + 20, (int) (100*totalScale) + 20
);
}
public void tracePath(boolean[][] moves, int xDirection, int yDirection) {
@ -250,4 +273,31 @@ public abstract class AbstractPiece implements IPiece {
return moveCount;
}
}
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 stepX = (endX-startX)/50;
double stepY = (endY-startY)/50;
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
int i = 1;
@Override
public void run() {
double currentX = i * stepX + startX;
double currentY = i * stepY + startY;
if(i > 50) {
timer.cancel();
setOverride(0, 0);
} else {
setOverride(currentX, currentY);
}
chessboard.repaint(getRepaintRectangle(currentX, currentY, chessboard.boardScale*chessboard.pieceScale));
i++;
}
}, 10, 10);
}
}

View file

@ -10,7 +10,7 @@ public class Chessboard extends JPanel {
/**
* Size of single square
*/
private final int SQUARE_SIZE = 100;
public final int SQUARE_SIZE = 100;
/**
* Count of squares on the board
@ -35,12 +35,12 @@ public class Chessboard extends JPanel {
/**
* Top location of the board
*/
private double startX;
public double startX;
/**
* Left location of the board
*/
private double startY;
public double startY;
/**
* Instance of the selected piece
@ -170,11 +170,15 @@ public class Chessboard extends JPanel {
}
}
if(selected != null && selected.isFloating()) {
g2.setTransform(beforeBoard);
g2.translate(selected.getOverrideX(), selected.getOverrideY());
g2.scale(pieceScale * boardScale, pieceScale * boardScale);
selected.paint(g2);
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);
}
}
}
g2.setTransform(beforeBoard);
@ -305,5 +309,4 @@ public class Chessboard extends JPanel {
}
}
}
}

View file

@ -84,11 +84,11 @@ public class ChessboardMouseAdapter extends MouseAdapter {
IPiece piece = c.getSelectedPiece();
if (piece != null) {
double totalScale = c.pieceScale * c.boardScale;
c.getRootPane().repaint(getRepaintRectangle(piece.getOverrideX(), piece.getOverrideY(), totalScale));
c.getRootPane().repaint(piece.getRepaintRectangle(piece.getOverrideX(), piece.getOverrideY(), totalScale));
double pieceX = me.getX() - 50 * totalScale;
double pieceY = me.getY() - 50 * totalScale;
piece.setOverride(pieceX, pieceY);
c.getRootPane().repaint(getRepaintRectangle(pieceX, pieceY, totalScale));
c.getRootPane().repaint(piece.getRepaintRectangle(pieceX, pieceY, totalScale));
}
}
@ -98,7 +98,7 @@ public class ChessboardMouseAdapter extends MouseAdapter {
PiecePosition pos = c.getPieceCoordinates(me.getX(), me.getY());
if(piece != null) {
if(piece.getPossibleMoves()[pos.y][pos.x]) {
piece.move(pos);
piece.move(pos, false);
c.showPossibleMoves(null);
if(c.getActivePlayer().inCheck()) System.out.println("Inactive player in check!");
c.changeActivePlayer();
@ -110,11 +110,4 @@ public class ChessboardMouseAdapter extends MouseAdapter {
c.getRootPane().repaint();
}
public Rectangle getRepaintRectangle(double pieceX, double pieceY, double totalScale) {
return new Rectangle(
(int) pieceX - 10, (int) pieceY - 10,
(int) (100*totalScale) + 20, (int) (100*totalScale) + 20
);
}
}

View file

@ -54,6 +54,8 @@ public interface IPiece {
*/
void setPosition(PiecePosition pos);
void setPosition(PiecePosition pos, boolean animate);
boolean[][] getPossibleMoves();
boolean[][] getPossibleMoves(boolean attack);
@ -62,11 +64,15 @@ public interface IPiece {
void move(PiecePosition pos);
void move(PiecePosition pos, boolean animate);
Player getPlayer();
boolean isEndangered();
int getMoveCount();
Rectangle getRepaintRectangle(double pieceX, double pieceY, double totalScale);
}

View file

@ -62,8 +62,8 @@ public class King extends AbstractPiece {
}
@Override
public void move(PiecePosition pos) {
super.move(pos);
public void move(PiecePosition pos, boolean animate) {
super.move(pos, animate);
if(moveCount == 1 && x == 6) {
player.getRightRook().setPosition(new PiecePosition(5, y));
}

View file

@ -57,7 +57,7 @@ public class Pawn extends AbstractPiece {
}
@Override
public void move(PiecePosition pos) {
public void move(PiecePosition pos, boolean animate) {
for (int directionX : new int[]{-1, 1}) {
if(checkEnPassant(directionX) && pos.x == x+directionX) {
@ -65,7 +65,7 @@ public class Pawn extends AbstractPiece {
}
}
super.move(pos);
super.move(pos, animate);
int changeY = color == PieceColor.WHITE ? 0 : chessboard.SQUARE_COUNT-1;
if(y == changeY) new Queen(player, x, y);

View file

@ -30,12 +30,12 @@ public class Player {
int first = startPosition == StartPosition.BOTTOM ? 7 : 0;
int second = startPosition == StartPosition.BOTTOM ? 6 : 1;
leftRook = new Rook(this, 0, first);
new Knight(this, 1, first);
rightRook = new Rook(this, 7, first);
/*new Knight(this, 1, first);
new Knight(this, 6, first);
new Queen(this, 3, first);
new Bishop(this, 5, first);
new Bishop(this, 2, first);
new Bishop(this, 2, first);*/
king = new King(this, 4, first);
for (int j = 0; j < 8; j++) {
new Pawn(this, j, second);