我正在尝试编写一个拼图游戏应用程序,在该应用程序中,图像被切成碎片,被打乱,并且用户必须通过拖放来重新排列它们以重新组装原始图像。 (如下所示:http://www.jigzone.com/puzzles/74055D549FF0?z=5)。
我必须用Graphics2d用Java编写。
因此,起初,我正在尝试制作某种可以显示图像一部分(现在为矩形)并可以用鼠标拖动的组件。
当只有一个这样的组件时,下面的代码可以很好地工作。问题是,当我添加第二个组件时,第一个组件不再可见。
我真的被困在这里。我有一种感觉,我真的缺少一些基本的东西。也许我走错了路。任何帮助将不胜感激。
编辑:我根据建议更改了一些代码,但是,仍然无法按预期工作。
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.MouseInputAdapter;
public class GraphicDragAndDrop extends JPanel {
Rectangle rect;
Image img;
public GraphicDragAndDrop(String imgFile, int x0, int y0){
rect = new Rectangle(x0, y0, 150, 75);
img = new ImageIcon(imgFile).getImage();
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setClip(rect);
int x = rect.x;
int y = rect.y;
g2d.drawImage(img, x, y, this);
}
public void setRect(int x, int y) {
rect.setLocation(x, y);
repaint();
}
public static void main(String[] args) {
// first piece
GraphicDragAndDrop piece1 = new GraphicDragAndDrop("a.png", 0, 0);
piece1.setRect(0, 0);
new GraphicDragController(piece1);
// second piece --> only this will be visible
GraphicDragAndDrop piece2 = new GraphicDragAndDrop("a.png", 200, 200);
//GraphicDragAndDrop piece2 = new GraphicDragAndDrop("b.png", 200, 200); // does'n work either
piece2.setRect(150, 150);
new GraphicDragController(piece2);
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(piece1);
f.add(piece2);
f.setSize(500,500);
f.setLocation(300,100);
f.setVisible(true);
}
}
class GraphicDragController extends MouseInputAdapter {
GraphicDragAndDrop component;
Point offset = new Point();
boolean dragging = false;
public GraphicDragController(GraphicDragAndDrop gdad) {
component = gdad;
component.addMouseListener(this);
component.addMouseMotionListener(this);
}
public void mousePressed(MouseEvent e) {
Point p = e.getPoint();
Rectangle r = component.rect;
if(r.contains(p)) {
offset.x = p.x - r.x;
offset.y = p.y - r.y;
dragging = true;
}
}
public void mouseReleased(MouseEvent e) {
dragging = false;
}
public void mouseDragged(MouseEvent e) {
if(dragging) {
int x = e.getX() - offset.x;
int y = e.getY() - offset.y;
component.setRect(x, y);
}
}
}
最佳答案
上面的代码仅用于绘制一张图像:
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setClip(rect);
int x = rect.x;
int y = rect.y;
// here
g2d.drawImage(new ImageIcon("a.png").getImage(), x, y, this);
}
如果需要绘制多个图像,请考虑创建图像集合并使用for循环遍历paintComponent中的集合:
同样,永远不要从paintComponent内读取图像,因为此方法应该精简,平均和快速,并且只涉及绘画。另外,您的程序每次绘制图像时都无需读取图像,因为这效率很低,并且会不必要地降低程序速度。而是在构造函数或类似的init方法中一次读取图像。
例如,
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
for (Image img: myImageCollection) {
g2d.drawImage(img, 0, 0, this);
}
}
编辑
您声明:
另外,我的计划是有更多的GraphicDragAndDrop类对象,每个对象都显示不同的原始图像。我的方法错了吗?
您可以使用组件,但是我感觉拖动图像很容易。我认为,例如,如果您希望您的程序具有此功能,旋转它们会更容易。如果不是,尽管一定要使用组件,但是如果您采用这种方法,我建议您使用JLabel并简单地设置其ImageIcon而不是拖动JPanels。
关于java - java 2d拼图应用程序,不能绘制多于一张,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/16424021/