Я создал простой GUI, чтобы продемонстрировать, как использовать границу многоугольника в Swing GUI. Вот GUI.
Вы не можете видеть на картинке, но вы можете взять зеленый круг (игрока) с помощью мыши и перетащите его в любое место внутри голубого алмаза (границы). Код не позволит вам перетащить игрока за границу.
Вот что я сделал.
Я создал два класса моделей. Один для границы, а другой для игрока. Я использовал эту логическую модель для рисования в представлении и выполнения вычислений в слушателе мыши. Это приложение модель / вид / контроллер .
Я создал простой Swing GUI с панелью для рисования. Я рассчитал, где будет находиться начало овала, чтобы я мог сохранить центральную точку и радиус в модели.
Я создал класс слушателя мыши для прослушивания нажатия и отпускания мыши .
А вот и код. Надеюсь, не так много, чтобы объяснить. Класс Polygon имеет метод, содержащий проверку того, находится ли прямоугольник полностью внутри многоугольника. Я преобразовал круг в прямоугольник в слушателе, чтобы использовать этот метод.
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Polygon;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.geom.Rectangle2D;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.border.Border;
public class PolygonBoundary implements Runnable {
public static void main(String[] args) {
SwingUtilities.invokeLater(new PolygonBoundary());
}
private Boundary boundary;
private Dimension dpSize;
private Player player;
public PolygonBoundary() {
this.dpSize = new Dimension(400, 400);
Polygon polygon = new Polygon();
polygon.addPoint(200, 0);
polygon.addPoint(0, 200);
polygon.addPoint(200, 400);
polygon.addPoint(400, 200);
this.boundary = new Boundary(polygon, Color.BLUE);
this.player = new Player(200, 200, 24, Color.GREEN);
}
@Override
public void run() {
JFrame frame = new JFrame("Polygon Boundary");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
DrawingPanel drawingPanel =
new DrawingPanel(dpSize, boundary, player);
frame.add(drawingPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public class DrawingPanel extends JPanel {
private static final long serialVersionUID = 1L;
private Boundary boundary;
private Player player;
public DrawingPanel(Dimension size, Boundary boundary,
Player player) {
this.boundary = boundary;
this.player = player;
this.setPreferredSize(size);
Border border = BorderFactory.createLineBorder(
Color.BLACK, 4);
this.setBorder(border);
PlayerMotion playerMotion =
new PlayerMotion(this, boundary, player);
this.addMouseListener(playerMotion);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setColor(boundary.getColor());
g2d.setStroke(new BasicStroke(4f));
g2d.drawPolygon(boundary.getPolygon());
g2d.setColor(player.getColor());
Point center = player.getCenter();
int radius = player.getRadius();
int diameter = radius + radius;
g2d.drawOval(center.x - radius, center.y - radius,
diameter, diameter);
}
}
public class PlayerMotion implements MouseListener {
private Boundary boundary;
private JPanel panel;
private Player player;
private Point originalPoint;
public PlayerMotion(JPanel panel, Boundary boundary,
Player player) {
this.panel = panel;
this.boundary = boundary;
this.player = player;
}
@Override
public void mouseClicked(MouseEvent event) {
}
@Override
public void mousePressed(MouseEvent event) {
Point center = player.getCenter();
int radius = player.getRadius();
Rectangle2D r2d = createRectangle(center, radius);
if (r2d.contains(event.getPoint())) {
originalPoint = event.getPoint();
}
}
@Override
public void mouseReleased(MouseEvent event) {
if (originalPoint == null) {
return;
}
Point endPoint = event.getPoint();
Point center = player.getCenter();
int radius = player.getRadius();
int newX = center.x - originalPoint.x + endPoint.x;
int newY = center.y - originalPoint.y + endPoint.y;
Point newPoint = new Point(newX, newY);
Rectangle2D r2d = createRectangle(newPoint, radius);
Polygon polygon = boundary.getPolygon();
if (polygon.contains(r2d)) {
player.setCenter(newPoint);
panel.repaint();
}
originalPoint = null;
}
private Rectangle2D createRectangle(Point center, int radius) {
double dx = center.x - radius;
double dy = center.y - radius;
double d = radius + radius;
Rectangle2D r2d = new Rectangle2D.Double(dx, dy, d, d);
return r2d;
}
@Override
public void mouseEntered(MouseEvent event) {
}
@Override
public void mouseExited(MouseEvent event) {
}
}
public class Boundary {
private final Color color;
private final Polygon polygon;
public Boundary(Polygon polygon, Color color) {
this.polygon = polygon;
this.color = color;
}
public Polygon getPolygon() {
return polygon;
}
public Color getColor() {
return color;
}
}
public class Player {
private final int radius;
private final Color color;
private Point center;
public Player(int x, int y, int radius, Color color) {
this.center = new Point(x, y);
this.radius = radius;
this.color = color;
}
public int getRadius() {
return radius;
}
public Point getCenter() {
return center;
}
public void setCenter(Point center) {
this.center = center;
}
public Color getColor() {
return color;
}
}
}