问题描述
所以我在 Java2D 中移动图像,它也会反弹.出于某种原因,它总是会留下一串旧图像.我该如何解决这个问题?
So I'm moving an image in Java2D and it bounces aswell. For some reason, it always leaves behind a trail of old images. How could I fix this?
主类:
package org.main.graphics;
import java.awt.Graphics;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import org.main.entity.Entity;
import org.main.entity.Loael;
@SuppressWarnings("serial")
public class GameWindow extends JFrame implements Runnable {
private List<Entity> entities = new ArrayList<Entity>();
private Thread animator;
public GameWindow() throws IOException {
super("Game");
setSize(640, 480);
setVisible(true);
setResizable(false);
setLocationRelativeTo(null);
revalidate();
entities.add(new Loael(500, 400));
animator = new Thread(this);
animator.start();
}
public void paint(Graphics g) {
for (Entity entity : entities) {
try {
g.drawImage(entity.getImage(), entity.getX(), entity.getY(),
this);
} catch (IOException e) {
e.printStackTrace();
}
}
}
@Override
public void run() {
while (true) {
for (Entity entity : entities) {
entity.animate(getBounds());
repaint();
}
try {
Thread.sleep(1);
} catch (InterruptedException e) {
}
}
}
}
错误示例:
推荐答案
不要直接在 JFrame
上绘画.相反,使用 JPanel
或 JComponent
的扩展.用于绘制覆盖 paintComponent()
而不是 paint()
.不要忘记调用super.paintComponent(g);
,否则你会遇到和你的例子一样的行为——之前的drawImage()
结果没有被清除轨迹依然存在.
Don't paint directly on JFrame
. Instead, use JPanel
or extension of JComponent
. For painting override paintComponent()
rather than paint()
. Don't forget to call super.paintComponent(g);
, otherwise you will encounter the same behavior as in your example - the previous result of drawImage()
is not cleared and the trail remains.
查看执行自定义绘画教程,以及仔细查看绘制机制部分,了解更多详细信息.
Take a look at Performing Custom Painting tutorial, and Closer Look at the Paint Mechanism section in particular, for more details.
考虑以下使用 Swing 计时器在 JPanel
中为图像设置动画的示例:
Consider the following example that animates image in JPanel
using Swing timer:
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.*;
public class AnimateDemo {
private static void createAndShowUI() {
try {
Image image = ImageIO.read(new URL(
"http://duke.kenai.com/iconSized/duke.gif"));
final MyPanel panel = new MyPanel(image);
JFrame frame = new JFrame("AnimateDemo");
frame.getContentPane().add(panel);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
ActionListener timerAction = new ActionListener() {
public void actionPerformed(ActionEvent evt) {
panel.animate();
}
};
Timer timer = new Timer(10, timerAction);
timer.setRepeats(true);
timer.start();
} catch (IOException e) {
e.printStackTrace();
}
}
static class MyPanel extends JPanel {
private Image image;
private int coordinateX = 0;
private int coordinateY = 0;
private boolean incrementX = true;
private boolean incrementY = true;
public MyPanel(Image image) {
this.image = image;
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (image != null) {
g.drawImage(image, coordinateX, coordinateY, this);
}
}
@Override
public Dimension getPreferredSize() {
return new Dimension(300, 300);
}
public void animate() {
if (image != null) {
if (image.getWidth(this) + coordinateX > getWidth()) {
incrementX = false;
}
if (coordinateX < 0) {
incrementX = true;
}
if (incrementX)
coordinateX++;
else
coordinateX--;
if (image.getHeight(null) + coordinateY > getHeight()) {
incrementY = false;
}
if (coordinateY < 0) {
incrementY = true;
}
if (incrementY)
coordinateY++;
else
coordinateY--;
repaint();
}
}
}
public static void main(String[] args) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
createAndShowUI();
}
});
}
}
这篇关于Java2D在移动图像后删除旧像素?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!