我正在尝试编写一个拼图游戏应用程序,在该应用程序中,图像被切成碎片,被打乱,并且用户必须通过拖放来重新排列它们以重新组装原始图像。 (如下所示: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/

10-14 12:27
查看更多