如何移动图像(动画)? [英] How to move an image (animation)?

查看:133
本文介绍了如何移动图像(动画)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正试图在x轴上移动船(没有键盘)。如何将运动/动画与 boat.png 相关联,而不是与任何其他图像相关?

I'm trying to move the boat on the x-axis (without the keyboard yet). How can I relate the movement/ animation to the boat.png and not to any other image?

public class Mama extends Applet implements Runnable {

int width, height;
int x = 200;
int y = 200;
int dx = 1;
Image img1, img2, img3, img4;

@Override
public void init(){
    setSize(627, 373);
    Thread t = new Thread(this);
    img1 = getImage(getCodeBase(),"Background.png");
    img2 = getImage(getCodeBase(), "boat.png");
    img3 = getImage(getCodeBase(), "LeftPalm.png");
    img4 = getImage(getCodeBase(), "RightPalm.png");

}

@Override 
public void paint(Graphics g){
    g.drawImage(img1, 0, 0, this);
    g.drawImage(img2, 200, 200, this);
    g.drawImage(img3, 40, 100, this);
    g.drawImage(img4, 450, 130, this);
}

@Override
public void run() {
    while(true){

        x += dx;
        repaint();
        try {
           Thread.sleep(17);
        } catch (InterruptedException e) {
             System.out.println("Thread generates an error.");
        }
    }
  }
} 


推荐答案

有一些事情很突出...

There are a few things that stand out...

如前所述,您需要为图像绘制过程提供变量参数。 g.drawImage(img2,x,y,this); ,这将允许您定义图像的绘制位置。

As has already been stated, you need to supply variable arguments to the image drawing process. g.drawImage(img2, x, y, this);, this will allow you define where the image should be painted.

虽然你已经实现了 Runnable ,但你实际上并没有启动任何线程来调用它。这意味着,实际上没有任何东西在改变变量。

While you've implemented Runnable, you've actually not started any threads to call it. This means, nothing is actually changing the variables.

在你的 start 方法中,你应该调用类似 new Thread(this).start()

In you start method, you should be calling something like new Thread(this).start().

虽然您已将问题标记为Swing,但您使用的是AWT组件。这是不推荐的(实际上小程序通常不鼓励,因为它们很麻烦 - 恕我直言)。另一个问题,就像你很快就会发现的那样,它们不是双缓冲的,这通常会在执行动画时导致闪烁,这是不可取的。

Although you've tagged the question as Swing, you're using AWT components. This isn't recommended (in fact applets are generally discouraged as they are troublesome - IMHO). The other problem, as you are bound to find out shortly, is they are not double buffered, this generally leads to flickering when performing animation, which isn't desirable.

另外,我们也不鼓励覆盖 Applet 等顶级容器的 paint 方法。顶级容器往往包含许多其他组件,通过覆盖这样的 paint 方法,您可以销毁此设置。此外,顶级容器也不倾向于双缓冲。

As a side note, it is also discouraged to override the paint method of top level containers like Applet. Top level containers tend to contain a number additional components, by overriding the paint method like this, you destroy this setup. Also, top level containers don't tend to be double buffered either.

以下示例使用 JFrame ,但是将它转换为使用 JApplet (只需将 AnimationPanel 放到它上面就不会花费太多。另一个原因是,通常不鼓励从顶级容器扩展;)

The example below uses a JFrame, but it wouldn't take much to convert it to use a JApplet (just drop the AnimationPanel on to it. This is another reason why extending from top level containers is generally discouraged ;)

public class AnimatedBoat {

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

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

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

        });
    }

    public class AnimationPane extends JPanel {

        private BufferedImage boat;
        private int xPos = 0;
        private int direction = 1;

        public AnimationPane() {
            try {
                boat = ImageIO.read(new File("boat.png"));
                Timer timer = new Timer(40, new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        xPos += direction;
                        if (xPos + boat.getWidth() > getWidth()) {
                            xPos = getWidth() - boat.getWidth();
                            direction *= -1;
                        } else if (xPos < 0) {
                            xPos = 0;
                            direction *= -1;
                        }
                        repaint();
                    }

                });
                timer.setRepeats(true);
                timer.setCoalesce(true);
                timer.start();
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }

        @Override
        public Dimension getPreferredSize() {
            return boat == null ? super.getPreferredSize() : new Dimension(boat.getWidth() * 4, boat.getHeight());
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);

            int y = getHeight() - boat.getHeight();
            g.drawImage(boat, xPos, y, this);

        }

    }

}

这篇关于如何移动图像(动画)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆