1

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

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

    }
4

1 回答 1

1

因此,您遇到的第一个问题是资源问题。

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

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

期待一个"./stand.png"不存在的文件。相反,您需要通过Class#getResourceAPI 加载资源...

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

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

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

您需要某种 x/y 值来告诉图像应该在哪里绘制。在调用之前,您可以通过线程内的给定 x/y 增量修改这些值repaint...

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

当我步履蹒跚时……我个人会推荐ImageIOover Toolkit#createImageor ImageIcon,主要是因为它支持更多格式,但也因为它会Exception在由于某种原因无法读取图像时抛出错误……

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

使用 Swing 示例更新

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

在此处输入图像描述

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

}
于 2013-08-21T07:44:25.667 回答