Overlay scene not showing - lua

I have 2 scenes: One main scene with a button, and another scene with only 1 text.
button action in Main Scene:
local options =
{
effect = "fade",
time = 400,
params =
{
sample_var = "anything",
custom = "you want",
data = "here"
}
}
storyboard.showOverlay("inventory", options)
The Overlay Scene:
local storyboard = require("storyboard")
local scene = storyboard.newScene()
function scene:createScene( event )
local group = self.view
local title = display.newText("Inventory", 20, 20, native.systemFont, 16)
title:setTextColor(255,0,0)
group:insert(title)
end
function scene:enterScene( event )
print("enterScene")
end
function scene:exitScene( event )
print("exitScene")
end
function scene:destroyScene( event )
print("destroyScene")
end
scene:addEventListener( "createScene", scene )
scene:addEventListener( "enterScene", scene )
scene:addEventListener( "exitScene", scene )
scene:addEventListener( "destroyScene", scene )
return scene
After pressed the "button", nothing happens (no error). Main Scene is still active & accessible. According to official documentation, a scene should appear after pressing the button.
What did I miss?
Note: Both scene has similar structure (using Storyboard), and button as main scene is created with the following codes:
function scene:createScene( event )
btnInventory = display.newImage("images/btn_right.png", 320, 600)
btnInventory:addEventListener("tap", openInventory)
end
where openInventory is the first code listing.

Should work, I just tried it.
So perhaps you have a typo in the scene file name or is it in a sub-folder ?
If it's in a sub-folder you've got to call :
storyboard.showOverlay("mysubfolder.inventory", options)

End up I found out that the Ceramic Tile Map covers everything (it's just like on topmost layer). If the map is removed, the overlay works fine.
p.s. I found that Director module is easier to use than Storyboard. I switched to it.

Related

corona composer background next scene not showing

I have a lot of difficulties with composer...it's not so easy!
My previous scene is "game" (game.lua) everything is ok
When i go to my scene "recolt" with this snippet inside my game lua :
local function goTo()
print("gotoscene")
composer.gotoScene( "recolt", { time = 1000, effect = "fromRight", params = params } )
end
timer.performWithDelay( 1000, goTo )
:The problem is that i see my previous scene behind my recolt scene and i can't see my background but i see my circle who's moving ??? however my sceneGroup is correct :
sceneGroup:insert(background,circle)
When i do :
sceneGroup:insert(circle,background)
I see my background who hide my previous scene and my circle. > behavior expected
What's wrong? i would like to see my background and my circle in y "recolt" scene. Could you help me ? Thanks a lot...Below the snippet "recolt.lua".
--recolt.lua
local composer = require( "composer" )
local scene = composer.newScene()
function scene:create( event )
local sceneGroup = self.view
params = event.params
local background=display.newImageRect("back02.png",display.contentWidth*.5,d isplay.contentHeight*.5,320,480)
background.x,background.y=display.contentWidth*.5,display.contentHeight*.5
background.xScale,background.yScale=2,2
background.alpha=1
local circle = display.newCircle(120,100,100)
sceneGroup:insert(background,circle)
timeT=150
local function tr4()
transition.to(circle,{time=timeT,x=200,y=300,alpha=1,transition=easing.linear, xScale=1,yScale=1})
end
local function tr3()
transition.to(circle,{time=200,x=100,y=300,transition=easing.linear, xScale=.2 ,yScale=.5,onComplete=tr4})
end
local function tr2()
transition.to(circle,{time=200,x=200,y=295,transition=easing.linear, xScale=.2 ,yScale=.2,alpha=.2,onComplete=tr3})
end
local function tr1()
transition.to(circle,{time=timeT,x=300,y=300,transition=easing.linear, xScale= .5,yScale=.5,onComplete=tr2})
end
timer.performWithDelay(700,tr1,-1)
end
function scene:show( event )
local sceneGroup = self.view
params = event.params
if event.phase == "did" then
--physics.start()
end
end
function scene:hide( event )
local sceneGroup = self.view
if event.phase == "will" then
--
-- Remove enterFrame listeners here
--
--physics.stop()
end
end
function scene:destroy( event )
local sceneGroup = self.view
end
---------------------------------------------------------------------------------
-- END OF YOUR IMPLEMENTATION
---------------------------------------------------------------------------------
scene:addEventListener( "create", scene )
scene:addEventListener( "show", scene )
scene:addEventListener( "hide", scene )
scene:addEventListener( "destroy", scene )
return scene
You need to check the docs: object:insert()
The problem is you can only add 1 object into the scene with insert() function, so you only need to change
sceneGroup:insert(background,circle)
to
sceneGroup:insert(background)
sceneGroup:insert(circle)
The order matters, the first object you create go back in the scene.

Can't see text in Storyboard

I am fairly new to Corona SDK and was trying to make a game menu, but when I run the code it just don't display the text.I have know for sure that the program make it's way up to this file. Any idea why?
local storyboard = require ("storyboard")
local scene = storyboard.newScene()
display.setStatusBar (display.HiddenStatusBar)
local function ButtonTap (event)
storyboard.gotoScene(event.target.goto, {effect="slideDown"})
return true
end
function scene:CreateScene (event)
local group = self.view
-->Play Button
local PlayBtn = display.newText ("Play",0,0)
PlayBtn.x = display.contentHeight/2
PlayBtn.y = display.contentWidth/2
PlayBtn.goto = "Play"
PlayBtn:addEventListener("tap", ButtonTap)
group:insert(PlayBtn)
-->Exit Button
local ExitBtn = display.newText ("Play",0,0)
ExitBtn.x = display.contentHeight/2
ExitBtn.y = display.contentWidth/2 + 60
ExitBtn.goto = "Play"
ExitBtn:addEventListener("tap", ButtonTap)
group:insert(ExitBtn)
end
-- Called immediately after scene has moved onscreen:
function scene:enterScene( event )
local group = self.view
end
-- Called when scene is about to move offscreen:
function scene:exitScene( event )
local group = self.view
end
-- Called prior to the removal of scene's "view" (display view)
function scene:destroyScene( event )
local group = self.view
end
scene:addEventListener( "createScene", scene )
scene:addEventListener( "enterScene", scene )
scene:addEventListener( "exitScene", scene )
scene:addEventListener( "destroyScene", scene )
return scene
Thanks in advance :)
function scene:CreateScene( event ) should be function scene:createScene( event ) if you follow the standard naming conventions. Lua is case sensitive. In:
scene:addEventListener( "createScene", scene )
You're using a lowercase "c", but in the function, you use an uppercase "C". These have to match and the Corona standard would be to go with the lowercase version.

self.view Objects Cleanup

I am trying to understand how to efficiently remove scene objects once a scene is destroyed. According to corona docs objects can be inserted to self.view in order to clean them up once a scene is destroyed.
Here is my code that I am trying
local composer = require( "composer")
local scene = composer.newScene()
local rects={}
local rectsNum = 0
local rectsCount = 0
local rectsTimer
local sceneGroup
local function rectTransComplete( obj )
print("rectTransComplete .. called")
rectsCount = rectsCount + 1
if rectsCount == 3 then
composer.removeScene("scene2")
end
end
local function spawnRect( )
print("inside spawnrects")
rectsNum = rectsNum + 1
rects[rectsNum] = display.newRect( display.contentWidth/2, 100, 100, 100)
rects[rectsNum]:setFillColor( 1,1,1 )
rects[rectsNum].id = numRect
rects[rectsNum].transition = transition.to( rects[rectsNum], {time = 9000, y = display.contentHeight + 100,
onComplete = rectTransComplete
} )
sceneGroup:insert( rects[rectsNum] )
end
function scene:create( event )
sceneGroup = self.view
end
function scene:show(event)
print("inside create")
if event.phase == "did" then
rectsTimer = timer.performWithDelay( 1000, spawnRect, -1 )
end
end
function scene:hide( event )
-- body
end
function scene:destroy( event )
timer.cancel( rectsTimer )
print("scene Destroyed")
end
scene:addEventListener( "create", scene )
scene:addEventListener( "show", scene )
scene:addEventListener( "hide", scene )
scene:addEventListener( "destroy", scene )
return scene
I seems to work fine since all the rectangles are removed from the screen once the scene is destroyed but I see the app printing messages "rectTransComplete .. called" even after the scene is destroyed. Why is it so and why are the transitions not automatically cancelled once the objects are removed. Do I need to cancel all transitions manually by iterating through all the rectangles and cancel each transition. What about the rects table as it also contains references to the rects. Should I manually clean it up. If I need to manually clean everything (or most of the things), what exactly is the benefit of using self.view
Just a note, you will also have the same problem if you ever use Runtime events to propagate events to your display objects.
I had the same issue a few days ago, there are 2 ways to approach this:
Method 1: You keep a reference to the opened transitions, iterate through all your references and call transition.cancel(transitionReference) on them.
Method 2: You create a listener in your rectangles objects, send a runtime event to the rectangles object when the scene is destroyed that triggers the listener, and inside the listener you "cancel" the transition linked to current rectangle (transition.cancel(rectangle))
You can have a look at this article if you need a howto to work with runtime events: http://www.engelteddy.com/softwaredevelopment/mobiledevelopment/observer-pattern-corona-sdk/
You need to call transition.cancel() in scene:destroy function.

attempt to index global 'group' (a nil value) - lua

I am new to lua and corona sdk, and i am using the storyboard api to create an app. i have a main.lua which just sends the user to menu.lua. menu.lua code looks like this:
local storyboard = require( "storyboard" )
local scene = storyboard.newScene()
-- include Corona's "widget" library
local widget = require "widget"
-- forward declarations and other locals
local playBtn
-- 'onRelease' event listener for playBtn
local function onPlayBtnRelease()
-- go to level1.lua scene
storyboard.gotoScene( "level1", "fade", 500 )
return true -- indicates successful touch
end
-- Called when the scene's view does not exist:
function scene:createScene( event )
local group = self.view
-- display a background image
local background = display.newImageRect( "background.png", display.contentWidth, display.contentHeight )
background:setReferencePoint( display.TopLeftReferencePoint )
background.x, background.y = 0, 0
-- create/position logo/title image on upper-half of the screen
local titleLogo = display.newImageRect( "logo.png", 264, 42 )
titleLogo:setReferencePoint( display.CenterReferencePoint )
titleLogo.x = display.contentWidth * 0.5
titleLogo.y = 100
-- create a widget button (which will loads level1.lua on release)
playBtn = widget.newButton{
label="Play Now",
labelColor = { default={255}, over={128} },
fontSize = "40",
defaultFile="button.png",
overFile="button-over.png",
width=250, height=80,
onRelease = onPlayBtnRelease -- event listener function
}
playBtn:setReferencePoint( display.CenterReferencePoint )
playBtn.x = display.contentWidth*0.5
playBtn.y = display.contentHeight - 125
-- all display objects must be inserted into group
group:insert( background )
group:insert( titleLogo )
group:insert( playBtn )
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
if playBtn then
playBtn:removeSelf() -- widgets must be manually removed
playBtn = nil
end
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 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
and this is my level1.lua:
-----------------------------------------------------------------------------------------
--
-- level1.lua
--
-----------------------------------------------------------------------------------------
local storyboard = require( "storyboard" )
local scene = storyboard.newScene()
-- include Corona's "physics" library
local physics = require "physics"
physics.start(); physics.pause()
--------------------------------------------
-- forward declarations and other locals
local screenW, screenH, halfW = display.contentWidth, display.contentHeight, display.contentWidth*0.5
-----------------------------------------------------------------------------------------
-- BEGINNING OF YOUR IMPLEMENTATION
--
-- NOTE: Code outside of listener functions (below) will only be executed once,
-- unless storyboard.removeScene() is called.
--
-----------------------------------------------------------------------------------------
-- Called when the scene's view does not exist:
function scene:createScene( event )
local group = self.view
-- create a grass object
local bar= display.newImage( "bar.png", 0, 398)
local function update( event )
local group = self.view
updateBackgrounds()
end
local background1 = display.newImage("images/bg.png")
background1.x = 240
background1.y = 160
local background2 = display.newImage("images/bg.png")
background2.x = 760
background2.y = 160
function updateBackgrounds()
local group = self.view
--near background movement
background1.y = background1.y - (3)
--if the sprite has moved off the screen move it back to the
--other side so it will move back on
if(background1.x < -239) then
background1.x = 760
end
background2.y = background2.y - (3)
if(background2.x < -239) then
background2.x = 760
end
end
--this is how we call the update function, make sure that this line comes after the
--actual function or it will not be able to find it
--timer.performWithDelay(how often it will run in milliseconds, function to call,
--how many times to call(-1 means forever))
timer.performWithDelay(1, update, -1)
end
-- all display objects must be inserted into group
group:insert( background1 )
group:insert( background2 )
group:insert( bar )
-- Called immediately after scene has moved onscreen:
function scene:enterScene( event )
local group = self.view
physics.start()
end
-- Called when scene is about to move offscreen:
function scene:exitScene( event )
local group = self.view
physics.stop()
end
-- If scene's view is removed, scene:destroyScene() will be called just prior to:
function scene:destroyScene( event )
local group = self.view
package.loaded[physics] = nil
physics = nil
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
And here is my error:
When you create the group variable in the updateBackgrounds() method, self.view is nil because self.view only exists in the methods createScene() and enterScene(). What I recommend to do is create a global variable on the beginning of the script called group and then on your createScene method just do group = self.view without the "local" identifier.
Something like this:
--begining of the script
local group
-- Called when the scene's view does not exist:
function scene:createScene( event )
group = self.view
end
this creates a variable called group that has the reference of the self.view variable through all the script.
Another good option is to create a new global group and add it to the self.view on the createScene() method, this keeps things clean.
local globalGroup
function scene:createScene(event)
local group = self.view
globalGroup = display.newGroup()
group:insert(globalGroup)
end
Hope this helps.
This might because functions are not ending properly. Check if you are ending each function in level1.lua.
You are calling a function with a timer, but that function doesn't have access to self.view. Use the "enterFrame" event on Runtime, this is called at every frame:
function scene:enterFrame(event)
local group = self.view
... stuff from update functions ...
end
Runtime.addEventListener("enterFrame", scene)
If you don't need every frame, but say every second frame, put a counter in scene:enterFrame. Or in scene:enterFrame compute how much time since last call to determine if update needed.
local group
Should become
group
so that it is indeed global. Adding the local makes the 'global' become a part of only the body, not the functions, vice versa. If you need Lua practice, Roblox is a good place to start. The provide libraries already in your scripts so that it is easier to code. Try it. ;)

In Corona SDK is it possible to use Scenes for a view that partially overlays another view

I have a Settings view that I want to slide over my main game view, but only partially, so that the main view is still visible behind the Settings view (a bit like a modal dialog)
The main game view would then be darkened (or blurred) slightly so its obvious that its not active anymore.
Is it possible to use a Scene to achieve this effect? I would really prefer to keep the code for the Settings view separated from the code for the main view. If not Scenes, then any other suggestions or examples I can look at.
I managed to get it working using the following code in the tap event handler for the button in the source view:
local options =
{
effect = "zoomOutIn",
time = 200,
isModal = true,
}
storyboard.showOverlay( "scenes.settings", options )
Using isModal=true prevents any clicks on the overlay view from propagating down onto the original view which remains displayed underneath the overlay view. Here is a tutorial explaining how to create an overlay view:
http://www.coronalabs.com/blog/2012/04/27/scene-overlays-and-parameter-passing/
Yes it is possible. I'll give you a sample:
-- main.lua --
local storyboard = require "storyboard"
storyboard.gotoScene( "scene1", "fade", 400 )
-- settings.lua --
local function myObject(group,x,y,imagePath)
local image = display.newImage( imagePath )
image.x, image.y = x, y
group:insert( image )
-- add motion (if needed) --
transition.to(image, {time=1000, x=display.contentWidth/2, y=0, transition=easing.inOutQuad})
-- add Listener --
image:addEventListener("touch", function() print("imageClicked") end )
end
local status = { myObject = myObject }
return status
-- Gamemenu.lua -- (This is your game scene)
local storyboard = require( "storyboard" )
local scene = storyboard.newScene()
function scene:createScene( event )
-- create a display group --
local screenGroup = self.view
settings.myObject(screenGroup, display.contentWidth/2, -(display.contentHeight/2), "bg.jpg")
screenGroup:insert( bg )
-- require object page --
local settings = require "settings"
-- call object --
settings.myObject(screenGroup, 200, 100, "Icon.png")
end
scene:addEventListener( "createScene", scene )
return scene
Keep Coding............ :)

Resources