【问题标题】:attempt to index global 'group' (a nil value) - lua尝试索引全局“组”(一个零值) - lua
【发布时间】:2014-01-12 10:15:41
【问题描述】:

我是 lua 和 corona sdk 的新手,我正在使用 storyboard api 创建一个应用程序。我有一个 main.lua,它只是将用户发送到 menu.lua。 menu.lua 代码如下所示:

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

这是我的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

这是我的错误:

【问题讨论】:

标签: lua coronasdk corona-storyboard


【解决方案1】:

在 updateBackgrounds() 方法中创建组变量时,self.view 为 nil,因为 self.view 仅存在于 createScene() 和 enterScene() 方法中。我建议做的是在脚本的开头创建一个名为 group 的全局变量,然后在你的 createScene 方法上只做 group = self.view 没有“本地”标识符。

类似这样的:

--begining of the script
local group

-- Called when the scene's view does not exist: 
function scene:createScene( event )
    group = self.view
end

这将创建一个名为 group 的变量,该变量在所有脚本中都具有 self.view 变量的引用。

另一个不错的选择是创建一个新的全局组并将其添加到 createScene() 方法的 self.view 中,这样可以保持干净。

local globalGroup

function scene:createScene(event)
    local group = self.view
    globalGroup = display.newGroup()
    group:insert(globalGroup)
end

希望这会有所帮助。

【讨论】:

  • 我认为第一个解决方案很危险:你不能保证 self.view 和 group 总是相同的(如果事件以正确的顺序调用,它们应该相同等等,但可能存在多种情况——如果你不清除——这是不正确的)。
【解决方案2】:

这可能是因为函数没有正确结束。检查是否要结束 level1.lua 中的每个函数。

【讨论】:

  • 如果你定义的函数不正确,这也是原因。
【解决方案3】:

您正在调用带有计时器的函数,但该函数无权访问 self.view。在运行时使用“enterFrame”事件,每帧都会调用:

function scene:enterFrame(event)
    local group = self.view
    ... stuff from update functions ...
end

Runtime.addEventListener("enterFrame", scene)

如果您不需要每一帧,而是说每隔一帧,请在场景中放置一个计数器:enterFrame。或者在场景中:enterFrame 计算自上次调用以来的时间,以确定是否需要更新。

【讨论】:

    【解决方案4】:
    local group    
    

    应该变成

    group
    

    所以它确实是全球性的。添加局部使“全局”成为仅主体的一部分,而不是功能的一部分,反之亦然。如果您需要 Lua 练习,Roblox 是一个不错的起点。脚本中已经提供了库,以便更容易编码。尝试一下。 ;)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-25
      • 1970-01-01
      • 1970-01-01
      • 2014-01-21
      • 2014-01-26
      相关资源
      最近更新 更多