In this tutorial, we will see the tricks and the code required to achieve a parallax scrolling background effect. The parallax effect is when different layers of backgrounds are moved at different speeds to achieve the effect of motion and depth. By moving the front layer(s) faster than the back the distance/depth effect is achieved. Video games didn’t invent this technique and the first modern use of the parallax effect dates back to early cinema. The famous Disney production Snow White used this effect as well as another trick where layers of backgrounds are moved in opposite directions to achieve a rotating effect.

patreon

 

 

The first time the effect was used in a video game was Atari’s Moon Patrol. Why not take a look at the video in the previous link. Notice the foreground which is plain green with the occasional pot-hole, scrolls at a different(faster) speed to the background hills. It is also possible with more modern hardware (like our Android phones) to have transparent parts to the layers and overlap them with other layers to create a more pleasing effect. Let’s code a parallax scrolling background.

About this project

Skill level 1
Time to complete 1 hour

New Concepts:

  1. Creating a multi-layered parallax effect
  2. Integrating the parallax feature with a simple game engine

Recommended preparation tutorials

How the parallax effect is achieved in code

The first frame of the game shows the background image like this. Please note these images are not the ones to add to your project. They are shown later in the tutorial.

parallax_explanation_part1

The way the next frame is shown is to move the image off-screen to the left. So what do we show on the last pixel on the right-hand side of the screen? We will make a reversed copy of the same image and show it to the right of the original(unreversed) image.

parallax_explanation_part2

As the original image and the reversed image are steadily scrolled to the left, eventually, half of each image will be shown, and so on.

parallax_explanation_part3

Eventually, we will be reaching the end of the original image and the last pixel on the right-hand-side of the reversed image will eventually be on-screen.

parallax_explanation_part4

At the point when the reversed image is shown in full on the screen, just like the original image was at the start, we will move the original image over to the right-hand side. The two backgrounds will continuously scroll and as the right-hand image (either original or reversed) becomes the entire view that the player sees, the left-hand image (either original or reversed) will be moved to the right-hand-side ready to be scrolled into view.

Let’s start coding.

Starting the project

Start a new project in Android Studio and choose the Empty Activity template without a layout file because we don’t need loads of auto-generated code and files. All the code and images are available on this page but if you want to help me out by telling others about this page then take a look at my bonus download for this project.

 

Making the game a full-screen landscape

We want to use every pixel that the device has to offer so we will make changes to the app’s AndroidManifest.xml configuration file.

  1. In the project explorer pane in Android Studio double click on the manifests folder, this will open up the AndroidManifest.xml file in the code editor.
  2. In the AndroidManifest.xml file, locate the following line of code,  android:name=".ParallaxActivity">
  3. Place the cursor before the closing > shown above. Tap the enter key a couple of times to move the > a couple of lines below the rest of the line shown above.
  4. Immediately below ParallaxActivity but BEFORE the newly positioned > type or copy and paste these two lines to make the game run full screen and lock it in the landscape orientation.

The code structure

The code structure for this game is almost the same as the Simple Game Engine tutorial with one extra class and one extra method in the main View-based class. We will call the Activity class ParallaxActivity and the View-based class ParallaxView. ParallaxActivity will be set up ParallaxView in onCreate and then set it as the view for the app.  ParallaxView will hold a Thread instance that will run the main game loop which in turn will consist of the usual calls to update and draw methods. We won’t obscure the parallax code by adding any extra game objects so the update method will only update the positions of our multiple backgrounds and the draw method (big reveal!) will draw them.

The class that does all the hard work will be called Background. The Background class will have a fairly in-depth constructor to initialize the instance, a method called update to control shifting the two images (regular and reversed) of the background around. This implies that each background will be a separate instance of the Background class. ParallaxView will hold these in an ArrayList called backgrounds. A  ArrayList for just two is probably overkill but you can then add as many layers as you like.

The draw method will just need to call the layers in order at the same time as inserting any game objects in between the appropriate layers. We will simply draw some text in between our layers just to see the effect.

Coding the Parallax Activity

Add the following code for the ParallaxActivity class. All it does is instantiate an instance of ParallaxView, pass in some resolution information, and set ParallaxView as the view for the game. If anything is unclear about any of the code that isn’t specifically about the parallax background, you can find more detail in the Simple Game Engine tutorial.

Coding the ParallaxView class

Add a new class to the project called ParallaxView and add the following code. All this code does is set up the class and a simple game loop. Currently, we do nothing in the  update method and just draw a bit of text in the draw method. Take a look at the comments that indicate where we will add our parallax-specific code once we have coded the Background class. If any of this code is unclear refer to the Simple Game Engine tutorial.

Coding the Background class

Now we get to see how we will implement the parallax scrolling background using the visual technique described at the start of the tutorial. The Background class we will now code will be instantiated once for each background image, the grass, and the city skyline.

Create a new class called Background and add this code which has all the member variables as well as the declaration of the constructor and update methods. Pay attention to the names and the types of the variables as we will use them soon when we actually code the two methods. Also take a look at the parameters of the methods, especially the constructor.

Adding the parallax image resources

As the final preparation, add the two images below to the drawable folder in Android Studio.

This image will be the back layer and be positioned at coordinates 0,0 at the top left of the screen (to start with).

skyline

Next, we will draw some text at different heights as seen in the draw method we coded previously.

Finally, we will draw this image near the bottom of the screen as the third layer.

grass

Coding the Background class constructor

The constructor is where we get everything ready to call update each frame of the game.  Add and study the code then we can talk about it.

First, in the constructor, we use the chained getResources().getIdentifier() methods to make a resource id that refers to the bitmaps we just added to the drawable folder. The name of the file is contained in the bitmapName parameter and can, therefore, be different for each call to the constructor. Next, we initialize bitmap and set the Boolean reversedFirst to false. This will tell our code which image (regular or reversed) to draw on the left and which on the right. Next, we initialize xClip to . The xClip variable will hold the horizontal position at which to cut/clip the current background. It will be strategically manipulated in the update method of this class in each frame. We set it to zero which means we don’t clip anything to start with, just as discussed at the start of the tutorial.

Here is some code repeated from above.

This code uses the parameters sY, eY and s to initialize the member variables startY, endY and speed. What is more interesting is why we initialize startY and endY the way that we do. The reason is that we want our code to work on screens of all resolutions. By dividing screenHeight by 100 and multiplying it by the passed-in parameters it means that when we call the constructor we can pass in a percentage vertical starting height rather than having to calculate the ideal height for any given screen resolution. The speed variable represents the number of pixels per second to move this particular background.

The final part of the code creates a bitmap and captures its size in the width and height variables. The Matrix class and the setScale method is what allows us to create a reversed copy of the image in the final line of code of the constructor.

Coding the Background update method

The update method is short and sweet because we have already set up everything we need. The first thing that happens is that xClip is modified based on the speed of the background and the current frame rate. The if/ else blocks check if we have reached the end of the current image and if we have switches the value of reversedFirst and resets xClip to either or width. We will see how these values are used in ParalaxView to draw the correct image (regular or reversed) in the correct position (first or second) with the appropriate amount of clipping on each. Add the update method and we are not far from being finished.

Updating the ParallaxView class

First, declare an ArrayList to hold the type of Background called backgrounds as the first line of code below shows. Note that you only need to add the first line. The rest of the code we added previously.

Now, add this extra code in the ParallaxView constructor to initialize the ArrayList and populate it with two backgrounds using calls to the Background constructor we just coded. Note the arguments. The different starting and ending heights along with different image names and speeds.

As the code to draw a background is relatively long and we will use it multiple times we will make it into a method. This drawBackground method will be called from the draw method along with the position in the ArrayList of the background we want to draw. Take a close look at the code and the comments and then we can talk about it a bit.

The first thing the code does is make a reference to the current background. Actually, this unnecessarily slows the code down a little but  it makes it much more readable as we can refer to bg.width instead of backgrounds.get(position).width , etc.

In the code, we create four RectF objects. These objects hold the coordinates from each of the images and the coordinates of the screen at which to draw them. All the values are taken from the background.

Finally, we draw the two images side by side using the four RectF objects to capture the appropriate part of each image and place it at the appropriate coordinates. The if/ else blocks use the reversedFirst Boolean to determine which image is currently drawn on the left or the right.

Updating and drawing the backgrounds

This code simply loops through any Background objects that are in the backgrounds array and calls their update method passing in the current frame rate as required. In the updated draw method, there are two calls to drawBackground, one before the text is drawn with the argument of zero and one after the text is drawn with one as the argument. This ensures the city skyline is drawn first, the text second and the bushes last.

We are done!

You can run the game and see the world whizzing by parallax style. Be sure to try different speeds and backgrounds.

Ideally, we should use a viewport solution so that speed and movement happen as a unit of measurement that is independent of the screen resolution. For example, a high-resolution screen will appear to be moving more slowly than a low-resolution screen. I thought I would leave out this issue to focus on the parallax solution. Furthermore, we should really scale the bitmaps relative to the size and resolution of the screen. If for example, you have a more “square” screen than mine your backgrounds might appear a little squashed. When I get around to the simple OpenGL ES series of tutorials we will see how this is solved.

I hope you enjoyed the tutorial. Please let me know either way or if you are stuck.

patreon