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

user3144971 picture user3144971 · Jan 12, 2014 · Viewed 16.4k times · Source

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:

img

Answer

Fayer picture Fayer · Jan 12, 2014

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.