Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/392.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在两个图像之间快速切换?_Java_Image - Fatal编程技术网

Java 在两个图像之间快速切换?

Java 在两个图像之间快速切换?,java,image,Java,Image,我想用两张快速切换的图像来制作一个对象,让它张开嘴并合上嘴。我尝试了一个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"

我想用两张快速切换的图像来制作一个对象,让它张开嘴并合上嘴。我尝试了一个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);

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

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

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

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

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

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

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

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

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

下面使用
javax.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();
        }

    }

}


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

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

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

下面使用
javax.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();
        }

    }

}


这还不够。“我试过使用for循环”让我担心,因为这实际上会阻塞UI,但听起来你好像在某处使用线程……1)为了更快地获得更好的帮助,请发布一条消息。2) 但是作为一般提示,在构建组件实例时加载图像并将其存储为类级属性。3) 如果
G
是图形实例,则应将其称为
G
。此外,如果它来自一个组件,它将有一个
ImageObserver
-so
g.drawImage(图像,x,y,20,20,这个)。这还不够。“我试过使用for循环”让我担心,因为这实际上会阻塞UI,但听起来你好像在某处使用线程……1)为了更快地获得更好的帮助,请发布一条消息。2) 但是作为一般提示,在构建组件实例时加载图像并将其存储为类级属性。3) 如果
G
是图形实例,则应将其称为
G
。此外,如果它来自一个组件,它将有一个
ImageObserver
-so
g.drawImage(图像,x,y,20,20,这个)
。如果
G
来自一个组件,它将有一个ImageObserver-so
G.drawImage(图像,x,y,20,20,这个)
。甚至更好:
g.drawImage(方向==Constant.UP?打开:关闭,x,y,20,20,null)G
来自一个组件,它将有一个ImageObserver-so
G.drawImage(图像,x,y,20,20,这个)
。甚至更好:
g.drawImage(方向==Constant.UP?打开:关闭,x,y,20,20,null)