Java – move background image in swing
Hello, I'm a novice programmer. We have a project We created a simple racing game with a moving background, but I insisted on my code and I didn't know what to do I need a moving background at the beginning of the game. Please help me I'm begging t_ T
This is my code:
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,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,800); spriteLabel3.setBounds(a1,b2,500); spriteLabel4.setBounds(a2,b3,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,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,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,650); } } } }
Solution
This is the spoiler
This is meat
I see you did something wrong:
>Keep creating new images Just use the same image. > Instead of using labels, I will just draw an image / bufferedimage on the painting surface. > Forget two timers You can use an expiration date That's the way you run your country. > Do not make any logic in the paint method In your current situation, you don't even need it because you don't even draw anything In my example, although I drew an image. > Do not paint on JFrame and overwrite the paint Instead, overwrite paintcomponent in JPanel and add the panel to the frame. > Finally, key components, usage (from 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)
You can get a better explanation in this post Basically, point s is the source image, so you can move SX1 and SX2 during the animation, which draws part of the moving image on the d-point painting surface
If you don't know how to make custom painting, I suggest you use performing custom painting
This is a complete example
(note that my image for the background is 2000 × 350)
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,getWidth(),getHeight()); g.drawImage(backgroundImage,dx1,dy2,srcx1,srcy2,this); g.drawImage(runnerImage,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(); } }); } }