Trying to use StoryBoard with one scene

Ok, I know I’m trying to do something potentially silly, but the reason I want to use a single scene file is: Depending on the arguments passed in when the scene loads, a different Tiled map will load and this is almost the only difference I need for each level. Using a single scene file for this would greatly simplify my code.

The error I’m getting (XP Pro, build 704) is:

[lua]Copyright © 2009-2011 A n s c a , I n c .
Version: 2.0.0
Build: 2011.704
scene1 table: 024A6540

scene1: createScene event
scene1: enterScene event
function: 024D7018
scene1: exitScene event
scene2: enterScene event
((destroying scene1’s view))
nil
Runtime error
…\m_webster\my documents\corona\gameoutline\scene.lua:73: attempt to c
all method ‘addEventListener’ (a nil value)
stack traceback:
[C]: in function ‘addEventListener’
…\m_webster\my documents\corona\gameoutline\scene.lua:73: in functi[/lua]

The code I have is the slightly changed storyboard example code, with the bg.jpg renamed to bg1.jpg…

main.lua:
[lua]-----------------------------------------------------------------------------------------

– main.lua


display.setStatusBar( display.HiddenStatusBar )

– require controller module
local storyboard = require “storyboard”
local widget = require “widget”

– load first screen
storyboard.prevsceneid = nil
storyboard.nextsceneid = “scene1”
storyboard.nextscenetrans = “fade”
storyboard.gotoScene( “scene” )
– Display objects added below will not respond to storyboard transitions

– table to setup tabBar buttons
local tabButtons = {
{ label=“First”, up=“icon1.png”, down=“icon1-down.png”, width = 32, height = 32, selected=true },
{ label=“Second”, up=“icon2.png”, down=“icon2-down.png”, width = 32, height = 32 },
}

– create the actual tabBar widget
local tabBar = widget.newTabBar{
top = display.contentHeight - 50, – 50 is default height for tabBar widget
buttons = tabButtons
}
–[[ Uncomment to monitor app’s lua memory/texture memory usage in terminal…

local function garbagePrinting()
collectgarbage(“collect”)
local memUsage_str = string.format( “memUsage = %.3f KB”, collectgarbage( “count” ) )
print( memUsage_str )
local texMemUsage_str = system.getInfo( “textureMemoryUsed” )
texMemUsage_str = texMemUsage_str/1000
texMemUsage_str = string.format( “texMemUsage = %.3f MB”, texMemUsage_str )
print( texMemUsage_str )
end

Runtime:addEventListener( “enterFrame”, garbagePrinting )
–]][/lua]

scene.lua:
[lua]---------------------------------------------------------------------------------

– testscreen1.lua


local storyboard = require( “storyboard” )
local scene = storyboard.newScene()


– BEGINNING OF YOUR IMPLEMENTATION

– Touch event listener for background image
local function onSceneTouch( self, event )
if event.phase == “began” then

storyboard.prevsceneid = storyboard.nextsceneid

if (storyboard.nextsceneid == “scene1”) then
storyboard.nextsceneid = “scene2”
storyboard.nexttrans = “fade”
elseif (storyboard.nextsceneid == “scene2”) then
storyboard.nextsceneid = “scene3”
storyboard.nextscenetrans = “fromRight”
else
storyboard.nextsceneid = “scene1”
storyboard.nextscenetrans = “fromLeft”
end

storyboard.gotoScene( “scene”, storyboard.nextscenetrans, 400 )

return true
end
end
– Called when the scene’s view does not exist:
function scene:createScene( event )
local screenGroup = self.view

if (storyboard.nextsceneid == “scene1”) then
screenGroup.image = display.newImage( “bg1.jpg” )
elseif (storyboard.nextsceneid == “scene2”) then
screenGroup.image = display.newImage( “bg2.jpg” )
else
screenGroup.image = display.newImage( “bg3.jpg” )
end

print(storyboard.nextsceneid, screenGroup.image)
screenGroup:insert( screenGroup.image )
screenGroup.image.touch = onSceneTouch

print( “\n”…storyboard.nextsceneid…": createScene event")
end
– Called immediately after scene has moved onscreen:
function scene:enterScene( event )
local screenGroup = self.view

print( storyboard.nextsceneid…": enterScene event" )

– remove previous scene’s view
if (storyboard.prevsceneid ~= nil) then
storyboard.purgeScene( “scene” )
end

– Update Lua memory text display
local showMem = function()
print(screenGroup.image.addEventListener)
screenGroup.image:addEventListener( “touch”, screenGroup.image )
end
local memTimer = timer.performWithDelay( 1000, showMem, 1 )
end
– Called when scene is about to move offscreen:
function scene:exitScene( event )
local screenGroup = self.view

print( storyboard.prevsceneid…": exitScene event" )

– remove touch listener for image
screenGroup.image:removeEventListener( “touch”, screenGroup.image )
end
– Called prior to the removal of scene’s “view” (display group)
function scene:destroyScene( event )
print( “((destroying “…storyboard.prevsceneid…”'s view))” )
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 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[/lua]
[import]uid: 8271 topic_id: 20502 reply_id: 320502[/import]

Do you have to do this with a scene?

Can’t you pass the data a different way, seems like overkill :slight_smile: [import]uid: 84637 topic_id: 20502 reply_id: 80460[/import]

Apparently, this is the appropriate way, according to the Q&A blog post on the StoryBoard API.

That’s not really my issue - the problem is that the scene cannot be loaded twice. I’m going to try a few things, but it would be great to get some direction on the official method to use. [import]uid: 8271 topic_id: 20502 reply_id: 80462[/import]

Have you tried purging the current scene before trying to reload it ? [import]uid: 84637 topic_id: 20502 reply_id: 80693[/import]

An app I’m building now has a similar need. I have 16+ pages where the only difference is a number identifying the page.

I’m thinking that if I put in code to detect when I need to visit a completely different scene, then I could move all of the create code to enterScene and then perhaps do a dispatch event to force the page to reload and only use gotoScene as necessary.

Dunno if that will work or not. [import]uid: 19626 topic_id: 20502 reply_id: 80831[/import]

I /think/ I’ve got it…

I really wanted to be able to re-use a single scene with different “levels” in my game - I believe I’ve found a way and it’s not much more than modularising the use of the storyBoard API.

I hope this is the right way to do it, but if not - I really hope Ansca (Mr. Beebe?) are watching this space and put their point forward…

The following is a reduced version (meaning the functionality, white spaces and some comments have been removed) of the Story Board Sample code presented by Jonathan Beebe.

main.lua:
[lua]local storyboard = require “storyboard”
local sceneapi = require(“scene”)

local scene1 = sceneapi.createScene( “scene1”, “scene3”, “scene2”, “fade”, “bg1.jpg” )
local scene2 = sceneapi.createScene( “scene2”, “scene1”, “scene3”, “slideLeft”, “bg2.jpg” )
local scene3 = sceneapi.createScene( “scene3”, “scene2”, “scene1”, “slideRight”, “bg3.jpg” )

function dump(t)
for k,v in pairs(t) do
print(k,v)
end
end

print(’\nscene1’)
dump(scene1)

print(’\nscene2’)
dump(scene2)

print(’\nscene3’)
dump(scene3)

storyboard.gotoScene( “scene1” )[/lua]

scene.lua:
[lua]module(…, package.seeall)

local storyboard = require( “storyboard” )

function createScene( scenename, prev, next, trans, img )
local scene = storyboard.newScene( scenename )
scene.name = scenename
scene.prev = prev
scene.next = next
scene.trans = trans
scene.img = img

– Touch event listener for background image
local function onSceneTouch( self, event )
if event.phase == “began” then
print( scene.next, scene.trans )
storyboard.gotoScene( scene.next, scene.trans, 400 )
end
return true
end

– Called when the scene’s view does not exist:
function scene:createScene( event )
local screenGroup = self.view

screenGroup.image = display.newImage( screenGroup, scene.img )
screenGroup.image.touch = onSceneTouch

print(scene.name…": createScene event")
end

– Called immediately after scene has moved onscreen:
function scene:enterScene( event )
local screenGroup = self.view

screenGroup.image:addEventListener( “touch”, screenGroup.image )
print(scene.name…": enterScene event")

– remove previous scene’s view
storyboard.purgeScene(scene.prev)
end

– Called when scene is about to move offscreen:
function scene:exitScene( event )
local screenGroup = self.view
print( scene.name…": exitScene event" )

– remove touch listener for image
screenGroup.image:removeEventListener( “touch”, screenGroup.image )
end

– Called prior to the removal of scene’s “view” (display group)
function scene:destroyScene( event )
print( “((destroying view: “…scene.name…”))” )
end

– “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 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
end[/lua]
[import]uid: 8271 topic_id: 20502 reply_id: 80862[/import]