Splitted floating and selected pieces, improved drag performance
This commit is contained in:
parent
50ba504505
commit
642d4e718b
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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++) {
|
||||
|
|
|
@ -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};
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in a new issue