java 使用鼠标移动多边形形状拖动

6rqinv9w  于 2022-12-02  发布在  Java
关注(0)|答案(1)|浏览(148)

我正在写一个五联骨牌游戏,但是移动棋子时出现了问题。形状移动了,但是每次移动的多边形边界的坐标实际上并不对应于多边形边界,移动形状变得不可能。
我就是这么做的:

import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.util.ArrayList;

public class MyPanel extends JFrame implements MouseListener, MouseMotionListener {
    Boolean isPressed = false;
    JPanel mainPane;
    Container contentPane;
    Point offset;
    ArrayList<Polygon> polygons = new ArrayList<Polygon>();
    Polygon fig1 = new Polygon(new int[]{50, 90, 90, 50}, new int[]{50, 50, 200, 200}, 4);
    Polygon fig2 = new Polygon(new int[]{170, 250, 250, 210, 210, 170, 170, 130, 130, 170}, new int[]{80, 80, 120, 120, 200, 200, 160, 160, 120, 120}, 10);
    Polygon fig3 = new Polygon(new int[]{370, 410, 410, 330, 330, 370}, new int[]{90, 90, 200, 200, 160, 160}, 6);
    /*Polygon fig4 = new Polygon(new int[]{50, 90, 90, 50}, new int[]{50, 50, 200, 200}, 4);
    Polygon fig5 = new Polygon(new int[]{50, 90, 90, 50}, new int[]{50, 50, 200, 200}, 4);
    Polygon fig6 = new Polygon(new int[]{50, 90, 90, 50}, new int[]{50, 50, 200, 200}, 4);
    Polygon fig7 = new Polygon(new int[]{50, 90, 90, 50}, new int[]{50, 50, 200, 200}, 4);
    Polygon fig8 = new Polygon(new int[]{50, 90, 90, 50}, new int[]{50, 50, 200, 200}, 4);
    Polygon fig9 = new Polygon(new int[]{50, 90, 90, 50}, new int[]{50, 50, 200, 200}, 4);
    Polygon fig10 = new Polygon(new int[]{50, 90, 90, 50}, new int[]{50, 50, 200, 200}, 4);
    Polygon fig11 = new Polygon(new int[]{50, 90, 90, 50}, new int[]{50, 50, 200, 200}, 4);
    Polygon fig12 = new Polygon(new int[]{50, 90, 90, 50}, new int[]{50, 50, 200, 200}, 4);*/
    int x, y;

    MyPanel(){
        polygons.add(fig1);
        polygons.add(fig2);
        polygons.add(fig3);

        mainPane = new JPanel(){
            public void paintComponent(Graphics g){
                super.paintComponent(g);
                Graphics2D g2 = (Graphics2D) g;

                for(Shape fig: polygons){
                    g2.setColor(Color.BLUE);
                    g2.fill(fig);
                }
            }
        };

        contentPane = this.getContentPane();
        contentPane.add(mainPane);
        mainPane.setLayout(null);

        setVisible(true);
        setSize(1000, 600);
        setResizable(false);
        setLocationRelativeTo(null);
        setDefaultCloseOperation(EXIT_ON_CLOSE);

        mainPane.addMouseListener(this);
        mainPane.addMouseMotionListener(this);
    }

    public void mousePressed(MouseEvent e) {
        for(Polygon polygon: polygons) {
            if (polygon.getBounds().contains(e.getPoint())) {
               //offset = new Point(e.getPoint().x - polygon.getBounds().x, e.getPoint().y - polygon.getBounds().y);
                x = e.getX();
                y = e.getY();
            }
        }
    }

    public void mouseClicked(MouseEvent e){}
    public void mouseReleased(MouseEvent e){}
    public void mouseEntered(MouseEvent e){}
    public void mouseExited(MouseEvent e){}

    public void mouseDragged(MouseEvent e) {
        if(e.getSource() == mainPane) {
            for(Polygon polygon: polygons) {
                if (polygon.getBounds().contains(x, y)) {
                    int dx = e.getX() - x;
                    int dy = e.getY() - y;
                    for (int i = 0; i < polygon.npoints; i++) {
                        polygon.xpoints[i] += dx;
                        polygon.ypoints[i] += dy;
                        repaint();
                    }
                    x += dx;
                    y += dy;
                }
            }
        }
    }
    public void mouseMoved(MouseEvent e){}
}

我明白问题出在这里:

public void mouseDragged(MouseEvent e) {
        if(e.getSource() == mainPane) {
            for(Polygon polygon: polygons) {
                if (polygon.getBounds().contains(x, y)) {
                    int dx = e.getX() - x;
                    int dy = e.getY() - y;
                    for (int i = 0; i < polygon.npoints; i++) {
                        polygon.xpoints[i] += dx;
                        polygon.ypoints[i] += dy;
                        repaint();
                    }
                    x += dx;
                    y += dy;
                }
            }
        }
    }

但是我不明白怎么解决,请告诉我是什么问题。

0s0u357o

0s0u357o1#

问题

Polygon类存储计算的边界框(Rectangle的示例),因此不必在每次需要时重新计算它。如果直接更改Polygon的坐标(xpointsypoints),则不会重新计算缓存的边界框。

溶液:

1.使用Polygon的translate()方法转换其点-它将清除缓存的边界框,强制重新计算边界框;
1.在更改所有点之后,使用Polygoninvalidate()方法删除缓存的边界框并强制其重新计算。
IMO第一点应优先考虑:不需要循环,更好地描述了意图。
备注:

  • 不需要为循环内的每个改变的坐标点调用repaint()-在所有点whee moved 之后调用一次就足够了-使用translate,根本不需要循环,但是repaint()仍然必须被调用一次;
  • 我还将创建一个字段来存储在mousePressed方法中单击的Polygon,并且只在拖动鼠标时移动该Polygon;
  • 恕我直言,将坐标和npoints声明为public是错误的!

相关问题