Level Navigation

Well, good news that the error goes away…

Now you need to rebuild the function as Rob described and then re-enable buttonRelease.

[code]local function buttonRelease(event)
local place = “world”…storyboard.world…“level”…storyboard.level
print("place = ", place)

storyboard.gotoScene(place)
end[/code]

What happens there? Still an error? What does the print statement show?

Also I see a typo in the tutorial. in main.lua it says storyboard.worlds = 0 when it should be storyboard.world = 0

We’ve almost got to the bottom of this…hang in there.

(and if there’s still a bug you may want to paste in your main.lua here…I feel like there is some sort of overwrite somewhere… [import]uid: 41884 topic_id: 34149 reply_id: 135859[/import]

After fixing main.lua and rebuilding buttonRelease I get:
2012-12-20 10:13:00.126 Corona Simulator[16906:903] place = world1level0
2012-12-20 10:13:00.126 Corona Simulator[16906:903] Cannot transition to scene: world1level0. There is either an error in the scene module, or you are attempting to go to a scene that does not exist. If you called storyboard.removeScene() on a scene that is NOT represented by a module, the scene must be re-created before transitioning back to it.
2012-12-20 10:13:00.127 Corona Simulator[16906:903] Runtime error
module ‘world1level0’ not found:resource (world1level0.lu) does not exist in archive
no field package.preload[‘world1level0’]
no file ‘/Users/focuslab/Desktop/Level Select Beta/world1level0.lua’
no file ‘/Applications/CoronaSDK/Corona Simulator.app/Contents/Resources/world1level0.lua’
no file ‘./world1level0.dylib’
no file ‘/Applications/CoronaSDK/Corona Simulator.app/Contents/Resources/world1level0.dylib’
stack traceback:
[C]: ?
[C]: in function ‘error’
?: in function ‘gotoScene’
…focuslab/Desktop/Level Select Beta/levels.lua:20: in function ‘onRelease’
?: in function <?:3>
?: in function <?:229>

Here’s the main.lua

-----------------------------------------------------------------------------------------  
--  
-- main.lua  
--  
-----------------------------------------------------------------------------------------  
  
-- hide the status bar  
display.setStatusBar( display.HiddenStatusBar )  
  
-- include the Corona "storyboard" module  
local storyboard = require "storyboard"  
  
-- Store the selected world and level  
storyboard.world = 0  
storyboard.level = 0  
  
-- load menu screen  
storyboard.gotoScene( "worlds" )  
storyboard.isDebug = true  

Here’s the rebuild of the function just for good measure

local function buttonRelease(event)  
 local place = "world"..storyboard.world.."level"..storyboard.level  
 print("place = ", place)  
   
 storyboard.gotoScene(place)   
end  

Also I see that its looking for world1level0.lua so I also tried just changing world1level1.lua to world1level0.lua and got this message:

2012-12-20 10:17:16.376 Corona Simulator[16906:903] place = world1level0
2012-12-20 10:17:16.377 Corona Simulator[16906:903] Runtime error
?:0: attempt to call method ‘dispatchEvent’ (a nil value)
stack traceback:
[C]: in function ‘dispatchEvent’
?: in function ‘gotoScene’
…focuslab/Desktop/Level Select Beta/levels.lua:20: in function ‘onRelease’
?: in function <?:3>
?: in function <?:229>
[import]uid: 72845 topic_id: 34149 reply_id: 135891[/import]

derp…well the first bug is an obvious oversight on my part; I forgot to add in storyboard.level = event.target.id. Without it storyboard.level is always zero and storyboard will never find the file.

However!

Getting that error after you “fixed” the filename means that the problem is in the scene file you’re going to! So paste one of those in. We’ve almost got this figured out. [import]uid: 41884 topic_id: 34149 reply_id: 136028[/import]

Well it’s not like could see what the level code looks like in sim, anyway, as you use a lot of assets. :slight_smile:

  1. You’re using the sprite library, which has been deprecated for awhile. So I can’t really help with that apart from saying that you don’t keep it local?

(Actually, looking at this file I would guess you’re using something to generate the code, like level helper?)

  1. You use a really strange line that I haven’t encountered before. I guess it could be legit, but…
require("gnomies").getSpriteSheetData(); -- never seen requires that look at subtables...
  1. Under “floors” you have three identically named variables, which at best means two are being overwritten, at worst means there is an error there.

  2. …and…I’m going to stop looking for bugs right here. The real problem, and it’s fairly simple, is that storyboard only works going to storyboard scenes. You can’t just point at whatever file you want; the destination has to have the same createScene/enterScene/exitScene construction template that you already used to build the menu screen.

You don’t have to use all of the commands but you do need to have these ABSOLUTE basics, otherwise no scene is constructed and thus storyboard gives up, because it doesn’t “see” something to go to.

[code]local storyboard = require(“storyboard”)
local scene = storyboard.newScene()

– you can put all of your functions and stuff here

function scene:createScene( event )
– all of the display objects you make need to go in here or enterScene
end

scene:addEventListener( “createScene”, scene )

return scene[/code]

Well, I’m glad it was solvable! :wink: [import]uid: 41884 topic_id: 34149 reply_id: 136055[/import]

I really appreciate the help. As you can tell I’m a huge noob. Baby steps…baby steps. [import]uid: 72845 topic_id: 34149 reply_id: 136056[/import]

EDIT
[import]uid: 72845 topic_id: 34149 reply_id: 136045[/import]

One last question. Now that I know why my level won’t run I made a new level to run properly. However I used the code you recommended

storyboard.level = event.target.id  

Like so…

local function buttonRelease(event)  
 local place = "world"..storyboard.world.."level"..storyboard.level = event.target.id  
 print("place = ", place)  
   
 storyboard.gotoScene(place)   
end  

And my game locks at the world select screen. I changed the world1level1.lua to world1level0.lua and removed the code you said to use and the level loaded fine. Did I not apply the code you gave me properly?

Thanks again [import]uid: 72845 topic_id: 34149 reply_id: 136059[/import]

Because you can’t use equals in two places; that’s wrong in just about any kind of code. :wink: It should be:

[code]local function buttonRelease(event)
storyboard.level = event.target.id – sets level so it isn’t 0!
local place = “world”…storyboard.world…“level”…storyboard.level

storyboard.gotoScene(place)
return true – if you want, not sure if needed with the widget?
end[/code]

And remember, when you post problems here (and you will, for certain), post the error message. :slight_smile: [import]uid: 41884 topic_id: 34149 reply_id: 136093[/import]

Based on what I see in the tutorial, you know the world…

"world #" = storyboard.world

And the button itself carries the level number.

"level #" == event.target.id

So when you use gotoScene…

storyboard.gotoScene( storyboard.world..event.target.id )

I appreciate the response. I’m still new to coding so I’m still a bit confused.

for

"level #" == event.target.id

would I change it to "level 1" == event.target.id

and

storyboard.gotoScene( storyboard.world..event.target.id )

would I keep that as is and just replace

 local worldText = display.newText("World Selected: "..storyboard.world,20,100,system.defaultFont,30)  
 local levelText = display.newText("Level Selected: "..storyboard.level,20,150,system.defaultFont,30)  

In the play.lua?

Thanks again for the help, I know I have a long way to go. [import]uid: 72845 topic_id: 34149 reply_id: 135768[/import]

“…” is concatenation. It works like this:

local cool = 1 local cat = "meow" print(cat..cool) -- "meow1"

Concatenation works for scene names too:

local world = 2 local level = 1 storyboard.gotoScene("level"..world.."-"..level) -- "level2-1"

So having looked more closely at that page code, you should do this:

-- inside the touch listener "buttonRelease", add this line inside the "if event.phase == "ended"" statement storyboard.level = event.target.id

-- then use the storyboard command storyboard.gotoLevel( "level"..storyboard.world..storyboard.level )

When you touch an object, inside of the touch event the object is called “event.target”, so “event.target.id” should be the level number too, it just looks like it’s easier to call storyboard.level since you are setting it already. [import]uid: 41884 topic_id: 34149 reply_id: 135777[/import]

So in the levels.lua it should be

local function buttonRelease(event)  
 storyboard.level = event.target.id  
 -- go to levels scene  
 storyboard.gotoLevel( "level"..storyboard.world..storyboard.level )  
  
 return true -- indicates successful touch  
end  

?
And if yes, when I click the world 1 level 1 button nothing happens : (
Is that because of my .lua name? do I have to name it world1level1.lua?

I really really appreciate your help with this. This is one of a few major hurdles I’m dealing with at the moment. [import]uid: 72845 topic_id: 34149 reply_id: 135782[/import]

What’s the FileName of your level? That’s what it has to match. [import]uid: 41884 topic_id: 34149 reply_id: 135785[/import]

World1Level1.lua [import]uid: 72845 topic_id: 34149 reply_id: 135789[/import]

When you use gotoScene, you need the exact name of the scene you’re going to. That scene name is always the name of the lua file. So if the scene name is “World1Level1.lua”, the scene name must be “World1Level1”. So let’s take a look at the concatenation:

storyboard.gotoScene( "World"..storyboard.world.."Level"..storyboard.level )

You have to get the case perfectly right, or corona can’t find the file. so I usually recommend lowercase only for lua files. :wink:

It’s also okay to use variables, btw

local where = "World"..storyboard.world.."Level"..storyboard.level storyboard.gotoScene(where) [import]uid: 41884 topic_id: 34149 reply_id: 135792[/import]

I’m pretty sure I understand now but for some reason it’s still not working.
I changed the .lua file name so it is now lowercase (world1level1.lua)

Here’s what my levels.lua looks like:

-----------------------------------------------------------------------------------------  
--  
-- levels.lua  
--  
-----------------------------------------------------------------------------------------  
  
local storyboard = require( "storyboard" )  
local widget = require "widget"  
  
local scene = storyboard.newScene()  
  
-- Table to hold level buttons  
local levels = {}  
  
-- 'onRelease' event listener for playBtn  
local function buttonRelease(event)  
 storyboard.level = event.target.id  
 -- go to levels scene  
storyboard.gotoScene( "world"..storyboard.world.."level"..storyboard.level )  
  
--^^^ Part that matters^^^---  
  
 return true -- indicates successful touch  
end  
-- Called when the scene's view does not exist:  
function scene:createScene( event )  
 local group = self.view  
  
 local background = display.newImageRect("background.png",480,320)  
 background.x = 240; background.y = 160  
 group:insert(background)  
  
 -- create 20 buttons to choose the level   
 for i=0,3 do  
 for j=1,5 do  
 current = i\*5 + j -- This calculates the current position in the table  
 levels[current] = widget.newButton{  
 label=current,  
 id=current,  
 default = "button.png",  
 width=64, height=64,  
 onRelease = buttonRelease -- event listener function  
 }  
 levels[current].x = 45 + (j\*65)  
 levels[current].y = 60+ (i\*65)  
  
 -- If you are using the last publicly available version of Corona, you may  
 -- need to replace the following line with:  
 -- group:insert( levels[current].view )  
 group:insert( levels[current] )  
  
 end  
 end  
  
end  
  
-- Called immediately after scene has moved onscreen:  
function scene:enterScene( event )  
 local group = self.view  
  
 -- INSERT code here (e.g. start timers, load audio, start listeners, etc.)  
  
end  
  
-- Called when scene is about to move offscreen:  
function scene:exitScene( event )  
 local group = self.view  
  
 -- INSERT code here (e.g. stop timers, remove listenets, unload sounds, etc.)  
  
end  
  
-- If scene's view is removed, scene:destroyScene() will be called just prior to:  
function scene:destroyScene( event )  
 local group = self.view  
  
 for i=#levels,1,-1 do  
 if levels[i] then  
 levels[i]:removeSelf() -- widgets must be manually removed  
 levels[i] = nil  
 end  
 end  
end  
  
-----------------------------------------------------------------------------------------  
-- END OF YOUR IMPLEMENTATION  
-----------------------------------------------------------------------------------------  
  
-- "createScene" event is dispatched if scene's view does not exist  
scene:addEventListener( "createScene", scene )  
  
-- "enterScene" event is dispatched whenever scene transition has finished  
scene:addEventListener( "enterScene", scene )  
  
-- "exitScene" event is dispatched whenever before next scene's transition begins  
scene:addEventListener( "exitScene", scene )  
  
-- "destroyScene" event is dispatched before view is unloaded, which can be  
-- automatically unloaded in low memory situations, or explicitly via a call to  
-- storyboard.purgeScene() or storyboard.removeScene().  
scene:addEventListener( "destroyScene", scene )  
  
-----------------------------------------------------------------------------------------  
  
return scene  

I have my world1level1.lua along with all the files needed to run it in the same folder as this tutorials files.

I’ve also tried to use a variable

local function buttonRelease(event)  
 storyboard.level = event.target.id  
 -- go to levels scene  
local where = "world"..storyboard.world.."level"..storyboard.level  
storyboard.gotoScene(where)  
   
--^^^ Part that matters^^^---  
  
 return true -- indicates successful touch  
end  

I feel like I’m missing something simple.
Again, thanks A LOT for your help. [import]uid: 72845 topic_id: 34149 reply_id: 135801[/import]

Variables in this case are just if you want to make your code easier to read or handle.

I feel like this should work at a glance but now what you need to do is troubleshoot. What you’re looking for is the shell to tell you what the error line is (the first error line it gives is usually what you’re looking for, or thereabouts) What error does it tell you? That the scene doesn’t exist?

So what you want to do is test the variables. Make buttonRelease look like this:

[code]local function buttonRelease(event)
storyboard.level = event.target.id

print(“storyboard.level is…”, storyboard.level)
print(“storyboard.world is…”, storyboard.world)

– go to levels scene
storyboard.gotoScene( “world”…storyboard.world…“level”…storyboard.level )

return true – indicates successful touch
end[/code]

If those numbers come out wrong then we need to fix something else. [import]uid: 41884 topic_id: 34149 reply_id: 135804[/import]

This is what it say in Terminal

2012-12-19 16:21:53.965 Corona Simulator[16861:903] storyboard.level is… 1
2012-12-19 16:21:53.966 Corona Simulator[16861:903] storyboard.world is… 1
2012-12-19 16:21:54.051 Corona Simulator[16861:903] Runtime error
?:0: attempt to call method ‘dispatchEvent’ (a nil value)
[import]uid: 72845 topic_id: 34149 reply_id: 135807[/import]

Yeah but what else shows up? Usually dispatchEvent is talking about something else further down [import]uid: 41884 topic_id: 34149 reply_id: 135808[/import]

2012-12-19 16:34:18.906 Corona Simulator[16906:903] storyboard.level is… 1
2012-12-19 16:34:18.906 Corona Simulator[16906:903] storyboard.world is… 1
2012-12-19 16:34:18.906 Corona Simulator[16906:903] Runtime error
?:0: attempt to call method ‘dispatchEvent’ (a nil value)
stack traceback:
[C]: in function ‘dispatchEvent’
?: in function ‘reloadScene’
?: in function ‘gotoScene’
…focuslab/Desktop/Level Select Beta/levels.lua:23: in function ‘onRelease’
?: in function <?:3>
?: in function <?:229>
[import]uid: 72845 topic_id: 34149 reply_id: 135809[/import]