[SOLVED] I filed the test project to bug report, and Ansca team got back to me, showing what was wrong with my implementation. The problem was, beamGroup needed to be forward referenced, but the beamGroup = display.newGroup() had to be inside the createScene function. It makes really good sense – and I should’ve known that, but somehow I didin’t see it. Also, beamGroup needed to be nilled upon exitScene (and I never thought of doing so with displayGroup.)
I’ve edited the code below with comment showing what was wrong and how it was fixed.
Thank you, Ansca Team!
Naomi
Using daily build 828, I have set up a very simple test project that has two scenes: menu.lua and game.lua
On both menu and game scenes, I create a simple animation using transition.to , and when I launch the project and come to menu.lua, it looks and works as expected.
When I tap on a button to leave menu scene and come to game scene, it also looks and works as expected.
However, when I tapp on “go back” button on game scene and return to menu scene, I get this dreadful runtime error (on line 42 of the menu.lua code below):
bad argument #-1 to ‘_newImageRect’ (Proxy expected, got nil)
Am I doing something wrong? Or is this Storyboard bug? Here are the code for menu and game scenes. I think when I return to menu.lua from game.lua, it is unable to insert the image to beamGroup. (I don’t understand why it is able to do this first time around but not the second time around.)
Naomi
menu.lua:
local widget = require( "widget" )
local storyboard = require( "storyboard" )
storyboard.isDebug = true
storyboard.purgeOnSceneChange = true
local scene = storyboard.newScene()
local localGroup
--local beamGroup = display.newGroup(); \<\< this was wrong
local beamGroup
local img = {}
img.bgBeam = {}
local btnSheetOption
local btnSheet
local playGame
local function changeScene( self, event )
storyboard.gotoScene( "game", "crossFade", 400 )
end
---------------------------------------------------------------------------------
-- rotate beam
---------------------------------------------------------------------------------
function img.rotateAgain()
img.rotateStart = nil;
beamGroup.rotation = 0
img.rotateBeam()
end
function img.rotateBeam()
img.rotateStart = transition.to(beamGroup, {time = 60000,
rotation = 360, onComplete=img.rotateAgain})
end
---------------------------------------------------------------------------------
-- Scene functions
---------------------------------------------------------------------------------
-- Called when the scene's view does not exist:
function scene:createScene( event )
localGroup = self.view
-- create display group here (not outside the createScene)
beamGroup = display.newGroup()
for i=1,18 do
img.bgBeam[i] = display.newImageRect( beamGroup, "PNG/beam.png", 40, 320 )
img.bgBeam[i]:setReferencePoint(display.TopCenterReferencePoint)
img.bgBeam[i].x = 0; img.bgBeam[i].y = 0;
if (i == 1) then
img.bgBeam[i].rotation = 20;
else
img.bgBeam[i].rotation = img.bgBeam[i-1].rotation+20;
end
end
beamGroup.x = 240; beamGroup.y = 180;
localGroup:insert(beamGroup);
btnSheetOption = {
width = 200,
height = 60,
numFrames = 2,
sheetContentWidth = 200,
sheetContentHeight = 120
};
btnSheet = graphics.newImageSheet( "PNG/rect.png", btnSheetOption )
playGame = widget.newButton{
sheet = btnSheet,
defaultIndex = 1,
overIndex = 2,
width = 200,
height = 60,
label = "PLAY GAME",
labelColor = { default={255}, over={255} },
fontSize = 20,
onRelease = changeScene,
emboss = true
}
playGame.x = 240;
playGame.y = 180;
localGroup:insert(playGame);
collectgarbage("collect")
end
-- Called immediately after scene has moved onscreen:
function scene:enterScene( event )
-- previous scene's view is purged by
-- storyboard.purgeOnSceneChange = true;
img.rotateBeam()
end
-- Called when scene is about to move offscreen:
function scene:exitScene( event )
-- cancel transition
if (img.rotateStart) then transition.cancel(img.rotateStart) end
-- remove display object that uses imageSheet
display.remove( playGame ); playGame = nil;
-- remove reference to the imageSheet
btnSheet = nil;
beamGroup = nil; -- nil out the display group here
end
function scene:didExitScene( event )
end
function scene:destroyScene( event )
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 )
scene:addEventListener( "didExitScene", scene )
---------------------------------------------------------------------------------
return scene
game.lua
[code]
local widget = require( “widget” )
local storyboard = require( “storyboard” )
storyboard.isDebug = true;
storyboard.purgeOnSceneChange = true;
local scene = storyboard.newScene()
local localGroup;
–local beamGroup = display.newGroup(); << this was wrong
local beamGroup
local img = {};
img.bgBeam = {};
local btnSheetOption;
local btnSheet;
local goBack;
local function changeScene( self, event )
storyboard.gotoScene( “menu”, “crossFade”, 400 )
end
– rotate beam
function img.rotateAgain()
img.rotateStart = nil;
beamGroup.rotation = 0
img.rotateBeam()
end
function img.rotateBeam()
img.rotateStart = transition.to(beamGroup, {time = 60000,
rotation = 360, onComplete=img.rotateAgain})
end
– Scene functions
– Called when the scene’s view does not exist:
function scene:createScene( event )
localGroup = self.view
– create display group here (not outside the createScene)
beamGroup = display.newGroup()
for i=1,18 do
img.bgBeam[i] = display.newImageRect( beamGroup, “PNG/beam.png”, 40, 320 )
img.bgBeam[i]:setReferencePoint(display.TopCenterReferencePoint)
img.bgBeam[i].x = 0; img.bgBeam[i].y = 0;
if (i == 1) then
img.bgBeam[i].rotation = 20;
else
img.bgBeam[i].rotation = img.bgBeam[i-1].rotation+20;
end
end
beamGroup.x = 240; beamGroup.y = 180;
localGroup:insert(beamGroup);
btnSheetOption = {
width = 200,
height = 60,
numFrames = 2,
sheetContentWidth = 200,
sheetContentHeight = 120
};
btnSheet = graphics.newImageSheet( “PNG/rect.png”, btnSheetOption )
goBack = widget.newButton{
sheet = btnSheet,
defaultIndex = 1,
overIndex = 2,
width = 200,
height = 60,
label = “GO BACK”,
labelColor = { default={255}, over={255} },
fontSize = 20,
onRelease = changeScene,
emboss = true
}
goBack.x = 240;
goBack.y = 180;
localGroup:insert(goBack);
end
– Called immediately after scene has moved onscreen:
function scene:enterScene( event )
img.rotateBeam()
– previous scene’s view is purged by
– storyboard.purgeOnSceneChange = true;
end
– Called when scene is about to move offscreen:
function scene:exitScene( event )
– cancel transition
if (img.rotateStart) then transition.cancel(img.rotateStart) end
– remove display object that uses imageSheet
display.remove( goBack ); goBack = nil;
– remove reference to the imageSheet
btnSheet = nil;
beamGroup = nil; – nil out the display group here
end
function scene:didExitScene( event )
end
– Called prior to the removal of scene’s “view” (display group)
function scene:destroyScene( event )
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 )
scene:addEventListener( “didExitScene”, scene )
return scene
[/code] [import]uid: 67217 topic_id: 24131 reply_id: 111459[/import]