2014-01-12 5 views
0

Я новичок в lua и corona sdk, и я использую раскадровку api для создания приложения. У меня есть main.lua, который просто отправляет пользователя в menu.lua. Menu.lua код выглядит следующим образом:попытка индексации глобальной «группы» (значение nil) - 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 

А вот моя ошибка:

img

+0

См. Http://stackoverflow.com/help/mcve –

ответ

1

При создании группы переменная в методе updateBackgrounds(), self.view - это nil, потому что self.view существует только в методах createScene() и enterScene(). То, что я рекомендую сделать, это создать глобальную переменную в начале скрипта, называемого группой, а затем по вашему методу 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 

это создает переменную группу, которая имеет ссылку переменной self.view через все сценарии.

Другим хорошим вариантом является создание новой глобальной группы и добавление ее в self.view по методу createScene(), что сохраняет чистоту.

local globalGroup 

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

Надеюсь, что это поможет.

+0

Я думаю, что первое решение опасно: вы не можете гарантировать, что self.view и группа всегда одинаковы (они должны быть одинаковыми, если события вызываются в правильном порядке и такие, но могут быть случаи, например, для нескольких сценариев - если вы не очищаете - где это неверно). – Schollii

0

Вы вызываете функцию с таймером, но эта функция не имеет доступа к self.view. Используйте «enterFrame» событие во время выполнения, это называется на каждом кадре:

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

Runtime.addEventListener("enterFrame", scene) 

Если вам не нужно каждый кадр, но говорят, что каждый второй кадр, поставить счетчик на сцене: enterFrame. Или в сцене: enterFrame вычислить, сколько времени с момента последнего вызова определить, требуется ли обновление.

1

Это может быть потому, что функции не заканчиваются должным образом. Проверьте, завершаете ли вы каждую функцию в level1.lua.

+0

Это также приводит к неправильной настройке функции. – UVM

0
local group  

должны стать

group 

так, что это действительно глобальный характер. Добавление локального означает, что «глобальный» становится частью только тела, а не функций, наоборот. Если вам нужна практика Lua, Roblox - хорошее место для начала. Предоставляйте библиотеки уже в ваших сценариях, чтобы их было легче закодировать. Попробуй. ;)

Смежные вопросы