##### Tutorial Details
• Difficulty: Beginner
• Platform: Flash (Flash Player 9)
• Language: AS3
• Software: Flash Professional CS3 or any AS3 IDE/compiler (e.g. FlashDevelop)
• Estimated Completion Time: One hour

Twice a month, we revisit some of our readers’ favorite posts from throughout the history of Activetuts+. This tutorial was first published in October, 2009 (and led to my inviting Michael to be Activetuts+ Tech Editor!)

This is a really simple technique which you can use to add the illusion of depth to any side-scroller game. While I’m explaining how it’s achieved, we’ll also take a look at making infinitely repeating backgrounds.

## Introduction

You can see the basic parallax scrolling effect at work in the demo. By adjusting the speeds at which certain objects scroll, we can change how near or far away they appear to be.

This tutorial will explain how to code the effect, as well as how to make the game’s camera appear to follow the car. Lastly, it’ll explain how to create infinitely repeating backgrounds, just like in Scooby Doo.

## Step 1: The Setup

If you’re using Flash, create a new ActionScript 3.0 Flash file. Set the size of the stage to be whatever you like; I’ve chosen the default 550 by 400 pixels.

If you’re not using the Flash IDE, don’t worry; just create a new AS3 project. The zip file contains a SWC with all my graphics, so you can use those just by adding it to your library. Skip all the drawing steps if you do so.

If you are using the Flash IDE but you don’t want to draw anything, the zip also contains a FLA file containing all my MovieClips :)

## Step 2: Draw a Car

Create a new MovieClip symbol and draw a car. You can animate it if you like. Here’s mine:

Try to centre the car so that its registration point (the little cross) is about half-way along. This will make it easier for the camera to follow it later.

## Step 3: Export Your Car for ActionScript

Right-click your car symbol in the Library and select Properties:

Give your car a Class (Car will do) and check the Export for ActionScript box (this lets us access the car using code). Also, check the Export in first frame box (otherwise, we’ll have to make a preloader).

## Step 4: Draw a Road

Create another new symbol, but this time draw a road:

Make it wider than the stage, but unlike the car, align the registration point with the left edge of the road. This will help later on, when we need to turn it into a repeating pattern.

Just like you did for the car, give the road a Class, export it for ActionScript and export it in the first frame.

## Step 5: Create the Document Class

Create a new AS file and paste the following code into it:

package
{
import flash.display.MovieClip;
public class ParallaxDemo extends MovieClip
{
public function ParallaxDemo()
{

}
}
}


Save this as ParallaxDemo.as, in the same folder as your FLA (or as your project, if you’re not using the IDE).

If you’re using the IDE, be sure to set this as your document class in the Properties Panel of your document:

Not sure what we’re doing here? Check out my Quick Tip on using a document class.

## Step 6: Set Up the Car and the Road

Create new instances of your car and road in the AS file: (lines 6, 7, 11, 12)

package
{
import flash.display.MovieClip;
public class ParallaxDemo extends MovieClip
{
public var car:Car;

public function ParallaxDemo()
{
car = new Car();
}
}
}


## Step 7: Position the Car and the Road

If you’re using my graphics, you can just copy the following code (lines 14-17):

package
{
import flash.display.MovieClip;
public class ParallaxDemo extends MovieClip
{
public var car:Car;

public function ParallaxDemo()
{
car = new Car();

car.x = 275.0;
car.y = 235.0;
}
}
}


Otherwise, you’ll need to figure out where your car and road should be placed at the start. Create a new Layer in your FLA’s timeline, then make it into a Guide Layer by right-clicking it and selecting Guide. Flash will ignore anything you do in this layer when it creates a SWF, so drag your car and road symbols here.

Make sure the left edge of your road is aligned with the left edge of the stage, and that the car is roughly in the centre (horizontally). Then adjust them so that they fit together:

Now take my code from above and adjust it to match the x- and y- coordinates of your car and road. By clicking on your car or road, you’ll be able to see these values in the Properties panel.

If you test your movie now, you’ll see nothing. We need to addChild() the car and road to the stage:

public function ParallaxDemo()
{
car = new Car();

car.x = 275.0;
car.y = 235.0;

}


(Make sure you add the road first, or it’ll cover the car!)

Test your movie now, and it should look like this:

Great! Well, OK, it’s nothing spectacular yet. But now the setup’s out of the way, we can make this more interesting. For starters, let’s get this car moving…

## Step 9: Add an ENTER_FRAME Event Listener

Alter your document class to add an event listener to be triggered on each frame: (lines 4, 23, 26-29)

package
{
import flash.display.MovieClip;
import flash.events.Event;
public class ParallaxDemo extends MovieClip
{
public var car:Car;

public function ParallaxDemo()
{
car = new Car();

car.x = 275.0;
car.y = 235.0;

}

public function onEnterFrame( evt:Event ):void
{

}
}
}


If you kept the default frame rate of 12fps, the onEnterFrame() function will be called every 1/12th of a second.

## Step 10: Move That Car!

If we keep increasing the car’s x-position…

public function onEnterFrame( evt:Event ):void
{
car.x = car.x + 10;
//if you're up for a challenge, try adding basic
//keyboard controls to let the player accelerate
//and decelerate.
}


…we can make the car move forwards…

…right off the edge of the screen!

## Step 11: Follow That Car!

This is hardly ideal; after a few seconds we can’t even see the car any more. So let’s make the “camera” appear to follow the car.

What exactly does this mean? Well, basically we need the car to stay in the same place, while the road appears to move backwards.

That means we could do something like this:

public function onEnterFrame( evt:Event ):void
{
}


…but this would just complicate things later. For example, imagine if we wanted to add other cars to the road, or powerups, or oil slicks, or anything at all; we’d have to move every single one of them backwards in the onEnterFrame() function.

No, there is a much simpler technique we can use. Instead of addChild()-ing the car and road to the stage, we create a new object, addChild() them to that, and then move this object backwards in the onEnterFrame() function.

It sounds more complicated than it is. Let me show you the actual code:

package
{
import flash.display.MovieClip;
import flash.events.Event;
public class ParallaxDemo extends MovieClip
{
public var car:Car;

public function ParallaxDemo()
{
car = new Car();

car.x = 275.0;
car.y = 235.0;

}

public function onEnterFrame( evt:Event ):void
{
car.x = car.x + 10;
}
}
}


In lines 9 and 21 we create a new, blank MovieClip called roadContainer. Flash automatically sets its x and y values to 0.

In lines 22 and 23 we add the road and the car to the roadContainer, instead of the stage. In line 25 we add the roadContainer itself to the stage – and since the car and road are now added to the roadContainer, this lets us see them on the stage.

Line 32 is the most important part. Here, we move the roadContainer backwards by the same amount that we just moved the car forwards. This means that everything inside the roadContainer gets moved left by 10 pixels, but since the car has just been moved 10 pixels to the right, it stays in the centre of the screen.

It’s a bit like running up the down escalator. If you walk up at the same speed that it’s moving down, then to a person standing on the stairs next to you, you don’t seem to be moving.

The overall effect:

The car stays in the centre! Great. Well, great apart from the gaping white hole. But we’ll get to that. Now if you want to add more cars to the road, all you have to do is addChild() them to the roadContainer.

## Step 12: Improve the Following

The trouble with just moving the whole container backwards a little bit every frame is that it’s not very flexible. What if the player uses a powerup to teleport the car 100 pixels forwards instead of 10? What if we want to make the camera centre on a different car?

When the SWF first loads, the car’s x-position is 275, and the roadContainer’s x-position is 0. How do they each change over time?

• Start: car.x is 275, roadContainer.x is 0
• Frame 1: car.x is 285, roadContainer.x is -10
• Frame 2: car.x is 295, roadContainer.x is -20
• Frame 3: car.x is 305, roadContainer.x is -30

Do you see a general rule connecting the two? If not, check this out:

• Start: car.x is 275, roadContainer.x is 275 – 275
• Frame 1: car.x is 285, roadContainer.x is 275 – 285
• Frame 2: car.x is 295, roadContainer.x is 275 – 295
• Frame 3: car.x is 305, roadContainer.x is 275 – 305

The connection is a little more obvious now! Let’s put it into code:

public function onEnterFrame( evt:Event ):void
{
car.x = car.x + 10;
}


You can do what you like with the car now. Speed it up, teleport it forwards a random number of pixels, stop it moving – whatever! The camera will still follow it.

And if you want to make the camera follow a different object, just replace car.x with otherObject.x in the line we just changed.

## Step 13: Extend the Road

Time to fix the endless white void of nothingness at the end of the road.

The simplest way to make the road longer is just to add another instance of the road symbol to the right of our existing symbol, like so: (lines 9, 22, 23, 27)

package
{
import flash.display.MovieClip;
import flash.events.Event;
public class ParallaxDemo extends MovieClip
{
public var car:Car;

public function ParallaxDemo()
{
car = new Car();

car.x = 275.0;
car.y = 235.0;

}

public function onEnterFrame( evt:Event ):void
{
car.x = car.x + 10;
}
}
}


Here’s how mine looks when it’s run:

Oh dear. Better fix that gap.

## Step 14: Mind the Gap

The problem is in line 22 of the above code, road2.x = road.x + road.width. The road’s width value must be slightly larger than my road actually appears to be.

Even if your road doesn’t have the same problem, it still might not fit together perfectly. So head back to your FLA and drag another Road symbol from the library to your Guide layer.

Make sure it’s got the same y-position as the first road segment, then move it along horizontally until there’s no gap:

## Step 15: Tweak the Join

If the edges of your two symbols don’t quite join together neatly, double-click one of them. You’ll be able to edit it and immediately see how the changes you make affect the other:

Use this trick to adjust the edges of the symbol so that the join is clean.

## Step 16: Work Out the Breadth

Instead of using road.width to figure out where the second road segment should be placed, we’ll use a number I call the breadth.

All you’re doing here is figuring out how many pixels apart your two road segments have to be in order to get the same perfect join you just created in Flash.

Create a new Number variable, roadBreadth, and set its value to the number you worked out in the previous step: (If you’re using my graphics, that number is 653.7.)

public class ParallaxDemo extends MovieClip
{
public var car:Car;

public function ParallaxDemo()
{
car = new Car();


## Step 18: Replace Width with Breadth

Replace the line:

road2.x = road.x + road.width;


with:

road2.x = road.x + roadBreadth;


Now test it out. There should be no gap:

Great! We still run into the endless white void, though…

## Step 19: Make the Background Repeat Infinitely

We could create a road3 and a road4 and a road5 and so on, positioning them each to the right of the one before them, but no matter how many segments we created, the car would reach the end of them eventually.

For a better solution, think back to when you were a child. Did you ever play that game where you pretend the floor is made of lava, but you have to get to the other end of the room somehow? (If not, heck, go play it now, it’s great fun.)

I don’t know about you, but in my house, sofa cushions were considered to be lava-resistant, able to be used as stepping-stones. We only had a couple, which wasn’t enough to reach the end of the room – but eventually I figured out how to make them reach further.

I’d lay the two cushions down to make a short path, and walk over to the second one. Then, I’d pick up the one behind me, drop it in front of me, and step across to it. By repeatedly picking up the one behind me and moving it in front of me, I could get to anywhere I pleased.

We can use the same technique to make the road last forever, without having to use more than two segments. All we have to do is detect when a road segment is “behind” the camera, and move it in front of it.

What do I mean by “behind” the camera? I mean that the right-hand edge of the segment is off the left-hand edge of the stage. We can use this if-statement to check that:

if ( road.x + roadBreadth + roadContainer.x < 0 )
{
}


Curious as to why this works? If not, skip to the next step. Otherwise, let me explain:

• road.x is how many pixels to the right the left-hand edge of road is from the left-hand edge of roadContainer
• roadContainer.x is how many pixels to the right the left-hand edge of roadContainer is from the left-hand edge of the stage (since roadContainer is constantly moving to the left, this will usually be negative)
• So, ( road.x + roadBreadth + roadContainer.x ) is how many pixels to the right the right-hand edge of road is from the left-hand edge of the stage.

Phew! OK, I’ll admit, that’s pretty confusing. If you’d like a deeper explanation, feel free to ask in the comments :)

## Step 20: Move the Road in Front of the Camera

Now that we can tell when the road segment is behind the camera, we need to move it in front of the camera again.

If we moved the road to the right by roadBreadth number of pixels, it would be in the exact same place as the other road segment. So, we need to move it to the right by twice that amount:

if ( road.x + roadBreadth + roadContainer.x < 0 )
{
}


Put that in your onEnterFrame() function, and test it out:

As you can see, one road segment is repeating, but the other isn’t yet.

## Step 21: Move the Other Road Segment

We can just copy the above code for our other road segment, road2:

public function onEnterFrame( evt:Event ):void
{
car.x = car.x + 25;
{
}
{
}
}


Test it out again:

Fantastic! An infinitely looping, side-scrolling background :) Now to create the actual parallax effect…

## Step 22: Create Rolling Hills

(Skip this step if you’re using my graphics.)

We’re going to need a repeating background to show off the parallax scrolling. I’ve chosen hills, but you could make buildings, forests, alien sculptures – anything you like!

There are a few tricks you can use to make what you draw look like it’s further away than the car:

1. Use duller colours (for instance, a darker shade of green for your grass)
2. Draw less detail (no individual tufts of grass)
3. Add a “blurred” effect to the edges (because the camera is focused on the car)

• Make the symbol wider than the stage
• Align the symbol so that the registration point is at the left-hand edge
• Give it a class name, export it for ActionScript, and export it in the first frame
• Tweak the join to make sure two symbols fit together neatly
• Figure out the “breadth” of the symbol

Here’s mine:

## Step 23: Code the Hills

The code regarding the hills is almost exactly the same as the code we just wrote regarding the roads. Have a go at writing it yourself. I’ve pasted my AS file with all the new additions below, so you can refer to it if you like:

package
{
import flash.display.MovieClip;
import flash.events.Event;
public class ParallaxDemo extends MovieClip
{
public var car:Car;
public var hills:Hills;
public var hills2:Hills;
public var hillsContainer:MovieClip;

public function ParallaxDemo()
{
car = new Car();

hills = new Hills();
hills2 = new Hills();

car.x = 275.0;
car.y = 235.0;

hills.x = 0;
hills.y = 14.5;
hills2.y = hills.y;

hillsContainer = new MovieClip();

}

public function onEnterFrame( evt:Event ):void
{
car.x = car.x + 10;
{
}
{
}

hillsContainer.x = 275 - car.x;
if ( hills.x + hillsBreadth + hillsContainer.x < 0 )
{
hills.x = hills.x + (2 * hillsBreadth);
}
if ( hills2.x + hillsBreadth + hillsContainer.x < 0 )
{
hills2.x = hills2.x + (2 * hillsBreadth);
}
}
}
}


(The new lines are 12-15, 24-26, 35-38, 45-47, 49, and 67-75. How did you do?)

Here is the result:

You might be wondering why I’ve bothered creating a hillsContainer. If so, then nicely spotted! We could just addChild() the hills to the roadContainer – but creating a new container for the background is what lets us create the actual parallax effect.

## Step 24: The Actual Parallax Effect

The effect only requires changing one line of code:

hillsContainer.x = 275 - car.x;


into this:

hillsContainer.x = (275 - car.x) * 1/5;


This makes the hills scroll at 1/5th the speed of the road and car.

It looks like this:

You don’t have to use 1/5; make this value larger or smaller until the speed feels right to you.

Why does this work? Well, remember that we see things in a cone of vision; the further away something is the more of it we can see. So if we walk past two objects of the same size, but one is further away, the closer of the two will appear to move faster, like so:

Let’s add another background layer, even further away than the hills.

## Step 25: Create Mountains

This is exactly the same as creating the road and the hills, so I’m not even going to paste the code this time! All I’ll do is post a picture of my mountains..

..tell you that my mountains’ breadth is 751.5, x is 0 and y is 63.0; remind you to create a new mountainContainer MovieClip; and let you know that my mountains scroll at 1/16th the speed of my road.

Oh, and show you the result:

## Step 26: Create the Sky

The sky is nice and easy. Since it’s really far away, it scrolls so slowly that it looks like it’s barely scrolling at all. Clouds and birds move, of course, and the Sun rises and sets, but none of this is due to any parallax scrolling effect. This means we don’t have to make anything in the sky scroll!

(The exception to this is if the camera is travelling really, really fast – like, the speed of an aeroplane or rocket. Even then, be sure to make it scroll very slowly.)

So, no need to worry about breadth here, or creating an infinitely repeating image. It’s still a good idea to make a skyContainer, though, just to keep things consistent. My sky is just a blue rectangle:

If you place it at x=0, y=0 it’ll cover the whole stage. Here’s what it looks like in the SWF:

## Step 27: Create a Big Tree in the Foreground

We’ve created a lot of background objects, but nothing closer to the camera than the car. As I’m sure you realise, such an object would have to scroll faster than the roadContainer, so let’s try this.

For my foreground object, I’ve drawn a tree:

The tree’s a little different from the other objects we’ve made so far because it’s not made to loop – it stands alone, it won’t join to another tree standing next to it. This means that we only ever need one tree on screen at any one time (especially since it’s so big!)

So we only need one Tree object in the code as well. Write the code for this object. If you’re using my graphics, the starting x-position will be 780.0 and the y-position will be 175.0.

Since the tree will scroll, we still need a treeContainer, and we still need a treeBreadth. However, this time, the treeBreadth just controls the number of pixels between each tree. I’ve used a nice round 1000.0 for mine.

## Step 28: Scroll the Tree

Since there’s only one tree, the scrolling code is much simpler:

treeContainer.x = (275 - car.x) * 3;
if ( tree.x + treeBreadth + treeContainer.x < 0 )
{
tree.x = tree.x + (2 * treeBreadth);
}


Nothing complicated :) Just note that it scrolls three times faster than the road. Here is the final result:

Congratulations! You’ve created a dynamically scrolling camera, infinitely repeating backgrounds, and a pseudo-3D parallax effect :)

## Further Ideas to Try

Here are few more things you can do with the same code:

If you’re creating a shoot-’em-up and you’d like all your explosions to appear closer to the camera than your enemies, simply create a new explosionsContainer, addChild() any explosions to that, and make it scroll at the same speed as the enemiesContainer.

Put the player’s score, their lives counter, the mute and pause buttons, and any other parts of your game’s interface into a single container. Place this container in front of all other containers, but don’t make it scroll. This is an easy way to keep a game’s camera and assets separate from its interface.

Try having one container stay still while making the containers in front of it and behind it scroll in opposite directions. This creates a cool rotation effect, as seen about five minutes into this clip from Disney’s Snow White!

## Conclusion

Speaking of comments, if you create anything using this tutorial, I’d love it if you posted a link so I could see it :)

• André

This code is very clear and very instructive, congratulations for your tutorial, and thanks a lot

• http://www.robinbrouwer.nl/ Robin

Thanks a lot for your tutorial! I’m planning on making my own game for the iPhone when Flash CS5 hits and can’t wait to put this to good use.

• http://gamedev.michaeljameswilliams.com/ MichaelJW

Thanks, André and Robin, I’m glad you found it useful :)

• http://www.liberatocreative.com Maurizio Liberato

Thanks Michael for the tutorial! very useful! Anything like having the parallax effect on mouse hover? something like http://activeden.net/item/parallax-manager/302

Thx :)

• I’M ALIVE

nice tut, very clear coding! thank you…….

• http://labs.dariux.com Dario Gutierrez

Fantastic Michael!! I will dev a flash game and apply this tips. Thanks.

• http://blog.princeporter.com Porter

Pretty in depth tutorial, many can benefit from this. I don’t think there should ever be a platformer game that doesn’t include this, it makes the game look substantially better. My newest game already has this included, it looks amazing due to some more complex additions we did to the the background and foreground. Awesome tutorial, thanks for sharing.

• http://gamedev.michaeljameswilliams.com/ MichaelJW

Thanks guys :)

@Maurizio: yes, they work off the same principle. If you want to do a similar mouse follow with this tutorial, try this:

At the start of your onEnterFrame() function, put this:

var focusX:Number = ((mouseX/stage.stageWidth)+0.5)*stage.stageWidth;

Then, replace:

…with:

Do the same for your other containers, like so:

hillsContainer.x = (275 – focusX) * 1/5;

You’ll probably want to tweak it more than that, but that’s a pretty good start :)

@Dario: Great!

• André

Excelent, good to see people with post helping here!!

• http://gamedev.michaeljameswilliams.com/ MichaelJW

Oh neat, I didn’t realise you could do nested comments.

• http://www.elimcmakin.com eli mcmakin

fantastic work. Keep it up.

• http://www.w2point.com Web 2.0

A very detailed tutorial, and very useful… Great work.

• http://www.vetgaar.nl/ Phil

Im glad you didnt spend too much time on the graphics. It looks pretty bad in the end but it’s all about the technique on this one. Nicely done.

• http://gamedev.michaeljameswilliams.com/ MichaelJW

Thanks Phil. Yeah, I always find it off-putting when a coding tutorial seems to require amazing art skills to follow, so I try to make mine as simple as possible.

(Though I don’t claim that I could actually make better graphics than these!)

• Daniel Correia

Big thanks!! This tutorial came exactly when I needed. Going to get A+ at school :)

• http://hybridmind.com HybridMind

Great tutorial! Thanks for writing this up. It is always good to see how people solve these 2d staples like viewports and parallax scrolling. Long live 2d games! ;)

• http://gamedev.michaeljameswilliams.com/ MichaelJW

Ahhh, “viewports”! Thanks, I couldn’t remember the right word :)

• http://spotdex.com David Moreen

That is interesting.

• Leo

i love your tutorial ! THanks you so much!

• andrew

very great indeed. workflow is amazing, I have been spending too much time on the design side, need to get back into coding…this is a good start.

BTW, the snow white clip reminded me, has anyone noticed the double standard for Disney films? Snow White takes an apple from an old lady and passes out, the “beast” from beauty and the beast doesn’t help an old lady and he gets transformed…damned if you do damned if you don’t

• http://gamedev.michaeljameswilliams.com/ MichaelJW

Cheers Andrew.

Haha, nice point. I’d never noticed that. Guess Disney found old ladies suspicious :P

• bob synclair

r.e.s.p.e.c.t

• http://www.flashframer.com Flash Framer

Very cool tutorial. Thanks

• some rescue guy

hillsContainer.x = (275 – car.x) * 1/5;

I would show this, but then change it to

hillsContainer.x = (275 – car.x) * 0.2;

Using exact values to increase cpu performance.

• some rescue guy

Thanks a bunch for your help in the past year. The game is close to demo status. Also intresting idea (new approach) to making the camera appear to follow MC. I myself find it common to use a movieclips x&y in calculations.

• http://gamedev.michaeljameswilliams.com/ MichaelJW

Thank you rescue86k :)

You’re right, using 0.2 instead of 1/5 would be slightly faster. I find 1/5 easier to understand at a glance, though.

How does your approach of making the camera follow the MC differ?

• some rescue guy

My approach can be a bit confusing. But basically changing the documents x and y to follow the MC. Through doing this it causes severe lag(moving all objects including the playscreen itself), which is why I spent so much time optimizing code, graphics, and sound. It wasn’t until I did “something” with the game mechanics itself that made things fan out smooth…

• yos

very good tutorial
thx u very much

• rob

Michael,

This is a GREAT tutorial; thanks for showing us how this works! This same effect can be easily done with motion tweens to avoid all that coding, but it’s nice to know how to use code to move things along a timeline. I wouldn’t have had a clue of how to create this effect with code, so it’s nice to see how this works up close!

Cheers!
Rob

• http://gamedev.michaeljameswilliams.com/ MichaelJW

Hey, thanks Rob!

Yeah, that’s a good point about tweens. Even if you wanted to use code-controlled motion, I guess it would be much easier to test out the overall speeds of the layers using tweens in the IDE.

Glad you found it useful :)

• sjaak

Very nice tutorial, very clear to follow and some of the techniques might come in handy some day :) thx alot!

• S

What if you wanted to add more than one road? for instance road 1,2,3,4, how would the code look in order for them to scroll properly?

• http://gamedev.michaeljameswilliams.com/ MichaelJW

Hey S,

//…

…you would have:

//…

If you do this, it’ll work immediately, with no need to change anything else.

Now, to add a third road, you set up a new var called road3 of the symbol RoadThree (let’s say), and then change your scrolling code from this:

{
}
{
}

…to this:

{
}
{
}
{
}

You can then repeat that to use as many different sections of road as you like, as long as they have the same breadth.

{
}
{
}
{
}

Make sense? Hope that helps :)

• trollbringer

how do you stop this on a specific frame?

• http://gamedev.michaeljameswilliams.com/ MichaelJW

You could remove the ENTER_FRAME listener:

removeEventListener( Event.ENTER_FRAME, onEnterFrame );

…though you’ll also want to call:

car.stop();

…if you want the car to stop animating.

• http://nonesxistant Andy

Once again I found myself reading your tutorials, and once again I have to say, awesome Job! My question is, if I wanted the background to stop scrolling once it reaches the end would I have to check the frame in which the x position of the my background reaches the x position of the stage where the stage width is X distance from reaching the end of my background image and once I obain the value remove the event listener? Or can I do it without checking which frame it is at? Like just checking for the distances. For example, if my stage.width is 550, and my background image is 1100, I would check for when the background.x has reached 550 and there I would remove the eventListener. Or do I have to check the frame where this happens?
Also, I would have to create a seperate function for this right? My guess is that if I put it in the onEnterFrame, it would crash because the onEnterFrame occurs when the eventListener is triggered, so if I remove it there, the onEnterFrame in essence will not be triggered, therefore the removal of the eventListener won’t happen. Not sure if this is the right logic or not, it’s just my guess.

• http://michaeljameswilliams.com/ Michael James Williams

Ooh, good question. I’m a little rusty on this code, but I think you can just check the x value of the background (rather than the frames), as you say – though I’m not sure what exactly you would check it against. Your idea sounds like it’s on the right track, at least, or perhaps it’s completely correct :)

No, you don’t have to create a separate function. You can remove an event listener from within that same listener’s handler function, and it’ll work just fine, as the handler’s already been triggered. It just won’t be triggered on the next frames.

• http://qfox.nl qFox

Thanks. I’ve replicated your demo in Javascript only :)
http://qfox.nl/notes/75 and http://car.qfox.nl

• http://gamedev.michaeljameswilliams.com/ MichaelJW

Awesome, thanks for sharing :)

Heh, seems to run faster in JS than AS.

• Nirbhay

Very clearly explained. Thank You.

• http://gamedev.michaeljameswilliams.com/ MichaelJW

Cheers!

• bob

thanks for this tutorial

• Aayush

This is a very nice tutorial and I’ll definitely appreciate you on that account.
But its very lengthy. It can’t be more simpler?…..
Also, In the beginning steps (2, 3 and 4) :- Do we have to make the pictures first and then convert them into symbols or we have to create the symbols first and then make the pictures in it?…….

• http://gamedev.michaeljameswilliams.com/ MichaelJW

Cheers Aayush :)

Yeah, I guess it is lengthy… the final code isn’t that long though, it’s the explanation more than anything.

It’s up to you whether you make the pictures first or the symbols first — it doesn’t matter as long as you end up with some symbols that have images inside them.

• John Smith

Hi Michael,

Really enjoyed the tutorial. Top-class intro to a very cool old-skool technique. It’s amazing how simple this technique is and yet how effective and uber it looks. Using Flash’s built-in support for animation you can do wondrous things with this.

Just a couple of things I noticed:

1. Adding fractional numbers continuously in the way used above (i.e. treeContainer.x = (275 – car.x) * 1/5) will eventually result in floating point precision errors that could lead to “cracks” appearing. This will only happen under specific circumstances. The easiest one to prove off the top of my head would be if this system was used in a game where the player could move back & forward at will with the car. Over time discrepancies would build up in the numbers due to accumulated floating point inaccuracies being multiplied against yet more floats!

The solution to this is to use the base position of objects and then compute a TOTAL offset from the origin of the container. I won’t go into too much detail here, but suffice to say that you would need to store a “base” x & y pos for each parallax object and then add the car’s position as a large offset, multiplied by the parallax factor (1/5 in this example). This would prevent floating point inaccuracies from piling up (multiply is particularly demonic for this type of bug)

2. The code used to determine whether objects need to be “moved” across could easily have been turned into a function taking the “breadth”, x pos and sprite and re-used. The code would have been a lot shorter and easier to understand. However I understand that you are not trying to create the greatest parallax system EVA so that is perfectly fine and the way you have introduced the concept will allow users who read the tutorial to most likely reach the same conclusion and optimize it themselves.

All up, very good work, I enjoyed the tutorial and now I’m going to mess around with this stuff for a game of my own :)

• http://gamedev.michaeljameswilliams.com/ MichaelJW

Thanks John!

1. Good point, and something I hadn’t considered. Though, do you mean the line “tree.x = tree.x + (2 * treeBreadth)” rather than “treeContainer.x = (275 – car.x) * 1/5)”?

I guess the simplest way to get around this would be to use the treeContainer’s x-position as the base point that you mentioned, then, yes, add on some multiple of the car’s position. Nice solution.

2. Great idea! I do like to repeat myself in tutorials in order to hammer certain points home, but you’re right, this could become a great re-usable system. Perhaps you could pass the distance (from the camera), x-pos, and then a list of sprites and their corresponding breadths to the function, so that you could make a tiled background instead of just repeating the same sprite.

Very clearly explained coding. Thanx

• Em

Awesome tutorial, thanks!

I added keyboard controls to move the car. How can I make the backgrounds repeat backwards as well?

• http://michaeljameswilliams.com/ Michael Williams

Thanks Em!

Nice work making the car move with the keyboard. What’ve you tried so far to get the backgrounds to loop backwards?

• Em

Well, to be honest I haven’t been trying very much. Are supposed to make a “flower picking game” as an assignment, I’ve mostly focused on the other parts so far.
Would it work with some kind of hitTestObject? Feels like there should be some quite simple solution, but I just can’t think of any. I tried to… sort of reverse the whole thing. But that didn’t work out very well at all :P

• http://michaeljameswilliams.com/ Michael Williams

Hehe :)

What didn’t work out so well when you tried to reverse it?

• Suprb

Great tutorial! But how do you add buttons to tell the movie clip to scroll to a specific location? Example: http://imaginingmozambique.com/

• http://michaeljameswilliams.com/ Michael Williams

Thanks, Suprb!

What’ve you tried so far?

• Panzer

Michael, I had to say that I used your tutorial to help with an idea that i am doing, but a problem is that when i have the “car” moving, it moves off the screen. but if i stopped the car moving, then how would everything else move when you are using its speed as comparison for every infinite loop?

• http://michaeljameswilliams.com/ Michael Williams

Hey Panzer,

What you’ll need to do is figure out how to calculate the hills/road/mountains/tree x-property based on the car’s x-property. How’s your algebra? ;)

• Matthew McFetridge

Hi :)

I’ve been following this tutorial on parallax scrolling (http://www.computerarts.co.uk/tutorials/new_media/create_3d_effects_and_add_parallax_scrolling) and have been comming up with some problems. I want this to work because I would LOVE to incorperate the skills learnt into a university assignment.

Here is a screen shot to hopfully make up for my bad explaining. http://i711.photobucket.com/albums/ww118/mutedmonkey/FlashError.jpg

I don’t why it isn’t working because to get to this point (after getting lost in the tutorial), I opened the parallax flash file and copied the code from the ‘main’ action script file into the document (all in the download link above). So it seems like a code issue, but this is the code that the author wrote… and all Flash file too.

Essentially I just get an error saying that “packages cannot be nested” error:1037 at line 2. I have been TRAWLING google and the internet to help me but I cannot find an answer. So I was hoping that with all your knowledge you might be able to help me out :)

Also I am using Flash CS5, Windows 7 Ultimate x64. Don’t know if this makes a difference?

• Matthew McFetridge

By the way this tutorial is amazing :)

• http://michaeljameswilliams.com/ Michael James Williams

Hey Matthew,

Thanks!

Looks like the issue here is that you’re pasting the code into the Actions panel for a frame — when using code like this (with a package), you need to enter the code into a separate class.

Check out my guide to using a document class to find out how to do this :)

• http://www.graphiics.com Graphiics

This is just awesome I got many good points from this post loved it

• http://www.benzai.nl Benny

Great tutorial, very well explained and in a fun way too! Good to first show the ‘wrong’ way and afterwards show a better way.
Thanks for this. I’m going to try it out. I need to create a platform like game (with a character) that will we use as menu for a website.

• http://michaeljameswilliams.com/ Michael James Williams

Thanks Benny! I’d love to see the game/menu when it’s done :)

• Paul Wright

I have an awful feeling that this is a really dumb question! Why are we adding the car to the road container? If it just stays added to the stage itself its going to stay in the middle and stll be available to shift forwards or back with some accelartion code?

Ready to go “ahh haa now I get it”! Nice tutorial – thank you. I even got my graphics to look amost the same as yours!

Paul

• http://michaeljameswilliams.com/ Michael James Williams

Hi Paul, that’s not a dumb question at all! If we look at it purely in terms of the car’s position, then you’re right: there’s no reason not to leave it simply added to the stage. But adding it to the road container makes it much easier to keep everything in its own parallax layer.

Also, it’s possible that you might want to offset the car’s parallax layer from the camera a little bit. Think about how, in the old 2D Sonic games, you could run so fast that the camera couldn’t keep up; if the car is added to the road container, then this is an easy effect to replicate: just offset the road container to the right. If the car and the road were both added directly to the stage, then you’d have to manually offset the car’s location to the right, on top of its own speed, and that could get pretty messy.

Hope that helps!

• http://www.spstudios.co.za Paul

That makes good sense. Thanks for this and the wealth of helpfull stuff you are creating

Best

Paul

I’ve usually don’t leave comments, but this was SUCH an amazing tutorial. I really like how you took it step by step from the learner’s perspective instead of just giving us code to copy/paste. Also you demos along the way to make sure we had things going were amazing and your explanation of the actual optics behind parallax. If everyone were like you, the internet would be a much better place.

Cheers!

• http://michaeljameswilliams.com/ Michael James Williams

• shumi

// skipped code for declarations …

if (keyRightPressed)
{
myCar.x += 10;
{
}
{
}
hillsContainer.x = (275 – myCar.x) * 1/5;
if ( hills.x + hillsBreadth + hillsContainer.x < 0 )
{
hills.x = hills.x + (2 * hillsBreadth);
}
if ( hills2.x + hillsBreadth + hillsContainer.x < 0 )
{
hills2.x = hills2.x + (2 * hillsBreadth);
}

}
if (keyLeftPressed)
{
myCar.x -= 10;

}

what should i write for the keyleftpressed and for the for the keyreleased code

great tutorial thank u

• Howard

Very nice tut. I am not a knowledgeable user but I wanted to ask you if this app would be appropriate to use for a dvd menu that has a static photo background of a road that I could scroll down and also use different side camera angles as I move down it. My thought was to fade in additional images of what was once on the side of the road
at each change in camera angle. I am wanting to make the menu actually be part of the story I am going to tell in the dvd video. I have been searching for photoshop & AE tus on this effect but without any luck. I am not a flash user but will learn. Any advise on this or points to tuts would be appreciated.

• http://michaeljameswilliams.com/ Michael James Williams

Sounds like a cool interface! I’m not sure whether you could export Flash to an interactive format that would run on a DVD, though. However, you can export Flash as a mov which should run on a DVD (but which won’t be interactive).

• http://paintndesign.com phil

Michael, whats the best to learn to do this kind of stuff flash or javascript? flash and as3 kinda makes more sense, but for the future whats best to learn?

thanks, very nice work

• http://michaeljameswilliams.com/ Michael James Williams

Thanks Phil. Why not learn both?

The way I see it: HTML5 and JavaScript are going to be around for a long time, and developers are going to keep inventing ways to make it more powerful. It’s going to be everywhere – heck, it already is everywhere: did you know that Windows 8 allows you to make desktop “Metro” apps with HTML5?

Flash, on the other hand, seems to be getting more specialised. It’s never been supported in an iPhone or iPad browser, and by this time next year it’s unlikely to be supported in any new Android phone or tablet browsers, either, or the default Windows 8 tablet browser. On the other hand, you’ll still (I assume) be able to use it to create native apps for tablets and phones, and to create SWFs within webpages for desktop browsers.

I don’t think JavaScript will overtake Flash in hardcore game development capabilities any time soon, so if that’s where your interest lies, stick with Flash, and maybe play with JS on the side. Otherwise, stick with JavaScript, and maybe play with Flash on the side.