Splitted floating and selected pieces, improved drag performance

This commit is contained in:
Filip Znachor 2023-04-22 11:23:57 +02:00
parent 50ba504505
commit 642d4e718b
11 changed files with 63 additions and 56 deletions

View file

@ -153,6 +153,11 @@ public abstract class AbstractPiece implements IPiece {
chessboard.addPiece(this, x, y);
}
@Override
public boolean isFloating() {
return overrideX != 0 && overrideY != 0;
}
/**
* Set override location if piece is floating
* @param x floating piece's X location
@ -203,7 +208,7 @@ public abstract class AbstractPiece implements IPiece {
if(x == this.x && y == this.y) return;
if(x < 0 || x >= moves.length || y < 0 || y >= moves.length) return;
IPiece piece = chessboard.getPiece(new PiecePosition(x, y));
if(piece != null && piece != chessboard.getFloatingPiece() && player == piece.getPlayer()) return;
if(piece != null && piece != chessboard.getSelectedPiece() && player == piece.getPlayer()) return;
moves[y][x] = true;
}
@ -226,7 +231,7 @@ public abstract class AbstractPiece implements IPiece {
while(i >= 0 && i < moves.length && j >= 0 && j < moves.length) {
setPossibleMove(moves, i, j);
IPiece piece = chessboard.getPiece(new PiecePosition(i, j));
if(piece != null && piece != chessboard.getFloatingPiece()) break;
if(piece != null && piece != chessboard.getSelectedPiece()) break;
i += xDirection;
j += yDirection;
}

View file

@ -44,7 +44,7 @@ public class Bishop extends AbstractPiece {
}
@Override
public boolean[][] getPossibleMoves(boolean theoretical) {
public boolean[][] getPossibleMoves(boolean attack) {
boolean[][] moves = new boolean[chessboard.SQUARE_COUNT][chessboard.SQUARE_COUNT];
int[] directions = new int[]{-1, 1};
for (int xDirection : directions) {

View file

@ -16,6 +16,7 @@ public class Chess {
okno.setTitle("Chess");
okno.setSize(800, 600);
okno.setMinimumSize(new Dimension(800, 600));
okno.setBackground(Color.GRAY);
Chessboard chessboard = new Chessboard();

View file

@ -43,9 +43,9 @@ public class Chessboard extends JPanel {
private double startY;
/**
* Instance of the floating piece
* Instance of the selected piece
*/
private IPiece floating;
private IPiece selected;
/**
* Two-dimensional array of pieces
@ -117,19 +117,17 @@ public class Chessboard extends JPanel {
g2.translate(startX, startY);
g2.scale(boardScale, boardScale);
boolean isBlack = true;
AffineTransform beforeSquares = g2.getTransform();
boolean isBlack = true;
for(int i=0; i<SQUARE_COUNT; i++) {
if(SQUARE_COUNT % 2 == 0) isBlack = !isBlack;
for(int j=0; j<SQUARE_COUNT; j++) {
g2.setTransform(beforeSquares);
if(isBlack) g2.setColor(Color.LIGHT_GRAY);
else g2.setColor(Color.WHITE);
isBlack = !isBlack;
g2.translate(i*SQUARE_SIZE, j*SQUARE_SIZE);
g2.fillRect(0, 0, SQUARE_SIZE, SQUARE_SIZE);
g2.fillRect(i*SQUARE_SIZE, j*SQUARE_SIZE, SQUARE_SIZE, SQUARE_SIZE);
}
}
@ -153,30 +151,27 @@ public class Chessboard extends JPanel {
}
g2.setTransform(beforeSquares);
AffineTransform beforePieces = g2.getTransform();
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] != floating) {
if(pieces[y][x] != null && !pieces[y][x].isFloating()) {
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(beforePieces);
g2.setTransform(beforeSquares);
}
}
}
if(floating != null) {
if(selected != null && selected.isFloating()) {
g2.setTransform(beforeBoard);
g2.translate(floating.getOverrideX(), floating.getOverrideY());
g2.translate(selected.getOverrideX(), selected.getOverrideY());
g2.scale(pieceScale * boardScale, pieceScale * boardScale);
floating.paint(g2);
selected.paint(g2);
}
g2.setTransform(beforeBoard);
@ -225,33 +220,22 @@ public class Chessboard extends JPanel {
}
/**
* Grab piece at specified position and mark it as floating
* @param pos piece position
* Set piece as selected
* @return piece
*/
public IPiece grabPiece(PiecePosition pos) {
if(!isOnBoard(pos.x, pos.y)) return null;
IPiece piece = getPiece(pos);
floating = piece;
return piece;
public void setSelectedPiece(IPiece piece) {
if(piece == null) {
selected.setOverride(0, 0);
}
selected = piece;
}
/**
* Get current floating piece
* Get current selected piece
* @return floating piece
*/
public IPiece getFloatingPiece() {
return floating;
}
/**
* Return piece at specified position to the board and unmark it from floating
*/
public void returnPiece() {
if(floating != null) {
floating.setOverride(0, 0);
}
floating = null;
public IPiece getSelectedPiece() {
return selected;
}
public boolean isEndangered(Player player, int x, int y) {
@ -301,7 +285,7 @@ public class Chessboard extends JPanel {
boolean[][] player2Area = new boolean[SQUARE_COUNT][SQUARE_COUNT];
for (IPiece[] pieces2 : pieces) {
for (IPiece piece : pieces2) {
if(piece != null && piece != floating) {
if(piece != null && piece != selected) {
if(piece.getPlayer() == player1) mergeCoverageAreas(player1Area, piece.getPossibleMoves(true));
if(piece.getPlayer() == player2) mergeCoverageAreas(player2Area, piece.getPossibleMoves(true));
}

View file

@ -1,3 +1,4 @@
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
@ -8,8 +9,6 @@ public class ChessboardMouseAdapter extends MouseAdapter {
long lastClicked;
IPiece selectedPiece;
boolean dragging;
/**
@ -49,8 +48,9 @@ public class ChessboardMouseAdapter extends MouseAdapter {
Chessboard c = (Chessboard) me.getSource();
PiecePosition pos = c.getPieceCoordinates(me.getX(), me.getY());
IPiece piece = c.getPiece(pos);
IPiece selectedPiece = c.getSelectedPiece();
if (piece != null && piece.getPlayer() == c.getActivePlayer() && selectedPiece != piece) {
selectedPiece = piece;
c.setSelectedPiece(piece);
c.generateCoverageAreas();
c.showPossibleMoves(piece.getPossibleMoves());
} else if(selectedPiece != null) {
@ -61,7 +61,7 @@ public class ChessboardMouseAdapter extends MouseAdapter {
if(c.getActivePlayer().inCheck()) System.out.println("Active player in check!");
}
c.showPossibleMoves(null);
selectedPiece = null;
c.setSelectedPiece(null);
}
c.getRootPane().repaint();
}
@ -71,25 +71,29 @@ public class ChessboardMouseAdapter extends MouseAdapter {
PiecePosition pos = c.getPieceCoordinates(me.getX(), me.getY());
IPiece piece = c.getPiece(pos);
if (piece != null && piece.getPlayer() == c.getActivePlayer()) {
c.grabPiece(pos);
c.setSelectedPiece(piece);
c.generateCoverageAreas();
c.showPossibleMoves(piece.getPossibleMoves());
c.getRootPane().repaint();
}
}
public void onDrag(MouseEvent me) {
Chessboard c = (Chessboard) me.getSource();
IPiece piece = c.getFloatingPiece();
IPiece piece = c.getSelectedPiece();
if (piece != null) {
double totalScale = c.pieceScale * c.boardScale;
piece.setOverride(me.getX() - 50 * totalScale, me.getY() - 50 * totalScale);
c.getRootPane().repaint();
c.getRootPane().repaint(getRepaintRectangle(piece.getOverrideX(), piece.getOverrideY(), totalScale));
double pieceX = me.getX();
double pieceY = me.getY();
piece.setOverride(pieceX - 50 * totalScale, pieceY - 50 * totalScale);
c.getRootPane().repaint(getRepaintRectangle(pieceX, pieceY, totalScale));
}
}
public void onDragEnd(MouseEvent me) {
Chessboard c = (Chessboard) me.getSource();
IPiece piece = c.getFloatingPiece();
IPiece piece = c.getSelectedPiece();
PiecePosition pos = c.getPieceCoordinates(me.getX(), me.getY());
if(piece != null) {
if(piece.getPossibleMoves()[pos.y][pos.x]) {
@ -99,10 +103,17 @@ public class ChessboardMouseAdapter extends MouseAdapter {
c.changeActivePlayer();
if(c.getActivePlayer().inCheck()) System.out.println("Active player in check!");
}
c.returnPiece();
c.setSelectedPiece(null);
}
c.showPossibleMoves(null);
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

@ -30,6 +30,12 @@ public interface IPiece {
*/
void setOverride(double x, double y);
/**
* Return true, if piece is floating
* @return floating state
*/
boolean isFloating();
/**
* Get piece's override X location
* @return override X location
@ -50,7 +56,7 @@ public interface IPiece {
boolean[][] getPossibleMoves();
boolean[][] getPossibleMoves(boolean theoretical);
boolean[][] getPossibleMoves(boolean attack);
PieceColor getColor();

View file

@ -38,7 +38,7 @@ public class King extends AbstractPiece {
}
@Override
public boolean[][] getPossibleMoves(boolean theoretical) {
public boolean[][] getPossibleMoves(boolean attack) {
boolean[][] moves = new boolean[chessboard.SQUARE_COUNT][chessboard.SQUARE_COUNT];
for(int i = x-1; i <= x+1; i++) {
for(int j = y-1; j <= y+1; j++) {

View file

@ -30,7 +30,7 @@ public class Knight extends AbstractPiece {
}
@Override
public boolean[][] getPossibleMoves(boolean theoretical) {
public boolean[][] getPossibleMoves(boolean attack) {
boolean[][] moves = new boolean[chessboard.SQUARE_COUNT][chessboard.SQUARE_COUNT];
int[] directions = new int[]{-1, 1};
boolean[] trueFalse = new boolean[]{false, true};

View file

@ -27,12 +27,12 @@ public class Pawn extends AbstractPiece {
}
@Override
public boolean[][] getPossibleMoves(boolean theoretical) {
public boolean[][] getPossibleMoves(boolean attack) {
boolean[][] moves = new boolean[chessboard.SQUARE_COUNT][chessboard.SQUARE_COUNT];
int directionY = player.getStartPosition() == StartPosition.TOP ? 1 : -1;
for(int i=-1; i<=1; i++) {
boolean isPieceThere = chessboard.getPiece(new PiecePosition(x+i, y+directionY)) != null;
if((i != 0 && (theoretical || isPieceThere)) || (i == 0 && (!theoretical && !isPieceThere))) setPossibleMove(moves, x+i, y+directionY);
if((i != 0 && (attack || isPieceThere)) || (i == 0 && (!attack && !isPieceThere))) setPossibleMove(moves, x+i, y+directionY);
}
boolean nextTwoPlacesEmpty = chessboard.getPiece(new PiecePosition(x, y+directionY*2)) == null && chessboard.getPiece(new PiecePosition(x, y+directionY)) == null;
if(moveCount == 0 && nextTwoPlacesEmpty) setPossibleMove(moves, x, y + directionY*2);

View file

@ -42,7 +42,7 @@ public class Queen extends AbstractPiece {
}
@Override
public boolean[][] getPossibleMoves(boolean theoretical) {
public boolean[][] getPossibleMoves(boolean attack) {
boolean[][] moves = new boolean[chessboard.SQUARE_COUNT][chessboard.SQUARE_COUNT];
int[] directions = new int[]{-1, 0, 1};
for (int xDirection : directions) {

View file

@ -30,7 +30,7 @@ public class Rook extends AbstractPiece {
}
@Override
public boolean[][] getPossibleMoves(boolean theoretical) {
public boolean[][] getPossibleMoves(boolean attack) {
boolean[][] moves = new boolean[chessboard.SQUARE_COUNT][chessboard.SQUARE_COUNT];
int[] directions = new int[]{-1, 0, 1};
for (int xDirection : directions) {