Chapter 4 — 创建场景(Creating Scenes)
Just as movies, television shows, and plays are organized into scenes for the telling of a story, apps are similarly arranged. In this chapter, you’ll learn the basics of scene management in Solar2D.
- Game Flow
- Scene Management
- Menu Scene
- Chapter Concepts
Game Flow
A scene is an isolated view or “page” of the app and everything that the player sees is contained in that scene. When an app starts, you’re usually presented with a title/intro scene. From there, you may be able to navigate to a settings scene or proceed to a tutorial. Each level in a game might also be a dedicated scene, depending on the design goals.
This game will have three core scenes:

- Menu — Title/intro scene containing various options.
- Game — The actual game scene.
- High Scores — A list of high scores.
Scene Management
Solar2D uses a system called Composer to handle moving from scene to scene. To make development easier, each Composer scene is a separate Lua file — this helps keep your game more organized.
In this chapter, we’re going to make changes to your previous code that will temporarily create errors in the Simulator. For now, you can either ignore the errors or exit the Simulator until you’re ready to see the results.
Let’s modify the existing project to use Composer:
-
Within your project folder, make a copy of the main.lua file and rename it to main_original.lua. We will need this original code in the next chapter, so it’s important to keep a copy for reference.
-
Using your chosen text editor, open the main.lua file (not the copy). In this file, erase all of your previous code — remember, you still have the copy to work with later.
-
In its place, add the following commands:
local composer = require( "composer" )-- Hide status bardisplay.setStatusBar( display.HiddenStatusBar )-- Seed the random number generatormath.randomseed( os.time() )-- Go to the menu screencomposer.gotoScene( "menu" )
Let’s inspect these commands in a little more detail:
-
The first line, local composer = require( "composer" ), creates a local variable called composer, and the require() command tells Solar2D to load all of the information about the Composer scene management library into the app.
-
The next command hides the status bar at the top of the device. Although you included this line in the previous chapter’s code, it’s logical to hide the status bar within main.lua of any Composer-enabled app so that it never appears in any scene.
-
Next, we set the “seed” for the pseudo-random number generator (recall that this command was included in our original project). Essentially, if you’re using math.random() anywhere in an app, it’s a good idea to call math.randomseed() inside main.lua so that the seed is reset each and every time the app runs.
-
Just one more command and we’re finished with main.lua. The composer.gotoScene( "menu" ) command takes advantage of the first line where we loaded Composer into the app. By doing so, we can now use this composer.gotoScene() command to tell Solar2D to load a different scene. As mentioned earlier, each of our scenes will be contained in their own Lua files: menu.lua, game.lua, and highscores.lua.
For this command, you don’t need to include .lua in the quotation marks because Solar2D already expects the file to have the .lua extension. Thus, you can simply use "menu" to go to the scene that will be contained in menu.lua.
composer.gotoScene( "menu" )
That’s it for main.lua — remember to save your changes! Unlike the previous project, this main.lua file is very short because we’re only using it to initialize Composer, hide the status bar, seed the random number generator, and move to the menu scene where the action starts.
Menu Scene
It’s time to create our first scene! The menu scene will consist of a background, title image, and two text objects which will behave as buttons.
When using Composer for scene management, we suggest that you begin with our standard scene template(scene-template.lua), included with this chapter’s source files. Please obtain this template file before you proceed further.
Including Images
For this scene, you’ll need to copy or create one additional image file and place it within your StarExplorer project folder. The default image is available for download as part of this chapter’s source files.
| File | Size (w×h) | Usage | | —- | —- | —- |`` | title.png | 500 × 80 | The game title image; will overlay our existing stars background. |
Scene Setup
Once you have the scene-template.lua file, make a copy of it. Rename this copy to menu.lua and place it inside your StarExplorer project folder. Using your text editor, open this menu.lua file and briefly inspect it. It may look overwhelming, but don’t worry, we’ll step through it together.
To begin, inspect these initial two commands:
local composer = require( "composer" )local scene = composer.newScene()
The first line, local composer = require( "composer" ), tells Solar2D to utilize the Composer library in this Lua file. This line must be included in every Composer scene.
The second line, local scene = composer.newScene(), essentially creates a new variable named scene that holds a Composer scene object. This variable (scene) will become important later in the file, as you’ll see shortly.
Accessible Code
Next, you’ll see a comment block talking about the execution of scene event functions, followed by a few blank lines. This is where you should usually write your functions which pertain to scene behavior, declare variables which the scene must have persistent access to, etc. Don’t worry too much about this now — you’ll learn how it all works as we go along.
For this menu screen, we only need two simple functions:
- The
gotoGame()function which tells Composer to move to the game scene (we’ll create this scene in the next chapter). - The
gotoHighScores()function that will show the high scores scene (we’ll create this scene in a later chapter).
Let’s write these functions in this scene-accessible space:
-- ------------------------------------------------------------------------------------- Code outside of the scene event functions below will only be executed ONCE unless-- the scene is removed entirely (not recycled) via "composer.removeScene()"-- -----------------------------------------------------------------------------------local function gotoGame()composer.gotoScene( "game" )endlocal function gotoHighScores()composer.gotoScene( "highscores" )end
These functions are about as basic as they come — each contains just one command, composer.gotoScene() , which you’ll recognize from earlier as the Composer command to change scenes.
Scene Events
Following this, you’ll see a section reserved for scene event functions. Composer scenes can utilize four (4) life cycle events, each triggered at different points in the scene’s life:
| Scene Event | Life Cycle Point |
|---|---|
| create | Occurs when the scene is first created but has not yet appeared on screen. |
| show | Occurs twice, immediately before and immediately after the scene appears on screen. |
| hide | Occurs twice, immediately before and immediately after the scene exits the screen. |
| destroy | Occurs if the scene is destroyed. |
Our standard template can handle all four events, but the create event is what we’ll focus on in this scene. A bit further down in the file, inspect the following highlighted code:
-- ------------------------------------------------------------------------------------- Scene event functions-- ------------------------------------------------------------------------------------- create()function scene:create( event )local sceneGroup = self.view-- Code here runs when the scene is first created but has not yet appeared on screenend
As you recall, the keyword function tells Solar2D that this block of code is a function. However, this declaration varies slightly — instead of prefacing function with the local keyword, we use the Lua object method discussed in the first chapter to associate this function with the scene variable created near the top of the file (local scene = composer.newScene()).
Essentially, :create( event ) indicates that this function will be associated with the Composer create scene event and that a table of data that we reference with event will be passed to the function.
Scene Creation
The scene:create() function is already set up for you, but it doesn’t really do anything yet. Let’s start modifying it to create the actual scene.
First, inspect the initial line already inside the function, local sceneGroup = self.view:
function scene:create( event )local sceneGroup = self.view-- Code here runs when the scene is first created but has not yet appeared on screenend
This important line creates a local reference to the scene’s view group, automatically created by Composer, which should contain all of the display objects used in the scene. Essentially, any display object which should be part of the scene must be inserted into the scene’s view group, and that group is referenced by sceneGroup inside each of the template’s default scene: functions.
Following the local sceneGroup = self.view command, enter the following highlighted lines to add a background image to the scene. For this project, we’ll simply use the same background image (background.png) that we used for the actual game in the previous chapter, although you’re free to use a different image.
function scene:create( event )local sceneGroup = self.view-- Code here runs when the scene is first created but has not yet appeared on screenlocal background = display.newImageRect( sceneGroup, "background.png", 800, 1400 )background.x = display.contentCenterXbackground.y = display.contentCenterYend
Pertaining directly to the important note above, we insert this background image into sceneGroup so that it will be automatically managed by Composer as part of this scene.
Next, let’s add the title image to the scene with these commands:
local background = display.newImageRect( sceneGroup, "background.png", 800, 1400 )background.x = display.contentCenterXbackground.y = display.contentCenterYlocal title = display.newImageRect( sceneGroup, "title.png", 500, 80 )title.x = display.contentCenterXtitle.y = 200end
Finally, let’s create two objects which will become menu choices for the player. One will prompt the player to start the game and the other will load the high scores scene. For simplicity at this point, we’ll use text objects instead of graphical buttons:
local title = display.newImageRect( sceneGroup, "title.png", 500, 80 )title.x = display.contentCenterXtitle.y = 200local playButton = display.newText( sceneGroup, "Play", display.contentCenterX, 700, native.systemFont, 44 )playButton:setFillColor( 0.82, 0.86, 1 )local highScoresButton = display.newText( sceneGroup, "High Scores", display.contentCenterX, 810, native.systemFont, 44 )highScoresButton:setFillColor( 0.75, 0.78, 1 )end

Let’s check the result of our code so far. Save your modified menu.lua file and then relaunch/restart the Simulator. If all went well, the menu background and text buttons should now be showing.
Finally, now that we have our visual objects in place, let’s tie together the scene functionality. This will be similar to the previous project where we made the balloon detect the player’s taps. Each text object will have its own tap handler which will call the gotoGame() and gotoHighScores() functions respectively.
Following the previous commands, add the following highlighted lines:
local playButton = display.newText( sceneGroup, "Play", display.contentCenterX, 700, native.systemFont, 44 )playButton:setFillColor( 0.82, 0.86, 1 )local highScoresButton = display.newText( sceneGroup, "High Scores", display.contentCenterX, 810, native.systemFont, 44 )highScoresButton:setFillColor( 0.75, 0.78, 1 )playButton:addEventListener( "tap", gotoGame )highScoresButton:addEventListener( "tap", gotoHighScores )end
This should be clear — each command simply adds a "tap" event listener to the appropriate text object. With these in place, the gotoGame() function that we wrote earlier will be called when the player taps anywhere on the playButton text, and likewise for gotoHighScores() when the highScoresButton text is tapped.
Tapping either of the buttons now will result in an error because we haven’t yet created the target scenes. In the next chapter, we will convert our previous game code into the game.lua Composer scene, and later create the highscores.lua scene as well.
If your code isn’t working as expected, please compare it to the menu.lua file bundled with this chapter’s source files. Fortunately, this scene is relatively easy because we only need to account for its scene:create() function.
Chapter Concepts
We’ve introduced just a couple more concepts in this chapter, both related to Composer:
| Command/Property | Description |
|---|---|
| composer.newScene() | Creates a new scene object which can be used with the Composer library. |
| composer.gotoScene() | Transitions to a specific Composer scene. |
#
⟨Chapter 3 — Bringing it to Life|Chapter 5 — Converting the Game to Composer⟩
© 2020-2026 Solar2D. All Rights Reserved.
Help us help you! If you notice a problem with this page, please report it.
Report an Issue
- corona-key-plugins.png
- ponywolf-sk8boarder-1.png
- ponywolf-platformer-1.png
- ponywolf-match3-1.png
- badge-steam.png
- badge-android-tv.png
- badge-tvos.png
- badge-mac.png
- badge-windows.png
- badge-amazon.png
- badge-google-play.png
- badge-app-store.png
- corona-live-builds.png
- sbs-starexplorer-icon.png
- anchor-diagram.png
- sbs-starexplorer-10.png
- sbs-scene-diagram.png
- sbs-starexplorer-9.png
- sbs-starexplorer-8.png
- sbs-starexplorer-7.png
- sbs-starexplorer-6.png
- sbs-starexplorer-5.png
- sbs-starexplorer-4.png
- sbs-starexplorer-3.png
- sbs-starexplorer-2.png
- sbs-starexplorer-13.png
- sbs-starexplorer-12.png
- sbs-starexplorer-1.png
- sbs-starexplorer-11.png
- content-zoomeven.png
- content-letterbox.png
- sbs-starexplorer-0.png
- sbs-balloon-4.png
- sbs-balloon-3.png
- pastel-rocket.png
- axes.png
- sbs-balloon-2.png
- sbs-balloon-1.png
- sbs-balloon-0.png
