Java2D在移动图像后删除旧像素? [英] Java2D removing old pixels after moving image?

查看:22
本文介绍了Java2D在移动图像后删除旧像素?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我在 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 上绘画.相反,使用 JPanelJComponent 的扩展.用于绘制覆盖 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在移动图像后删除旧像素?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆