Level reset / restart button

Hello!

I want to restart the level (stage) at the touch of a button.

But I did not find normal information on the Internet or on YouTube!

I understand this is a hot topic.

I do not want to link to another scene, that is:

Level 1. Lua -> Restart. Lua -> Level 1. Lua

I want to make a scene restart in the same scene!

Level 1. Lua -> // push the button restart // -> Level 1. Lua

How can I do this? I have 3 days watching YouTube and shake Examples Guide hub.

Corona! Help!

Generally a game scene is made up of objects.  Those objects have various actions applied to them:
 

  1. Create them

  2. Position them

  3. Move them

  4. Modify them

  5. Destroy them

Creating is pretty straight forward. In general you create objects in scene:create(), though spawns typically are created when they are needed during game play.

Positioning is easy during scene creation or spawning, they have an X, Y that needs set.

Moving becomes a bit more tricky. If you’re using transitions or enterFrame listeners to move things around, you just have to change their X, Y back to their starting position. If your object rotated, you would need to reset it. Adding Physics in the mix means you also are dealing with momentum both linear and angular.

You may modify your objects beyond movement (location, angle) by having the object have properties like “health” if it takes multiple hits to destroy the object. Or if you change colors, use a sprite and it’s using a different animation (walk vs stand).

Finally you’ve probably destroyed some of the objects along the way (picked up coins, power ups, killed enemies etc.)

So what does restarting all of this mean? It means your restart button has to call a function that:

a) recreates anything that was destroyed

b) re-positions anything that was moved

c) restart any timers, transitions, physics (which could involve removing/re-adding physics bodies), or other things that puts your game in motion.

d) reset any stat things like health, points etc.

You probably should have two functions declared above scene:create()

local function resetObjects()       do a, b and d here end local function restartGame()      do c here end local function handleRestartButton() -- assuming tap or widget.newButton onRelease or onPress handler      resetObjects()      restartGame() end function scene:create()     create non destroyable things like normal     call resetObject() to create everything else end function scene:show()     if event.phase == "did" then         restartGame()     end end

Depending on your game, this may be pretty straight forward. But it could be fairly complex.  Creating a reset scene/next level/game over/try again scene where you can destroy the entire game scene and start over can be much, much similar.

 
I tried to do so. Calling the scene button restart. The scene is reloaded, but the effect of the transition occurs only the first time and every time you press the button, the number of objects doubles!

local composer = require( "composer" ) local physics = require( "physics" ) local scene = composer.newScene() display.setDefault( "background", 0, 1, 0 ) physics.start( ) local restart = display.newImage( "restart.png", 250, 0 ) function onTouch (event) if ( event.phase == "began" ) then composer.removeScene("main") composer.gotoScene( "main", "fade", 800 ) end end restart:addEventListener( "touch", onTouch ) function scene:create( event ) --print( "ВТОРАЯ СЦЕНА СОЗДАЕТСЯ" ) local sceneGroup = self.view local ball = display.newImage( "ball.png", 100, 0 ) physics.addBody( ball, "dinamic", { friction = 0.3, density = 0.01 } ) sceneGroup:insert(ball) end function scene:show( event ) local sceneGroup = self.view local phase = event.phase if ( phase == "will" ) then elseif ( phase == "did" ) then end end function scene:hide( event ) local sceneGroup = self.view local phase = event.phase if ( phase == "will" ) then elseif ( phase == "did" ) then end end function scene:destroy( event ) local sceneGroup = self.view end scene:addEventListener( "create", scene ) scene:addEventListener( "show", scene ) scene:addEventListener( "hide", scene ) scene:addEventListener( "destroy", scene ) return scene

FuRFAvHP1Sk.jpg

OvUE-Fwlizs.jpg

Could I have done what that stupid mistake …?

Here’s how I did it! Created and deleted!

But would not it be my application to consume a lot of memory?

local composer = require( "composer" ) local physics = require( "physics" ) local scene = composer.newScene() display.setDefault( "background", 0, 1, 0 ) physics.start( ) local restart = display.newImage( "restart.png", 250, 0 ) function create\_obj( ) ball = display.newImage( "ball.png", 100, 0 ) physics.addBody( ball, "dinamic", { friction = 0.3, density = 0.01 } ) end create\_obj() function onTouch (event) if ( event.phase == "began" ) then display.remove( ball ) create\_obj() end end restart:addEventListener( "touch", onTouch )

Back to your previous post.

main.lua should not be used as a scene. While I’m sure with some work you can make it work, its much better if main.lua is simply:

local composer = require(“composer”)

composer.gotoScene(“game.lua”)

and any other one-time initialization that needs done.

But the next problem is if main.lua is your scene and you try to remove it, the system has nothing to display.  This is why we recommend a game over level. It makes life so easy.

Into your second post, yes, that works. But a)  your not using Composer and b ) if you’re game gets any more complex than that, you’re going to running into a ton of work to manage your objects.

Rob

I loaded really big levels and tired to reset using this method. Let me tell you it was not worth the convenience, assuming your levels stay really small and not display to many objects.

Thanks corona! I understood you!

I found another way.

If you click I move to a new stage, and out of it quickly turn back. How do you make that decision?

main.lua -> menu.lua -> game.lua -> // press button “restart” // -> restart.lua (and quickly turn on) -> game.lua

For the user, not much that I move to a new stage! And it looks great. Memory problems can be?

game.lua

local composer = require( "composer" ) local physics = require( "physics" ) local scene = composer.newScene() display.setDefault( "background", 0, 1, 0 ) physics.start( ) local restart = display.newImage( "restart.png", 250, 0 ) function onTouch (event) if ( event.phase == "began" ) then composer.removeScene("main") composer.gotoScene( "restart" ) end end restart:addEventListener( "touch", onTouch ) function scene:create( event ) --print( "ВТОРАЯ СЦЕНА СОЗДАЕТСЯ" ) local sceneGroup = self.view local ball = display.newImage( "ball.png", 100, 0 ) physics.addBody( ball, "dinamic", { friction = 0.3, density = 0.01 } ) sceneGroup:insert(ball) end function scene:show( event ) local sceneGroup = self.view local phase = event.phase if ( phase == "will" ) then elseif ( phase == "did" ) then end end function scene:hide( event ) local sceneGroup = self.view local phase = event.phase if ( phase == "will" ) then elseif ( phase == "did" ) then end end function scene:destroy( event ) local sceneGroup = self.view end scene:addEventListener( "create", scene ) scene:addEventListener( "show", scene ) scene:addEventListener( "hide", scene ) scene:addEventListener( "destroy", scene ) return scene

restart.lua

local composer = require( "composer" ) local scene = composer.newScene() local composer = require( "composer" ) local scene = composer.newScene() -- create() function scene:create( event ) local sceneGroup = self.view end -- show() function scene:show( event ) local sceneGroup = self.view local phase = event.phase if ( phase == "will" ) then elseif ( phase == "did" ) then composer.removeScene("restart") composer.gotoScene( "main", "fade" ) end end -- hide() function scene:hide( event ) local sceneGroup = self.view local phase = event.phase if ( phase == "will" ) then elseif ( phase == "did" ) then end end -- destroy() function scene:destroy( event ) local sceneGroup = self.view end scene:addEventListener( "create", scene ) scene:addEventListener( "show", scene ) scene:addEventListener( "hide", scene ) scene:addEventListener( "destroy", scene ) return scene

Generally a game scene is made up of objects.  Those objects have various actions applied to them:
 

  1. Create them

  2. Position them

  3. Move them

  4. Modify them

  5. Destroy them

Creating is pretty straight forward. In general you create objects in scene:create(), though spawns typically are created when they are needed during game play.

Positioning is easy during scene creation or spawning, they have an X, Y that needs set.

Moving becomes a bit more tricky. If you’re using transitions or enterFrame listeners to move things around, you just have to change their X, Y back to their starting position. If your object rotated, you would need to reset it. Adding Physics in the mix means you also are dealing with momentum both linear and angular.

You may modify your objects beyond movement (location, angle) by having the object have properties like “health” if it takes multiple hits to destroy the object. Or if you change colors, use a sprite and it’s using a different animation (walk vs stand).

Finally you’ve probably destroyed some of the objects along the way (picked up coins, power ups, killed enemies etc.)

So what does restarting all of this mean? It means your restart button has to call a function that:

a) recreates anything that was destroyed

b) re-positions anything that was moved

c) restart any timers, transitions, physics (which could involve removing/re-adding physics bodies), or other things that puts your game in motion.

d) reset any stat things like health, points etc.

You probably should have two functions declared above scene:create()

local function resetObjects()       do a, b and d here end local function restartGame()      do c here end local function handleRestartButton() -- assuming tap or widget.newButton onRelease or onPress handler      resetObjects()      restartGame() end function scene:create()     create non destroyable things like normal     call resetObject() to create everything else end function scene:show()     if event.phase == "did" then         restartGame()     end end

Depending on your game, this may be pretty straight forward. But it could be fairly complex.  Creating a reset scene/next level/game over/try again scene where you can destroy the entire game scene and start over can be much, much similar.

 
I tried to do so. Calling the scene button restart. The scene is reloaded, but the effect of the transition occurs only the first time and every time you press the button, the number of objects doubles!

local composer = require( "composer" ) local physics = require( "physics" ) local scene = composer.newScene() display.setDefault( "background", 0, 1, 0 ) physics.start( ) local restart = display.newImage( "restart.png", 250, 0 ) function onTouch (event) if ( event.phase == "began" ) then composer.removeScene("main") composer.gotoScene( "main", "fade", 800 ) end end restart:addEventListener( "touch", onTouch ) function scene:create( event ) --print( "ВТОРАЯ СЦЕНА СОЗДАЕТСЯ" ) local sceneGroup = self.view local ball = display.newImage( "ball.png", 100, 0 ) physics.addBody( ball, "dinamic", { friction = 0.3, density = 0.01 } ) sceneGroup:insert(ball) end function scene:show( event ) local sceneGroup = self.view local phase = event.phase if ( phase == "will" ) then elseif ( phase == "did" ) then end end function scene:hide( event ) local sceneGroup = self.view local phase = event.phase if ( phase == "will" ) then elseif ( phase == "did" ) then end end function scene:destroy( event ) local sceneGroup = self.view end scene:addEventListener( "create", scene ) scene:addEventListener( "show", scene ) scene:addEventListener( "hide", scene ) scene:addEventListener( "destroy", scene ) return scene

FuRFAvHP1Sk.jpg

OvUE-Fwlizs.jpg

Could I have done what that stupid mistake …?

Here’s how I did it! Created and deleted!

But would not it be my application to consume a lot of memory?

local composer = require( "composer" ) local physics = require( "physics" ) local scene = composer.newScene() display.setDefault( "background", 0, 1, 0 ) physics.start( ) local restart = display.newImage( "restart.png", 250, 0 ) function create\_obj( ) ball = display.newImage( "ball.png", 100, 0 ) physics.addBody( ball, "dinamic", { friction = 0.3, density = 0.01 } ) end create\_obj() function onTouch (event) if ( event.phase == "began" ) then display.remove( ball ) create\_obj() end end restart:addEventListener( "touch", onTouch )

Back to your previous post.

main.lua should not be used as a scene. While I’m sure with some work you can make it work, its much better if main.lua is simply:

local composer = require(“composer”)

composer.gotoScene(“game.lua”)

and any other one-time initialization that needs done.

But the next problem is if main.lua is your scene and you try to remove it, the system has nothing to display.  This is why we recommend a game over level. It makes life so easy.

Into your second post, yes, that works. But a)  your not using Composer and b ) if you’re game gets any more complex than that, you’re going to running into a ton of work to manage your objects.

Rob

I loaded really big levels and tired to reset using this method. Let me tell you it was not worth the convenience, assuming your levels stay really small and not display to many objects.

Thanks corona! I understood you!

I found another way.

If you click I move to a new stage, and out of it quickly turn back. How do you make that decision?

main.lua -> menu.lua -> game.lua -> // press button “restart” // -> restart.lua (and quickly turn on) -> game.lua

For the user, not much that I move to a new stage! And it looks great. Memory problems can be?

game.lua

local composer = require( "composer" ) local physics = require( "physics" ) local scene = composer.newScene() display.setDefault( "background", 0, 1, 0 ) physics.start( ) local restart = display.newImage( "restart.png", 250, 0 ) function onTouch (event) if ( event.phase == "began" ) then composer.removeScene("main") composer.gotoScene( "restart" ) end end restart:addEventListener( "touch", onTouch ) function scene:create( event ) --print( "ВТОРАЯ СЦЕНА СОЗДАЕТСЯ" ) local sceneGroup = self.view local ball = display.newImage( "ball.png", 100, 0 ) physics.addBody( ball, "dinamic", { friction = 0.3, density = 0.01 } ) sceneGroup:insert(ball) end function scene:show( event ) local sceneGroup = self.view local phase = event.phase if ( phase == "will" ) then elseif ( phase == "did" ) then end end function scene:hide( event ) local sceneGroup = self.view local phase = event.phase if ( phase == "will" ) then elseif ( phase == "did" ) then end end function scene:destroy( event ) local sceneGroup = self.view end scene:addEventListener( "create", scene ) scene:addEventListener( "show", scene ) scene:addEventListener( "hide", scene ) scene:addEventListener( "destroy", scene ) return scene

restart.lua

local composer = require( "composer" ) local scene = composer.newScene() local composer = require( "composer" ) local scene = composer.newScene() -- create() function scene:create( event ) local sceneGroup = self.view end -- show() function scene:show( event ) local sceneGroup = self.view local phase = event.phase if ( phase == "will" ) then elseif ( phase == "did" ) then composer.removeScene("restart") composer.gotoScene( "main", "fade" ) end end -- hide() function scene:hide( event ) local sceneGroup = self.view local phase = event.phase if ( phase == "will" ) then elseif ( phase == "did" ) then end end -- destroy() function scene:destroy( event ) local sceneGroup = self.view end scene:addEventListener( "create", scene ) scene:addEventListener( "show", scene ) scene:addEventListener( "hide", scene ) scene:addEventListener( "destroy", scene ) return scene