HTML5 Game Tutorial – Infinite Runner

HTML5 Game Tutorial – Infinite Runner

In this tutorial, we are going to create an HTML5 infinite runner effect that you can use to create games with, or just to create cool looking websites.

Here is a screen shot of what we will be building.


Infinite Runner (or walker, in this case)


First, let’s create a list of what we will need:


jQuery is my go-to Javascript library. Thankfully, I’m not alone there as it has become very popular over the years. The Greensock Animation Platform (GSAP) is one of, if not the best Javascript animation libraries. They have some cool demos over at their site. The animateSprite plugin is something I found the other day and decided to use it for this project as it rates very high on the easy-to-use scale. I Like easy to use!

Here is a break down of what we need to do:

  1. Craft a basic HTML page
  2. Include all of our resources
  3. Make some terrain and clouds in a photo editor
  4. Get the terrain and clouds to move
  5. Animate our main character (his name is Mark, by the way).
  6. Put some game mechanics in place (Not included in this tutorial)


We are going to cover items 1 though 5. I’ll leave number 6 up to you, or maybe a new tutorial, if enough people are interested.

So, to get started, here is a basic HTML5 page that we will be using.


For this tutorial, I’m putting everything in one page. For anything half-way serious, you would of course use separate files. I find it easier to view source code of other demos when it is all contained in one page as opposed to going though multiple source files to find what I’m looking for.

Let’s now include our 3rd party Javascript libraries. Add these right before our empty <script>  tag.

I’m using the cloudflare CDN for jQuery and GSAP. I didn’t see a CDN link for the animateSprite plugin but I did notice you can install it from bower or download from Github. I used the download from Github and included it locally.

Next, we add some variables and start using jQuery.

Put the above code inside the empty  <script>  tag. These are some global variables we will be using. We should of course be using a plugin style method here, but I’d like to keep these as basic as possible. For those curious, start here.

Now, inside of our jQuery ready function, we will initialize our variables. $(function(){})  is shorthand for the jQuery.ready()  function. Code inside of this function will only be executed after our page is fully loaded into the browser. Learn more about the function over at sitepoint.

Let’s init our variables:

On lines 2 and 3 we are creating a bookmark to our HTML body and container elements. We prefix the variables with a dollar sign as a naming convention to remind ourselves that these are jQuery elements. We can use any jQuery functions on these elements.

Lines 5 to 11 we bind two window events, the resize and keypress events. We will use the resize event to change the height and width of our playing area once the browser loads (line 13) and every time the browser gets resized (line 6). The keypress event isn’t used in this demo, but I’ve included it so you can easily respond to the keyboard and react in any way you see fit.

Lastly, we call our update screen function to size our game initially and then call an init function. More on that later.


Graphics are the hardest part of making games, in my opinion, and are the most important part. Or, at least one of the most important parts. For this demo, we head over to Open Game Art and find some suitable graphics. Some jungle tiles and a character sprite sheet help us get started.

There is a nice website called Stitches by Matthew Cobbs that I found will be used to create a sprite sheet. If you look in the character sprite download from Open Game Art, there are a bunch of individual poses. Drop those onto the Stitches website and you will get a nice sprite sheet that we can use with our animation plugin.


Stitches Sprite Sheet Generator


Download this file and drop it in a folder named images beside our html file we created above. Here is a link to the finished result.

Now, open the jungle tiles Jungle_terrain.png file in your favorite image editor. Along side it, create a new image that is 2400 pixels wide by 768 pixels high with a transparent background. It can be shorter or longer, but that’s what we will use for this tutorial. Now, copy and paste various elements from the Jungle_terrain.png file into your blank image to create a long terrain that has a flat surface to walk/run on. Here is mine as I worked on it:


Once you have a long straight terrain for the character to walk/run on, select and copy just the usable terrain and save it as a transparent image. Here is my finished result:

Now, let’s grab some clouds and put them in a similar file. Like so:

We save these files as terrain.png and clouds.png respectively. The clouds don’t need a transparent background as they are layered behind the terrain, so we can save on the file size.


Ok, now that we have graphics, let’s animate!

Going back to our HTML, we need to add the following to our <container>  tag.

We have a DIV to put our clouds in, and one for our terrain. While we are at it, add the following CSS in the <style>  tag:

After a few default styles for our body and container elements, we position the terrain and clouds in absolute positioning. The clouds at the top of the window, and the terrain at 200px down. The nowrap is important here for our animation technique.

Now, let’s go back to the code and fill in some of our missing function. In the first few code snippets, we referenced a function called updateScreen and one called init. Here are those functions:

This function simply resizes our container to whatever the browser gets resized to.

Now for init():

There is a bit going on here, so let me take it one piece at a time:

Line 2: We need to add an html element to the page in order to display Mark. A div does that nicely. CSS to follow.

Lines 4 – 11 are where the sprite animation magic happens. We reference our Mark element by class, “.mark”, via jQuery selector $(".mark")  and call our animateSprite()  plugin. The plugin takes a list of options in order to set things up.

First, we set our Frames Per Second (fps) to 5. Decease this for slower walking, increase for running. Then, we define our animations. These take a name (walkRight, walkLeft) and an array of frames to cycle through. The frames are numbered from 0. Our mark.png file has two rows of 6 poses, so we fill our the right facing array with comma separated 0 though to 5 and the left facing array with 6 to 11. The plugin assumes our frames are all the same width and height (which they should be for sprite animation) and figures out the math for us. Finally, we set loop equal to true, as we want our character to keep walking/running. There are more options, see the plugin Github page for info.

Line 13: Next, we tell the plugin to start the animation.

Lines 15 & 16: Here, we select our terrain and clouds images, clone them and add the clone to the right of the original. The reason for this will be explain a bit later, but just try removing the clones and seeing what happens.

Lastly, we start our terrain and cloud animations! Before we should that though, we need some CSS for Mark. Add this to our CSS:

Mark is also positioned in an absolute manner with a z-index greater then the other elements so it is always visible. You can play with the left and top positioning to get what feels good for you.

Now, for our scrolling animations.

This is where we use GSAP. Specifically, we use the function. target:Object, duration:Number, vars:Object )

This function takes a target, a duration, and vars (variables) as arguments. Our object will be a jQuery reference to the outer containers for our terrain and cloud images. The DIV with class “.terrain” and “.clouds” classes. Our terrain has a duration of 35 and the clouds have a slower duration of 75, which gives the perception of depth.

For vars, we give the following: x, ease and repeat. “-2400px” tells GSAP to animate the DIV from wherever it is currently (we set it to 0px) to negative 2400 pixels. negative moves to left and positive to the right. Linear.easeNone tells GSAP to just animate smoothly. We could add a bounce or snap effect if we wanted to. -1 means that it should repeat infinitely. A positive number here would only repeat that many times.

Now I will try and explain why we added another copy of each image to the right of our originals. When the animation repeats, it moves back to its original place. Without the trailing copy of the image, we would see the right edge of the image as the animation ended, and then we would see the image “snap” back into place as it moves back to start repeating. The trailing image hides this from the user so it all looks nice and smooth. To fully appreciate this, remove the or comment out the code to clone the images and see what happens.

A big thank you and credit to Shaun Gorneau over at the GSAP forums for help with the scrolling. I was over thinking my solution to get the background to scroll infinitely and he provided some much needed clarity.

Now, I’ll add in the code for the keypress event handler:

At this point, you should be able to run the demo!


agrothe (9 Posts)

Andrew Grothe is an enterprise developer with an interest in HTML5 mobile and game development. Andrew is current working on a casual HTML5 game at and maintains the website.