Java2D移动图像后删除旧像素?

时间:2012-09-08 16:16:17

标签: java swing 2d paint java-2d

所以我在Java2D中移动图像并且它也会反弹。出于某种原因,它总是留下旧图像的痕迹。我怎么能解决这个问题?

主要课程:

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) {
                        }
                }
        }
}

错误的例子:

enter image description here

1 个答案:

答案 0 :(得分:2)

不要直接在JFrame上画画。相反,请使用JPanelJComponent的扩展名。用于绘制覆盖paintComponent()而不是paint()。不要忘记调用super.paintComponent(g);,否则您将遇到与示例中相同的行为 - drawImage()的先前结果未被清除且路径仍然存在。

有关更多详细信息,请查看Performing Custom Painting教程和Closer Look at the Paint Mechanism部分。

考虑以下使用Swing计时器在JPanel中动画图像的示例:

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();
            }
        });
    }
}