I'm trying to animate a background in a JPanel, but after a few cycles the background starts to have this "smear" effect. I think it's because Java is constantly drawing over the previous image, but I can't seem to find a way to "Un-draw" the image.
我试图在JPanel中为背景设置动画,但在几个周期后,背景开始出现这种“拖影”效果。我认为这是因为Java不断地覆盖以前的图像,但我似乎无法找到一种“取消绘制”图像的方法。
Part of the Background class
Background类的一部分
public void setPosition(double x, double y) {
this.x = (x * moveScale) % GamePanel.WIDTH;
this.y = (y * moveScale) % GamePanel.HEIGHT;
}
public void setVector(double dx, double dy) {
this.dx = dx;
this.dy = dy;
}
public void update() {
x += dx % GamePanel.WIDTH;
y += dy % GamePanel.HEIGHT;
}
public void draw(Graphics2D g) {
g.drawImage(image, (int) x, (int) y, null);
if (x < 0) {
g.drawImage(image, (int) x + GamePanel.WIDTH, (int) y, null);
}
if (x > 0) {
g.drawImage(image, (int) x - GamePanel.WIDTH, (int) y, null);
}
}
Part of the Menu class where it gets called
调用它的Menu类的一部分
public void update() {
bg.update();
}
public void draw (Graphics2D g) {
bg.draw(g);
g.setColor(titleColor);
g.setFont(titleFont);
g.drawString("Save Squishy!", 80, 70);
g.setFont(font);
for (int i = 0; i < options.length; i++) {
if (i == currentChoice) {
g.setColor(Color.BLACK);
} else {
g.setColor(Color.RED);
}
g.drawString(options[i], 145, 140 + (i * 15));
}
}
Works fine for the first cycle:
适用于第一个周期:
Then starts to smear
然后开始涂抹
1 个解决方案
#1
1
In your example, you should use the paintComponent(g)
method that you override from a container-class like JPanel
instead of creating your own paint/draw method or using the graphical object obtained from an image. Like this, you avoid troubles with repainting, just call repaint()
on the class that extends JPanel.
在您的示例中,您应该使用从JPanel等容器类重写的paintComponent(g)方法,而不是创建自己的绘制/绘制方法或使用从图像获取的图形对象。像这样,你可以避免重新绘制的麻烦,只需在扩展JPanel的类上调用repaint()。
As mentioned in the comments, it is recommended to use the paintComponent(g)
method. Start with something like this:
如评论中所述,建议使用paintComponent(g)方法。从这样的事情开始:
public class TestImage extends JPanel {
private BufferedImage bimg = null;
public TestImage() {
// initiate the class ...
try {
bimg = ImageIO.read(new File("C:/Path/To/Image/image.jpg"));
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(bimg, 0, 0, null);
// do other painting stuff with g
}
public static void main(String[] args) {
JFrame fr = new JFrame("Image test demo");
fr.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
fr.setSize(600, 400);
fr.setLocationRelativeTo(null);
fr.add(new TestImage());
fr.setVisible(true);
}
}
#1
1
In your example, you should use the paintComponent(g)
method that you override from a container-class like JPanel
instead of creating your own paint/draw method or using the graphical object obtained from an image. Like this, you avoid troubles with repainting, just call repaint()
on the class that extends JPanel.
在您的示例中,您应该使用从JPanel等容器类重写的paintComponent(g)方法,而不是创建自己的绘制/绘制方法或使用从图像获取的图形对象。像这样,你可以避免重新绘制的麻烦,只需在扩展JPanel的类上调用repaint()。
As mentioned in the comments, it is recommended to use the paintComponent(g)
method. Start with something like this:
如评论中所述,建议使用paintComponent(g)方法。从这样的事情开始:
public class TestImage extends JPanel {
private BufferedImage bimg = null;
public TestImage() {
// initiate the class ...
try {
bimg = ImageIO.read(new File("C:/Path/To/Image/image.jpg"));
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(bimg, 0, 0, null);
// do other painting stuff with g
}
public static void main(String[] args) {
JFrame fr = new JFrame("Image test demo");
fr.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
fr.setSize(600, 400);
fr.setLocationRelativeTo(null);
fr.add(new TestImage());
fr.setVisible(true);
}
}