如何移动图像(动画)?
我正试图在X轴上移动船(没有键盘)。 如何将运动/动画与boat.png
联系起来,而不是与任何其他图像联系起来?
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."); } } } }
有一些东西突出……
问题”
如前所述,您需要为图像绘制过程提供变量参数。 g.drawImage(img2, x, y, this);
,这将允许您定义应该绘制图像的位置。
虽然您已经实现了Runnable
,但实际上您还没有启动任何线程来调用它。 这意味着,实际上没有任何东西改变变量。
在你的start
方法中,你应该调用类似new Thread(this).start()
。
建议
虽然您已将问题标记为Swing,但您使用的是AWT组件。 这是不推荐的(实际上小程序通常不鼓励,因为它们很麻烦 – 恕我直言)。 另一个问题,就像你很快就会发现的那样,它们不是双缓冲的,这通常会在执行动画时导致闪烁,这是不可取的。
另外,我们也不鼓励覆盖像Applet
这样的顶级容器的paint
方法。 顶级容器往往包含许多其他组件,通过覆盖这样的paint
方法,您可以销毁此设置。 此外,顶级容器也不倾向于双缓冲。
下面的示例使用了一个JFrame
,但将它转换为使用JApplet
并不需要太多(只需将AnimationPanel
放到它上面。这是为什么不鼓励从顶级容器扩展的另一个原因;)
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); } } }
你需要替换g.drawImage(img2, 200, 200, this);
用g.drawImage(img2, x, y, this);