代码之家  ›  专栏  ›  技术社区  ›  heyBad.

在Swing中移动背景图像

  •  3
  • heyBad.  · 技术社区  · 11 年前

    你好,我是编程新手,我们有一个项目。我们创建了一个带有移动背景的简单赛车游戏,但我被代码卡住了,我不知道怎么做。游戏开始时我需要移动背景,请有人帮助我。我恳求t_t

    enter image description here

    这是我的代码:

    public class Game extends JFrame implements KeyListener, ActionListener {
    
        Random s = new Random();
        int x = 0, y = 50, a = 0, b = 250, f = 900, a1 = 0, b2 = 350, a2 = 0, b3 = 150;
        int Move;
        int value;
        JLabel spriteLabel1 = new JLabel(new ImageIcon("ss.gif"));
        JLabel spriteLabel2 = new JLabel(new ImageIcon("ss.gif"));
        JLabel spriteLabel3 = new JLabel(new ImageIcon("ss.gif"));
        JLabel spriteLabel4 = new JLabel(new ImageIcon("ss.gif"));
        JLabel background = new JLabel(new ImageIcon("geren.png"));
        Timer T1 = new Timer(5000, this);
        Timer T = new Timer(5, this);
    
        public static void main(String args[]) {
            new Game();
        }
    
        public Game() {
            Container c = getContentPane();
            c.setLayout(null);
            c.add(spriteLabel1);
            c.add(spriteLabel2);
            c.add(spriteLabel3);
            c.add(spriteLabel4);
            c.add(background);
            background.setBounds(0, 0, 1024, 768);
            addKeyListener(this);
            setSize(1000, 750);
            setVisible(true);
        }
    
        public void paint(Graphics g) {
            super.paint(g);
            spriteLabel1.setBounds(x, y, 60, 1000);
            spriteLabel2.setBounds(a, b, 60, 800);
            spriteLabel3.setBounds(a1, b2, 60, 500);
            spriteLabel4.setBounds(a2, b3, 60, 650);
        }
    
        public void keyPressed(KeyEvent e) {
            String k = e.getKeyText(e.getKeyCode());
            if (k.equals("D")) {
                if (a != f) {
                    x = x + 15;
                    spriteLabel1.setIcon(new ImageIcon("ss.gif"));
                    repaint();
                    if (x > f) {
                        x = f;
                        spriteLabel1.setIcon(new ImageIcon("ss.gif"));
                        //JOptionPane.showMessageDialog(null,"Congratulations!! 
                        //Sanji wins!","Result",JOptionPane.PLAIN_MESSAGE,
                        //new ImageIcon("evolve sanji.gif"));
                        //System.exit(0);
                    }
                    repaint();
                }
            }
            T.stop();
        }
    
        if(k.equals ( 
            "D")) 
        {
            if (x != f) {
                T.start();
                Move = 3;
            }
        }
    
        public void keyReleased(KeyEvent e) {
        }
    
        public void keyTyped(KeyEvent e) {
        }
    
        public void actionPerformed(ActionEvent e) {
            if (Move == 3) {
                a = a + (s.nextInt(3));
                a = a + value;
                if (a > f) {
                    a = f;
                }
                spriteLabel2.setIcon(new ImageIcon("ss.gif"));
                spriteLabel2.setBounds(a, b, 100, 800);
            }
            if (a == f) {
                if (Move == 3) {
                    a1 = a1 + (s.nextInt(3));
                    a1 = a1 + value;
                    if (a1 > f) {
                        a1 = f;
                    }
                    spriteLabel3.setIcon(new ImageIcon("ss.gif"));
                    spriteLabel3.setBounds(a1, b2, 100, 500);
                }
                if (Move == 3) {
                    a2 = a2 + (s.nextInt(5));
                    a2 = a2 + value;
                    if (a2 > f) {
                        a2 = f;
                    }
                    spriteLabel4.setIcon(new ImageIcon("ss.gif"));
                    spriteLabel4.setBounds(a2, b3, 100, 650);
                }
    
            }
        }
    }
    
    1 回复  |  直到 10 年前
        1
  •  7
  •   Community CDub    8 年前

    这是扰流板

    enter image description here

    这是肉

    我看到你做错了几件事:

    • 不断创建新图像。只需使用相同的图像。

    • 我将不使用标签,只在绘画表面上绘制Image/BufferedImage。

    • 忘记两个计时器。你可以用一个。这就是你如何管理你的州。

    • 不要在绘画方法中做任何逻辑。在你目前的情况下,由于你甚至没有画任何东西,你甚至不需要它。

    • 不要在上面作画 JFrame 和覆盖 paint 推翻 paintComponent 而是在 JPanel 并将该面板添加到框架中。

    • 最后,关键成分,使用方法(来自 Graphics ) -

      public abstract boolean drawImage(Image img,
              int dx1,
              int dy1,
              int dx2,
              int dy2,
              int sx1,
              int sy1,
              int sx2,
              int sy2,
              ImageObserver observer)
      

      你可以得到更好的解释 in this post 。基本上 s 点是源图像,因此您只需移动 sx1 sx2 在动画期间,它将移动要在 d 绘制表面的点。

    如果你不知道如何真正地做定制绘画,我建议你试一下 Performing Custom Painting

    下面是完整的示例

    (请注意,我用于背景的图像是2000x350)

    import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.FlowLayout;
    import java.awt.Graphics;
    import java.awt.Image;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.image.BufferedImage;
    
    import javax.imageio.ImageIO;
    import javax.swing.ImageIcon;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.SwingUtilities;
    import javax.swing.Timer;
    
    public class MovingBackgroundDemo {
    
        public MovingBackgroundDemo() {
            JFrame frame = new JFrame();
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.add(new AnimatingPanel());
            frame.pack();
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
        }
    
        private class AnimatingPanel extends JPanel {
            private static final int DIM_W = 350;
            private static final int DIM_H = 350;
            private static final int INCREMENT = 10;
    
            private BufferedImage backgroundImage;
            private Image runnerImage;
    
            private int dx1, dy1, dx2, dy2;
            private int srcx1, srcy1, srcx2, srcy2;
            private int IMAGE_WIDTH;
    
            public AnimatingPanel() {
                initImages();
                initImagePoints();
                Timer timer = new Timer(40, new ActionListener() {
                    public void actionPerformed(ActionEvent e) {
                        moveBackground();
                        repaint();
                    }
                });
                timer.start();
    
                FlowLayout layout = (FlowLayout)getLayout();
                layout.setHgap(0);
                layout.setVgap(0);
            }
    
            @Override
            protected void paintComponent(Graphics g) {
                super.paintComponent(g);
                g.setColor(Color.WHITE);
                g.fillRect(0, 0, getWidth(), getHeight());
                g.drawImage(backgroundImage, dx1, dy1, dx2, dy2, srcx1, srcy1,
                        srcx2, srcy2, this);
                g.drawImage(runnerImage, 0, 0, getWidth(), getHeight(), this);
            }
    
            @Override
            public Dimension getPreferredSize() {
                return new Dimension(350, 350);
            }
    
            private void initImagePoints() {
                dx1 = 0;
                dy1 = 0;
                dx2 = DIM_W;
                dy2 = DIM_H;
                srcx1 = 0;
                srcy1 = 0;
                srcx2 = DIM_W;
                srcy2 = DIM_H;
            }
    
            private void initImages() {
                try {
                    runnerImage = new ImageIcon(getClass().getResource("runner.gif")).getImage();
                    backgroundImage = ImageIO.read(getClass().getResource(
                            "background.png"));
                    IMAGE_WIDTH = backgroundImage.getWidth();
                    System.out.println(IMAGE_WIDTH);
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
    
            private void moveBackground() {
                if (srcx1 > IMAGE_WIDTH) {
                    srcx1 = 0 - DIM_W;
                    srcx2 = 0;
                } else {
                    srcx1 += INCREMENT;
                    srcx2 += INCREMENT;
                }
            }
        }
    
        public static void main(String[] args) {
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    new MovingBackgroundDemo();
                }
            });
        }
    }