Composer.remove scene not working

Hello ?

any help ?

I asked you several questions which for the most part you did not answer. What you did was restate the original problem and post some code that’s not your reset.lua scene.

It feels like you don’t understand the relationship of your scenes and what you need to do. And I suspect, you have us chasing a wrong problem.

You’re using Composer which is our scene manager. You have three scenes that seem to flow like this:

game.lua -> reset.lua -> game2.lua

I don’t know why you even have a reset.lua if you want to go game2.lua. You should be able to go directly to game2.lua and if you plan to go back to game.lua, then you can remove game.lua inside game2.lua.

Now based on the description, even a working reset.lua scene or removing the scene in game2.lua isn’t going to help. If you change scenes and you still see objects from the scene you left, it’s because you *did not*  add those objects to the game.lua scene.view group. If you are unable to hide the previous seen that’s the problem. Trying to remove the scene isn’t doing to do anything.

Rob

Have you looked through the Corona documentation? Many of the tutorials there are very useful, but you can’t copy and paste the code. You have to apply the knowledge and changes the code to fit yours. 

I would post them here, but Coronalabs.com is under maintenance.

Their are 10 game.lua scenes . And 10 restart.lua . The first scene is start.lua when the user touches the screen they go into game.lua . If they complete game.lua they go into restart.lua which makes then touch the screen to go into the next level (game2.lua) . And then that keeps going until they beat the game . If they run out of time , then they will go into another scene and restart the game over . Do I have to add the timer into the create scene to have it removed to ? I didn’t do this in other apps and they work perfectly fine . 

I’ll post my whole code to see if I can give you a better understanding of what’s happening .

game.lua:

-- requires local physics = require "physics" physics.start() local composer = require( "composer" ) local scene = composer.newScene() local background function scene:create(event) local screenGroup = self.view local randomImage = math.random(1,41) local background = display.newImageRect("images/background"..randomImage..".jpg",display.contentWidth,display.contentHeight) background.x = display.contentCenterX background.y = display.contentCenterY screenGroup:insert(background) CreateWalls(screenGroup,1) display.setDefault("fillColor", 0, 1, 1) -- create image of a ball Ball = display.newCircle(100, 100, 10) physics.addBody(Ball, "dynamic", {friction=2}) Ball:applyLinearImpulse(-.05, .05, 0, 0) screenGroup:insert(Ball) end local options = { effect = "fade", time = 400 } function SetDefaultAnchor( pos ) display.setDefault("anchorX", pos.x) display.setDefault("anchorY", pos.y) end function CreateWalls( ScreenGroup, BorderWidth ) -- make the math easier local OldAnchor = {x = display.getDefault(anchorX), y = display.getDefault(anchorY) } SetDefaultAnchor({x=0, y=0}) local Height = display.contentHeight -- + (2 \* BorderWidth) local Width = display.contentWidth -- + (2 \* BorderWidth) local leftWall = display.newRect( ScreenGroup, 0, 0, BorderWidth, Height) -- this is where the error is local rightWall = display.newRect( ScreenGroup, Width - BorderWidth, 0, BorderWidth, Height) local ceiling = display.newRect( ScreenGroup, 0, 0, Width, BorderWidth) local floor = display.newRect( ScreenGroup, 0, Height-BorderWidth, Width, BorderWidth) physics.addBody (leftWall, "static", {bounce = 0.7, friction = 2}) physics.addBody (rightWall, "static", {bounce = 0.0, friction = 2}) physics.addBody (ceiling, "static", {bounce = 0.8, friction = 2}) physics.addBody (floor, "static", {bounce = 0.0, friction = 2}) -- restore previous defaults SetDefaultAnchor(OldAnchor) end local timeLimit = 6 timeLeft = display.newText(timeLimit, 160, 20, native.systemFontBold, 24) timeLeft:setTextColor(255,0,0) function timerDown() timeLimit = timeLimit-1 timeLeft.text = timeLimit if(timeLimit==0)then display.remove(timeLeft) timer.cancel(timerr) composer.gotoScene("maxtime",options) end end timerr = timer.performWithDelay(1000,timerDown,timeLimit) function onBallTap( event ) timer.cancel(timerr) composer.gotoScene("restart",options) end function scene:show(event) local sceneGroup = self.view composer.removeScene( "start" ) Ball:addEventListener( "tap", onBallTap ) end function scene:hide(event) local sceneGroup = self.view end function scene:destroy(event) end scene:addEventListener("create", scene) scene:addEventListener("show", scene) scene:addEventListener("hide", scene) scene:addEventListener("destroy", scene) return scene

restart.lua:

-- requires local composer = require( "composer" ) local scene = composer.newScene() -- background local background function scene:create(event) local screenGroup = self.view local background = display.newImageRect("nextlevel.jpg",display.contentWidth,display.contentHeight) screenGroup:insert(background) end local options = { effect = "flip", time = 400 } local function touchScreen( event ) if event.phase == "began" then display.remove(timeLeft) composer.removeScene( "game" ) composer.gotoScene( "game2", options ) end end function scene:show(event) if event.phase == "did" then Runtime:addEventListener("touch", touchScreen) end end function scene:hide(event) if event.phase == "did" then Runtime:removeEventListener("touch", touchScreen) end end function scene:destroy(event) end scene:addEventListener( "create", scene ) scene:addEventListener( "show", scene ) scene:addEventListener( "hide", scene ) scene:addEventListener( "destroy", scene ) return scene

Firstly, is the gameplay in game.lua, game2.lua, game3.lua essentially the same, but maybe slightly harder or with additional elements?

And likewise the behaviour of the restart.lua, restart2.lua screens the same?

If so, this really isn’t an optimal way of doing things. Ideally you’d have one game.lua and one restart.lua, and keep track of the level number to determine how the level should play and what the restart screen displays.

Secondly, you specifically remove timeText in restart.lua. This timeLeft object is never added to scene.view in game.lua, so it won’t be cleared when calling removeScene.

I’d recommend creating objects either within scene:create or a function you can call from elsewhere. In your code you create some things within scene:create, some within CreateWalls(), but also some within the main listing. It’s easy to lose track of these ‘loose’ items, and forget to add them to the scene.view.

Edit: corrected timeText to timeLeft

  1. Yes . They are all the same it just gets harder as the levels go up .
  2. Yes all of the restart.lua scenes are basically the same .
  3. Where do I put the timer ? I thought it belonged to the function that’s why I didn’t put it in a scene function.

Also how do I do this ?

If so, this really isn’t an optimal way of doing things. Ideally you’d have one game.lua and one restart.lua, and keep track of the level number to determine how the level should play and what the restart screen displays.

There are various ways to persist data between scenes:

You can use the built in composer functionality to set (and get) variables.

https://docs.coronalabs.com/api/library/composer/setVariable.html

You can use a module:

[lua]

— globals.lua

local m = {}

 m.currentLevel = 1

return m

— game.lua

local glo = require(“globals”)

glo.currentLevel = glo.currentLevel + 1

— restart.lua

local glo = require(“globals”)

print (glo.currentLevel)  – this will be 2

[/lua]

Or you can save the values to disk:

https://forums.coronalabs.com/topic/62324-how-to-save-and-load-game-progress/

https://docs.coronalabs.com/ is still available, it’s just the main website we are working on.

In addition to Nick’s spot on answer, in game.lua you never add “timeLeft” object to the scene either. This will hang around when you change scenes.

Also semantics are important when programming.  You don’t create a variable “NumberOfApples” to hold a display.newImageRect() object of a picture of a car. “restart.lua” implies that you are attempting to restart a level, not go to a new level. I tend to name that scene “nextlevel.lua” 

I’d also recommend you read up on scope within lua, as you seem to be declaring a lot of global variables and functions. There’s no need for timerr to be global just so you can access it from the tap listener. Declare local timerr at the top of your lua file, and then assign the timer to this at the appropriate time.

Once you have your currentLevel variable available within game.lua, you just use this to determine how hard your level is. That might be by adjusting the size or speed or the ball, the amount of time before game over etc.

Just as an example…

[lua]

local ballSpeed = 5 + (glo.currentLevel * 0.25)

local ballSize = 20 - (glo.currentLevel) 

local gameTime = 90 - (glo.currentLevel * 5)

[/lua]

or…

[lua]

local ballSpeeds = {5, 6, 8, 10, 15, 20, 30, 40, 60}

local ballSizes = {20, 19, 18, 15, 12, 10,8, 7, 6, 5}

local gameTimes = {90, 85, 75, 70, 60, 55, 48, 45, 42, 40}

local ballSpeed = ballSpeeds[glo.currentLevel]

local ballSize = ballSizes[glo.currentLevel]

local gameTime = gameTimes[glo.currentLevel]

[/lua]

I don’t know why but I just put it as restart . Do I have to change it ?

This seems a little complicated so I would like to do it the way I’m already doing it because I wouldn’t understand the way you suggested . 

You don’t have to change restart.lua to nextlevel.lua. That’s not a hard rule. As long as you know what you’re doing and what the purpose that scene serves, that’s really all that matters. However when asking for help, had we seen “nextscene.lua” it would have helped us understand the problem a bit better. So if you want to re-ask the question “Should I change it” then the answer becomes “I would recommend it”.

Rob

Ok I did.

Trust me, a little extra reading and work now to understand this will save you countless hours in the future. Imagine your game in the future has 20, 30, 40 levels, game.lua, game1.lua, game2.lua etc. What happens when you want to change something as to how the basic game works, or add some extra HUD text. You’d have to make this change in all 20, 30, 40 files.

Ok so are there any docs that will help me start ?

It’s not so much docs you need, as putting together a few basic coding principles that you’ll need to become a good developer.

  1. Have a variable for the currentLevel, that can be accessed throughout the app. I posted various ways of doing that.

  2. Adjust how your level behaves and is built depending on the value of currentLevel. So instead of hard-coding things like speed or size,  use variables to set these. I posted a couple of ways of doing that - if the level is 1 it might grab/calculate a value of 20 for speed, if the level is 2 it might grab/calculate a value of 25.

What things does Level 2 change? Is it just a shorter timer? Quicker ball? Smaller ball?

Imagine Sonic the Hedgehog. If they built that in Corona, they wouldn’t have greenhillzone.lua, marblezone.lua etc, all containing the same logic for controlling Sonic, moving platforms, collecting rings, displaying his number of lives etc. They’d have one Lua file for game logic, and then depending on the level Sonic is on import data about what tiles, objects and enemies should go where. If they want to make Sonic have a faster top speed, they just change one value in game.lua. 

What things does Level 2 change? Is it just a shorter timer? Quicker ball? Smaller ball?

The ball moves faster and the timer is a little bit longer .