2012-09-08 46 views
1

所以我在Java2D中移動了一個圖像,並且它彈跳了。出於某種原因,它總是留下一些舊圖像。我怎麼能解決這個問題?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

回答

2

不要JFrame直接作畫。相反,請使用JPanelJComponent的擴展名。對於繪畫覆蓋paintComponent()而不是paint()。不要忘記撥打super.paintComponent(g);,否則您將遇到與您的示例中相同的行爲 - drawImage()的先前結果未被清除,並且線索仍然存在。

請參閱Performing Custom Painting教程和Closer Look at the Paint Mechanism部分以瞭解更多詳情。

考慮下面的例子,使用搖擺定時器在動畫圖像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(); 
      } 
     }); 
    } 
}