图像动画未显示

时间:2013-08-21 07:11:56

标签: java animation awt frame paint

我有以下代码。我想在一段时间延迟之后在屏幕上的小鸡数组中显示图像。坐标必须移动 10px  图片已加载。我想知道我可以在此代码中添加哪些附加代码片段,以便在我的Frame上使用我拥有的两个图像制作动画.Below是我的代码:

 import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.Frame;
    import java.awt.Graphics;
    import java.awt.Image;
    import java.awt.Toolkit;


    public class Chicken extends Frame implements Runnable{
        Thread animation;
        long frameDelay = 3000;
        Image chick[] = new Image[2];
        int numFrames = chick.length;
        Toolkit tk = getToolkit();
        public Chicken()
        {
            setSize(new Dimension(300,300));
            setVisible(true);
            setBackground(Color.BLACK);
            animation = new Thread(this);
            chick[0] = tk.createImage("stand.png");
            chick[1] = tk.createImage("walk.png");
            animation.start();
            //setVisible(false);

        }
        public void paint(Graphics g)
        {
            g.drawImage(chick[0],100,100,null );
        }
        @Override
        public void run() {
            // TODO Auto-generated method stub
            repaint();
            try {
                Thread.sleep(frameDelay);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

        }
        public static void main(String args[])
        {
            Chicken instance = new Chicken();
        }

    }

1 个答案:

答案 0 :(得分:1)

所以,你遇到的第一个问题是资源问题。

存储在应用程序内部的资源(通常称为嵌入式资源)无法像外部资源一样加载。

chick[0] = tk.createImage("stand.png");

期望文件"./stand.png"不存在。相反,您需要通过Class#getResource API ...

加载资源
chick[0] = tk.createImage(getClass().getResource("/stand.png"));

您将面临的第二个问题是您正在覆盖顶级容器的paint。这真的不应该这样做。让我们从它不是双重缓冲的事实开始,并以框架具有位于可视区域内的装饰为结束。这意味着装饰将重叠你在表面上绘制的东西......不漂亮......

第三个问题是你没有告诉图像它应该移动到哪里。这是静态的。

您需要某种x / y值来告诉图像应该在哪里绘制。在调用repaint ...

之前,您可以在线程内按给定的x / y delta修改这些值

您可能遇到的第四个问题是您正在使用AWT ...这有点过时了。 Swing会为你解决你的双缓冲问题...恕我直言,会做出更好的选择 - 现在有很多关于Swing铺设的文档和示例;)

当我在蹒跚骑马的时候...我个人会推荐ImageIO超过Toolkit#createImageImageIcon,主要是因为它支持更多格式,但也因为它会当由于某种原因无法读取图像时抛出Exception ...

我有一个简单的例子,如果Swing,但我不会发布它,因为我会因为运行主题而遇到麻烦...如果你想看到它,请告诉我

已更新为Swing示例

这使用默认包中的嵌入图像...

enter image description here

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class ChickenDance {

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

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

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

    public class TestPane extends JPanel {

        private BufferedImage chicken;
        private int xPos;
        private int yPos;

        private int xDelta = 4;

        public TestPane() {
            try {
                chicken = ImageIO.read(getClass().getResource("/Chicken.png"));
            } catch (IOException ex) {
                Logger.getLogger(ChickenDance.class.getName()).log(Level.SEVERE, null, ex);
            }

            Timer timer = new Timer(40, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    xPos += xDelta;
                    if (xPos + chicken.getWidth() > getWidth()) {
                        xPos = getWidth() - chicken.getWidth();
                        xDelta *= -1;
                    } else if (xPos < 0) {
                        xPos = 0;
                        xDelta *= -1;
                    }
                    yPos = (getHeight() - chicken.getHeight()) / 2;
                    repaint();
                }
            });
            if (chicken != null) {
                timer.start();
            }
        }

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

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            if (chicken != null) {
                Graphics2D g2d = (Graphics2D) g.create();
                g2d.drawImage(chicken, xPos, yPos, this);
                g2d.dispose();
            }
        }
    }

}