Creating the next great side scroller? Well, you’ll need a scrolling background. And if you’re programming in Java, here’s an easy way to do it.
Quick Demo
Here’s a little demo of what we’re going to create. What’s happening is that there are two copies of the same image scrolling from the right to left. As one copy gets all the way off the left edge it leapfrogs back over to the right side. Normally they’d be the same, but it makes more sense on the demo for the two copies to be different colors.
The black box is the screen. Everything to the right or left of the box is happening off screen.
Click to start and click to stop.
The Code
In the previous posts I’ve showed the code and then went back and explained. This time, since Java involves quite a bit more code, I put comments into the code instead.
There are 3 files as part of this demo; one to hold an individual background, one is the canvas that holds both background instances, and a runner.
Background.java
This is an individual copy of the background. It takes care of the motion, drawing to a Graphics reference, and moving back when needed.
import java.awt.Graphics; import java.awt.image.BufferedImage; import java.io.File; import javax.imageio.ImageIO; public class Background { private BufferedImage image; private int x; private int y; public Background() { this(0,0); } public Background(int x, int y) { this.x = x; this.y = y; // Try to open the image file background.png try { image = ImageIO.read(new File("background.png")); } catch (Exception e) { System.out.println(e); } } /** * Method that draws the image onto the Graphics object passed * @param window */ public void draw(Graphics window) { // Draw the image onto the Graphics reference window.drawImage(image, getX(), getY(), image.getWidth(), image.getHeight(), null); // Move the x position left for next time this.x -= 5; // Check to see if the image has gone off stage left if (this.x <= -1 * image.getWidth()) { // If it has, line it back up so that its left edge is // lined up to the right side of the other background image this.x = this.x + image.getWidth() * 2; } } public void setX(int x) { this.x = x; } public int getX() { return this.x; } public int getY() { return this.y; } public int getImageWidth() { return image.getWidth(); } public String toString() { return "Background: x=&amp;amp;quot; + getX() + ", y=" + getY() + ", height=" + image.getHeight() + ", width=" + image.getWidth(); } }
ScrollingBackground.java
ScrollingBackground holds two instances of the Background object and takes care of drawing them on the stage.
import java.awt.Canvas; import java.awt.Color; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.image.BufferedImage; public class ScrollingBackground extends Canvas implements Runnable { // Two copies of the background image to scroll private Background backOne; private Background backTwo; private BufferedImage back; public ScrollingBackground() { backOne = new Background(); backTwo = new Background(backOne.getImageWidth(), 0); new Thread(this).start(); setVisible(true); } @Override public void run() { try { while (true) { Thread.currentThread().sleep(5); repaint(); } } catch (Exception e) {} } @Override public void update(Graphics window) { paint(window); } public void paint(Graphics window) { Graphics2D twoD = (Graphics2D)window; if (back == null) back = (BufferedImage)(createImage(getWidth(), getHeight())); // Create a buffer to draw to Graphics buffer = back.createGraphics(); // Put the two copies of the background image onto the buffer backOne.draw(buffer); backTwo.draw(buffer); // Draw the image onto the window twoD.drawImage(back, null, 0, 0); } }
Runner.java
Runner puts everything together.
import java.awt.Component; import javax.swing.JFrame; public class Runner extends JFrame { public Runner() { super("Scrolling Background Demo"); setSize(550, 250); ScrollingBackground back = new ScrollingBackground(); ((Component)back).setFocusable(true); getContentPane().add(back); setDefaultCloseOperation(EXIT_ON_CLOSE); setVisible(true); } public static void main(String[] args) { new Runner(); } }
Two comments:
– Can you fix portions of the code? Ie. < got changed to lt
– Do you know why my second image streaks? I've modified the code the scroll vertically, but it is streaking the image so that you can't see what it is anymore.
To add to the second part, I believe my draw function is incorrect in the logic. How would you draw the image if it is going off the bottom of the screen?
Alright, think I got all of the HTML entity mess cleaned up.
Not sure I understand the question about off the bottom of the screen. The code doesn’t really care where it’s drawing. It can draw off the screen. You just won’t be able to see it.
How would you go about adding a single stationary image on top of this scrolling background?
I don’t understand what makes the background move?
Can someone help me understand what makes the background move??
I can’t even find where the img url isThanks,
– Noah
Well the reason that the background is moving is to be found in Background draw() method. You can see in this method that every tick, the x position of the image = the x position of image – 5. The number 5 is changeable compared to how fast you want the background to move. Hope it makes sense
I need to coding for move background in 2d game . by swing function and in public void paint in java core
Hello,
Great work, I love it! I was wondering if someone can help me implement it into my flappy bird project where it will switch back and forth between two images. I added all files to my project and put image I wanted it to display in the code. However, it is not working. Any help is greatly appreciated!
Thanks