2012-12-03 49 views
0

我想制作一个物体来打开嘴巴,并使用两个快速切换的图像关闭它。我尝试了一个for循环,但它滞后于我的游戏。快速切换两个图像?

if(direction == Constant.UP){ 

     ImageIcon i = new ImageIcon("src\\images\\pacman up.png"); 
     image = i.getImage(); 

     ImageIcon i2 = new ImageIcon("src\\images\\pacman left.png"); 
     image = i2.getImage(); 

     } 
G.drawImage(image, x, y, 20,20,null); 
+0

这还不够。 *“我尝试了一个for循环”*担心我应该实际上阻止用户界面,但它听起来像你正在使用某个线程... – MadProgrammer

+0

1)为了更好地帮助,请发布[SSCCE](http ://sscce.org/)。 2)但作为一般技巧,构建组件实例时加载图像并将它们存储为类级别属性。 3)如果'G'是一个图形实例,它应该被称为'g'。此外,如果它来自一个组件,它将有一个'ImageObserver' - 所以'g.drawImage(image,x,y,20,20,this);'。 –

回答

0

每次都不会创建图标。在启动时创建两个映像,并在运行时切换回 。

if(direction == Constant.UP){ 
    image = open; 
}else { 
    image = closed; 
} 

G.drawImage(image, x, y, 20,20,null); 
+1

如果'G'来自一个组件,它将会有一个ImageObserver - 所以'G.drawImage(image,x,y,20,20,this);'。 –

+1

甚至更​​好:'g.drawImage(direction == Constant.UP?open:closed,x,y,20,20,null);' – Doorknob

+0

terniary表达式让我感到冷。我更喜欢其他的。 – BevynQ

3

Swing中的任何动画都需要考虑Event Dispatching Thread

您应该永远不要在可能阻止它的EDT内容中执行任何操作(例如循环或I/O),因为这会阻止EDT(除其他之外)处理绘制请求。

你总是应该使用能够支持双缓冲的表面,如JPanel,因为这将有助于消除闪烁

下面以javax.swing.Timer两幅图像之间进行切换...

enter image description hereenter image description here

public class TestPacMan { 

    public static void main(String[] args) { 
     new TestPacMan(); 
    } 

    public TestPacMan() { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
       } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { 
       } 

       JFrame frame = new JFrame(); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame.setLayout(new BorderLayout()); 
       frame.add(new PacManPane()); 
       frame.pack(); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 
      } 
     }); 
    } 

    public class PacManPane extends JPanel { 

     private BufferedImage pacOpened; 
     private BufferedImage pacClosed; 
     private BufferedImage frame; 
     private boolean opened = true; 

     public PacManPane() { 
      try { 
       pacOpened = ImageIO.read(new File("PC-Closed.png")); 
       pacClosed = ImageIO.read(new File("PC-Opened.png")); 
       frame = pacOpened; 
      } catch (IOException exp) { 
       exp.printStackTrace(); 
      } 

      Timer timer = new Timer(500, new ActionListener() { 
       @Override 
       public void actionPerformed(ActionEvent e) { 
        opened = !opened; 
        frame = opened ? pacOpened : pacClosed; 
        repaint(); 
       } 
      }); 
      timer.setRepeats(true); 
      timer.setCoalesce(true); 
      timer.start(); 

     } 

     @Override 
     public Dimension getPreferredSize() { 
      return new Dimension(500, 500); 
     } 

     @Override 
     protected void paintComponent(Graphics g) { 
      super.paintComponent(g); 
      Graphics2D g2d = (Graphics2D) g.create(); 
      if (frame != null) { 
       int x = (getWidth() - frame.getWidth())/2; 
       int y = (getHeight() - frame.getHeight())/2; 
       g2d.drawImage(frame, x, y, this); 
      } 
      g2d.dispose(); 
     } 

    } 

}