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);
4

2 回答 2

3

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

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

您应该始终使用能够支持双缓冲的表面,例如JPanel这将有助于消除闪烁

下面使用 ajavax.swing.Timer在两个图像之间切换...

在此处输入图像描述在此处输入图像描述

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

    }

}
于 2012-12-03T03:19:38.973 回答
0

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

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

G.drawImage(image, x, y, 20,20,null);
于 2012-12-03T01:57:56.680 回答