Corona SDK: Creating a Scrolling Background

Corona SDK: Creating a Scrolling Background

Tutorial Details
  • Technology: Corona SDK Build 2011.561
  • Difficulty: Intermediate
  • Estimated Completion Time: 45 Minutes

The Corona SDK makes game development for the iPhone, iPad, and Android easy. Corona uses the Lua programming language to create cross-platform apps. In this tutorial we will explore how to create a scrolling background with the Corona SDK.

Brief Overview

scrolling background Corona SDK

The Corona SDK makes it very easy to create dynamic effects with very few lines of code. Using the Corona SDK, we will create a scrolling 2D background with graphics that we create in Photoshop. This tutorial will not cover designing for a particular device. Instead, the scrolling background we create can be used for the iPhone, iPad, or Android platforms.

Create the Graphics

Using Photoshop, we are going to use the Custom Shape Tool to create stars for our background. While you can theoretically use any shape for the background this tutorial will demonstrate how to create a “starry night” background.

With Photoshop open, create a new document that is 45×45 pixels.

Select the Custom Shape Tool and select the 5 Point Star as your custom shape. If you cannot find the 5 Point Star, you may have to append the list with the Shapes list.

scrolling background Corona SDK

After you have selected the 5 Point Star, make sure your foreground color is white and draw a star on a new layer.

scrolling background Corona SDK

Exporting the Graphics

Now that we have drawn a star, use the Save for Web & Devices tool to save the star in 3 different sizes:

Star1.png 45×45 pixels
Star2.png 30×30 pixels
Star3.png 15×15 pixels

Code

With our graphics, we can start creating the scrolling background. Let’s get started by opening your preferred Lua editor and create a new document called main.lua.

Hide the Status Bar

Our first step is to hide the status bar. The status bar is a bar at the top of the screen that gives information to the user such as signal strength or battery level.

display.setStatusBar( display.HiddenStatusBar );

Variables

We will now set up some variables to be used throughout our program.

_W = display.contentWidth; --Returns Screen Width
_H = display.contentHeight; --Returns Screen Height
local starTable = {} -- Set up star table

Set Up Star Table

After we have initialized some global variables, we are going to insert star objects into the starTable. In this table, we identify the image path of the stars and the movement speed of each star. Then we insert the star into starTable.

Movement Speed is calculated in milliseconds and will determine how fast it will take the star to move from the bottom of the screen to the top of the screen. The bigger stars will move slightly faster than the smaller stars to give the illusion of depth to the background.

function initStar()
	local star1 = {}
	star1.imgpath = "star1.png"; --Set Image Path for Star
	star1.movementSpeed = 10000; --Determines the movement speed of star in milliseconds
	table.insert(starTable, star1); --Insert Star into starTable
	local star2 = {}
	star2.imgpath = "star2.png";
	star2.movementSpeed = 12000;
	table.insert(starTable, star2);
	local star3 = {}
	star3.imgpath = "star3.png";
	star3.movementSpeed = 14000;
	table.insert(starTable, star3);
end

Moving the Stars

The getRandomStar function returns a random star object from the starTable. Once the function gets the star, we set the image path, the name of the star and how fast the star will move. Here is what the complete function looks like.

	function getRandomStar()
	local temp = starTable[math.random(1, #starTable)]
	local randomStar = display.newImage(temp.imgpath)
	physics.addBody(randomStar, { isSensor = true } )
	randomStar.myName = "star"
	randomStar.movementSpeed = temp.movementSpeed;
randomStar.x = math.random(0,_W)
	randomStar.y = _H + 50
	randomStar.rotation = math.random(0,360)
	starMove = transition.to(randomStar, {
		time=randomStar.movementSpeed,
		y=-45,
		onComplete = function(self) self.parent:remove(self); self = nil; end
		})
end

Getting a Random Star

The first line gets a random star from the starTable and stores it in the local variable randomStar.

local temp = starTable[math.random(1, #starTable)]

Star Image Path

After we retrieve a random star, we will set the image path of the star.

local randomStar = display.newImage(temp.imgpath)

Star Name and Speed

Now, we will set the name of the star object to “star” and the movement speed will be set according to the speed of the random star that we pulled from the starTable.

randomStar.myName = "star"
randomStar.movementSpeed = temp.movementSpeed; -- in milliseconds

Star Starting Point

The starting point of the star is going to be a random X position on the bottom of the screen. The star will also start off the screen for a smoother transition into the visible area of the screen. We also randomly rotate each star to add variance to the background.

randomStar.x = math.random(0,_W)
randomStar.y = _H + 50
randomStar.rotation = math.random(0,360)

Moving the Star

After the star has been set up, we can use the transition.to() method to move the star towards the top of the screen. The star object will then be removed from memory when it has reached its destination point.

starMove = transition.to(randomStar, {
		time=randomStar.movementSpeed,
		y=-45,
		onComplete = function(self) self.parent:remove(self); self = nil; end
		})

Starting the Timers

This function sets up three timers that will call on the getRandomStar function to generate the star object and start the star moving towards the top of the screen.

The first parameter in timer.performWithDelay is the delay, which determines how many times the timer will be called. The second parameter is the function that will be called and the last parameter is the number of times the timer will be called. A value of “0” tells the timer to loop forever.

function startGame()
	starTimer1 = timer.performWithDelay(1700,getRandomStar, 0)
	starTimer2 = timer.performWithDelay(2300,getRandomStar, 0)
	starTimer3 = timer.performWithDelay(2700,getRandomStar, 0)
end

Start the App

Finally, we can run our app. The following code calls the functions that we have created throughout the tutorial to start the creating the stars, moving them towards the top of the screen and removing them when they have reached the sensor bar.

	initStar()
startGame()

Conclusion

You can use a 2D scrolling background in a variety of games and utilizing a scrolling background is an easy way to make games more dynamic. Try swapping out the stars for clouds, leaves, or anything else that you can think of!

Thank you for reading!

Note: Want to add some source code? Type <pre><code> before it and </code></pre> after it. Find out more
  • Guillermo

    Daniel,

    Einfach Klasse!!

    Daniel, excelente tutorial gracias por tu colaboración.

    Thanks for this great, easy and functional Tutorial, really productive.

    Best,

    Guillermo.

  • Daniel
    Author

    Thank you Guillermo!

  • http://www.balancebikes4kids.com Balance Bikes 4 Kids

    I’m a hobbyist at this point, but have been working on a game app to use to promote my online store (we sell balance bikes). I was looking for something that would help me create a scrolling background of a sidewalk, houses, mailboxes, etc. This definitely helped me understand how scrolling can work using Corona.

    Thanks Daniel!

  • http://www.smartscreenuk.com IPete2

    Hey,

    Brilliant tutorial – very comprehensive and it works beautifully (with the addition of):

    local physics = require(“physics”);
    physics.start();

    Thanks very for t.

    IPete2

  • Jay T

    Thanks for the awesome tutorial!

    I’m using this to create a moving background — I put it in the main.lua file while using Director.
    Do you know how to move the stars to the background? I know you can do toBack(), but not sure which group/object to send back…

    Thanks!

  • Mad Geek

    I just modified the code so that stars come from upside down but it is not working… what am i doing wrong.

    function getRandomStar()
    local temp = starTable[math.random(1, #starTable)] — Get a random star from starTable
    local randomStar = display.newImage(temp.imgpath) — Set image path for object
    randomStar.myName = “star” — Set the name of the object to star
    randomStar.movementSpeed = temp.movementSpeed; — Set how fast the object will move

    randomStar.x = math.random(0,_W) — Set starting point of star at a random X position
    randomStar.y = -50 — Start the star off screen
    randomStar.rotation = math.random(0,360) — Rotate the object
    starMove = transition.to(randomStar, {
    time=randomStar.movementSpeed,
    y=+45,
    onComplete = function(self) self.parent:remove(self); self = nil; end
    }) — Move the star
    end–END getRandomStar()

    • YK

      Set the randomStar.y = 0 and y = _H like below:

      – returns a random star object from the starTable.
      function getRandomStar()
      local temp = starTable[math.random(1, #starTable)];

      local randomStar = display.newImage(temp.imgpath);
      –physics.addBody(randomStar, {isSensor = true});
      randomStar.myName = “star”;
      randomStar.movementSpeed = temp.movementSpeed;
      – set the star starting point
      randomStar.x = math.random(0, _W);
      randomStar.y = 0;
      randomStar.rotation = math.random(0, 360);
      – move the star
      starMove = transition.to(randomStar, {
      time = randomStar.movementSpeed,
      y = _H,
      onComplete = function(self)
      self.parent:remove(self);
      self = nil;
      end
      });
      end

  • Ryan

    —————————————————————————————–

    – main.lua

    —————————————————————————————–

    – hide the status bar
    display.setStatusBar( display.HiddenStatusBar )

    – include the Corona “storyboard” module
    local storyboard = require “storyboard”

    – load menu screen
    storyboard.gotoScene( “menu” )
    local textObject = display.newText( “Nigahiga’s “, 80, 50, native.systemFont,24 )
    local textObject = display.newText( “is Escape From The Finger “, 10, 130, native.systemFont,24 )

    _W = display.contentWidth; –Returns Screen Width
    _H = display.contentHeight; –Returns Screen Height
    local starTable = {} — Set up star table

    function initStar()
        local star1 = {}
        star1.imgpath = “star1.png”; –Set Image Path for Star
        star1.movementSpeed = 10000; –Determines the movement speed of star in milliseconds
        table.insert(starTable, star1); –Insert Star into starTable
        local star2 = {}
        star2.imgpath = “star2.png”;
        star2.movementSpeed = 12000;
        table.insert(starTable, star2);
        local star3 = {}
        star3.imgpath = “star3.png”;
        star3.movementSpeed = 14000;
        table.insert(starTable, star3);
    end

    function getRandomStar()
    local temp = starTable[math.random(1, #starTable)]
    local randomStar = display.newImage(temp.imgpath)
    physics.addBody(randomStar, { isSensor = true } )
    randomStar.myName = “star”
    randomStar.movementSpeed = temp.movementSpeed;
    randomStar.x = math.random(0,_W)
    randomStar.y = _H + 50
    randomStar.rotation = math.random(0,360)
    starMove = transition.to(randomStar, {
    time=randomStar.movementSpeed,
    y=-45,
    onComplete = function(self) self.parent:remove(self); self = nil; end
    })
    end

    local temp = starTable[math.random(1, #starTable)]

    local randomStar = display.newImage(temp.imgpath)

    randomStar.myName = “star”
    randomStar.movementSpeed = temp.movementSpeed; — in milliseconds

    randomStar.x = math.random(0,_W)
    randomStar.y = _H + 50
    randomStar.rotation = math.random(0,360)

    time=randomStar.movementSpeed,
    y=-45,
    onComplete = function(self) self.parent:remove(self); self = nil; end
    })

    function startGame()
    starTimer1 = timer.performWithDelay(1700,getRandomStar, 0)
    starTimer2 = timer.performWithDelay(2300,getRandomStar, 0)
    starTimer3 = timer.performWithDelay(2700,getRandomStar, 0)
    end

    initStar()
    startGame()

    Does anyone understand why this doesn’t work??

    • Ryan

      The screen just goes black

  • http://www.facebook.com/henry.chenphd Henry Chen Phd

    I have combined the scrolling background with my storyboard, so the scrolling background became one of the scenes in my ebook template.
    But, when I pressed back button to go back to the Table of Contents, I found the stars also showed up in my TOC. I have been trying hard to deal with this problem, but so far I don’t have any luck. I believe there are two possible problems:
    First, I haven’t actually destroy the scene when I turned to other page.
    Second, I haven’t actually put the scrolling background in the local group.
    Please advise how to deal with the problem. Thank you in advance.
    My email is Dr.Henry.Chen@gmail.com

  • Jez

    Thanks this is really helpful.
    I have got it working nicely in only the top half of the screen.
    I also added a random shooting star every 5 minutes or so…

    Now i am trying to put the images into a display group in a director setup.
    I can’t seem to get it to display.
    The concept is that it shows day/night depending on the time.
    If the hour is past a certain time, the night image show really well.
    I want to add stars to a display group that is only only visible sometimes, but not sure how

    Any suggestions?

    Thanks

  • eight studio

    Hi Daniel, just a question. If I want change the direction. If I have my device in landscape mode.