2019-07-09 09:20:30 +02:00
|
|
|
package dev.kske.chess.ui;
|
|
|
|
|
2019-07-23 10:38:19 +02:00
|
|
|
import java.awt.BasicStroke;
|
2019-07-09 09:20:30 +02:00
|
|
|
import java.awt.Color;
|
|
|
|
import java.awt.Graphics;
|
2019-07-16 15:32:02 +02:00
|
|
|
import java.awt.Graphics2D;
|
|
|
|
import java.awt.Point;
|
|
|
|
import java.awt.Polygon;
|
|
|
|
import java.awt.Shape;
|
|
|
|
import java.awt.geom.AffineTransform;
|
2019-07-09 09:20:30 +02:00
|
|
|
import java.util.ArrayList;
|
|
|
|
import java.util.List;
|
|
|
|
|
|
|
|
import javax.swing.JComponent;
|
|
|
|
|
2019-07-16 15:32:02 +02:00
|
|
|
import dev.kske.chess.board.Move;
|
2019-07-09 09:20:30 +02:00
|
|
|
import dev.kske.chess.board.Position;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Project: <strong>Chess</strong><br>
|
|
|
|
* File: <strong>OverlayComponent.java</strong><br>
|
|
|
|
* Created: <strong>08.07.2019</strong><br>
|
|
|
|
* Author: <strong>Kai S. K. Engelbart</strong>
|
|
|
|
*/
|
|
|
|
public class OverlayComponent extends JComponent {
|
|
|
|
|
|
|
|
private static final long serialVersionUID = -7326936060890082183L;
|
|
|
|
|
|
|
|
private final BoardPane boardPane;
|
|
|
|
|
2019-07-27 08:06:43 +02:00
|
|
|
private List<Position> dots;
|
|
|
|
private Move arrow;
|
2019-07-09 09:20:30 +02:00
|
|
|
|
|
|
|
public OverlayComponent(BoardPane boardPane) {
|
|
|
|
this.boardPane = boardPane;
|
2019-07-16 15:32:02 +02:00
|
|
|
dots = new ArrayList<>();
|
2019-07-27 09:34:40 +02:00
|
|
|
setSize(boardPane.getPreferredSize());
|
2019-07-09 09:20:30 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected void paintComponent(Graphics g) {
|
|
|
|
super.paintComponent(g);
|
|
|
|
|
|
|
|
final int tileSize = getTileSize();
|
2019-07-16 15:32:02 +02:00
|
|
|
|
2019-07-27 08:06:43 +02:00
|
|
|
// Draw an arrow representing the last move and mark its position and
|
|
|
|
// destination
|
2019-07-16 15:32:02 +02:00
|
|
|
if (arrow != null) {
|
2019-07-27 08:06:43 +02:00
|
|
|
Point pos = new Point(arrow.pos.x * tileSize + tileSize / 2, arrow.pos.y * tileSize + tileSize / 2);
|
|
|
|
Point dest = new Point(arrow.dest.x * tileSize + tileSize / 2, arrow.dest.y * tileSize + tileSize / 2);
|
|
|
|
|
2019-07-23 10:38:19 +02:00
|
|
|
Graphics2D g2d = (Graphics2D) g;
|
|
|
|
g2d.setStroke(new BasicStroke(3));
|
|
|
|
|
|
|
|
g2d.setColor(Color.yellow);
|
|
|
|
g2d.drawRect(arrow.pos.x * tileSize, arrow.pos.y * tileSize, tileSize, tileSize);
|
|
|
|
g2d.drawRect(arrow.dest.x * tileSize, arrow.dest.y * tileSize, tileSize, tileSize);
|
|
|
|
|
|
|
|
Shape arrowShape = createArrowShape(pos, dest);
|
2019-07-16 15:32:02 +02:00
|
|
|
g.setColor(new Color(255, 0, 0, 127));
|
2019-07-23 10:38:19 +02:00
|
|
|
g2d.fill(arrowShape);
|
|
|
|
g2d.setColor(Color.black);
|
|
|
|
g2d.draw(arrowShape);
|
2019-07-16 15:32:02 +02:00
|
|
|
}
|
2019-07-27 08:06:43 +02:00
|
|
|
|
|
|
|
// Draw possible moves if a piece was selected
|
|
|
|
if (!dots.isEmpty()) {
|
|
|
|
g.setColor(Color.green);
|
|
|
|
int radius = tileSize / 4;
|
|
|
|
for (Position dot : dots)
|
|
|
|
g.fillOval(dot.x * tileSize + tileSize / 2 - radius / 2,
|
|
|
|
dot.y * tileSize + tileSize / 2 - radius / 2,
|
|
|
|
radius,
|
|
|
|
radius);
|
|
|
|
}
|
2019-07-16 15:32:02 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
private Shape createArrowShape(Point pos, Point dest) {
|
|
|
|
Polygon arrowPolygon = new Polygon();
|
|
|
|
arrowPolygon.addPoint(-6, 1);
|
|
|
|
arrowPolygon.addPoint(3, 1);
|
|
|
|
arrowPolygon.addPoint(3, 3);
|
|
|
|
arrowPolygon.addPoint(6, 0);
|
|
|
|
arrowPolygon.addPoint(3, -3);
|
|
|
|
arrowPolygon.addPoint(3, -1);
|
|
|
|
arrowPolygon.addPoint(-6, -1);
|
|
|
|
|
|
|
|
Point midPoint = midpoint(pos, dest);
|
|
|
|
|
2019-07-27 08:06:43 +02:00
|
|
|
double rotate = Math.atan2(dest.y - pos.y, dest.x - pos.x);
|
|
|
|
double ptDistance = pos.distance(dest);
|
|
|
|
double scale = ptDistance / 12.0; // 12 because it's the length of the arrow
|
|
|
|
// polygon.
|
2019-07-16 15:32:02 +02:00
|
|
|
|
|
|
|
AffineTransform transform = new AffineTransform();
|
|
|
|
|
|
|
|
transform.translate(midPoint.x, midPoint.y);
|
|
|
|
transform.rotate(rotate);
|
|
|
|
transform.scale(scale, 5);
|
|
|
|
|
|
|
|
return transform.createTransformedShape(arrowPolygon);
|
|
|
|
}
|
|
|
|
|
|
|
|
private Point midpoint(Point p1, Point p2) {
|
|
|
|
return new Point((int) ((p1.x + p2.x) / 2.0), (int) ((p1.y + p2.y) / 2.0));
|
2019-07-09 09:20:30 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
public void displayDots(List<Position> dots) {
|
|
|
|
this.dots.clear();
|
|
|
|
this.dots.addAll(dots);
|
|
|
|
repaint();
|
|
|
|
}
|
|
|
|
|
|
|
|
public void clearDots() {
|
|
|
|
dots.clear();
|
|
|
|
repaint();
|
|
|
|
}
|
|
|
|
|
2019-07-16 15:32:02 +02:00
|
|
|
public void displayArrow(Move arrow) {
|
|
|
|
this.arrow = arrow;
|
|
|
|
repaint();
|
|
|
|
}
|
|
|
|
|
|
|
|
public void clearArrow() {
|
|
|
|
arrow = null;
|
|
|
|
repaint();
|
|
|
|
}
|
|
|
|
|
2019-07-27 08:06:43 +02:00
|
|
|
public int getTileSize() { return boardPane.getTileSize(); }
|
2019-07-09 09:20:30 +02:00
|
|
|
}
|