我正在写一个五联骨牌游戏,但是移动棋子时出现了问题。形状移动了,但是每次移动的多边形边界的坐标实际上并不对应于多边形边界,移动形状变得不可能。
我就是这么做的:
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;
}
}
}
}
但是我不明白怎么解决,请告诉我是什么问题。
1条答案
按热度按时间0s0u357o1#
问题
Polygon
类存储计算的边界框(Rectangle
的示例),因此不必在每次需要时重新计算它。如果直接更改Polygon的坐标(xpoints
和ypoints
),则不会重新计算缓存的边界框。溶液:
1.使用Polygon的
translate()
方法转换其点-它将清除缓存的边界框,强制重新计算边界框;或1.在更改所有点之后,使用
Polygon
的invalidate()
方法删除缓存的边界框并强制其重新计算。IMO第一点应优先考虑:不需要循环,更好地描述了意图。
备注:
repaint()
-在所有点whee moved 之后调用一次就足够了-使用translate
,根本不需要循环,但是repaint()
仍然必须被调用一次;mousePressed
方法中单击的Polygon,并且只在拖动鼠标时移动该Polygon;npoints
声明为public
是错误的!