将它们添加到情节提要显示组时,不显示显示对象(按钮小部件)

时间:2014-03-19 09:16:24

标签: mobile lua storyboard corona

我有一个简单的场景。有三个按钮小部件和一个标题。

当我将它们包含在group中时,不会绘制对象。但是,当我不包括它们时,它们会出现。但是当场景退出时它们不会消失。

我一直在阅读故事板模块,我确信我正在以正确的方式使用它,将它们包含在组中。

为什么显示对象在包含在组中时不会被绘制?

我将包括我的main.lua,以防万一。

main.lua:

local storyboard = require("storyboard")
local mydata = require("mydata")

local widget = require( "widget" )

centerX = display.contentCenterX
centerY = display.contentCenterY
_W = display.contentWidth
_H = display.contentHeight

display.setStatusBar( display.HiddenStatusBar )

local bkg = display.newImage( "stripes.png", centerX, centerY )

local disclaimer = display.newText("DISCLAIMER", 300-75, centerY-175, 320, 0, "Helvetica", 30 )

local message = display.newText("The creators take no responsibility for\nany damage done by this app, etc.\n", 300-110, centerY-120, 320, 0, "Helvetica", 16)


local howtoTitle = display.newText("HOW TO PLAY", 300-85, centerY-50,320, 0, "Helvetica", 30)
local howto = display.newText("1. Select Time Frame\n      2.Select Sides\n       3.Have Fun", 300-60, centerY, 320, 0, "Helvetica", 16)

mydata.time = 0
mydata.sides = 0
mydata.hits = 0

-- Function to handle button events
local function handleButtonEvent( event )
    local phase = event.phase
    if "ended" == phase then
        event.target:removeSelf()
        disclaimer:removeSelf()
        message:removeSelf()
        howto:removeSelf()
        howtoTitle:removeSelf()
        storyboard.loadScene("time_select")
    end
end

local playButton = widget.newButton {
    left = 100,
    top = 350,
    width = 105,
    height = 39,
    defaultFile = "start.png",
    overFile = "start_pressed.png",
    label = "",
    onEvent = handleButtonEvent,
}

time_select.lua:

local storyboard = require("storyboard")
local widget = require("widget")

local scene = storyboard.newScene()

local mydata = require("mydata")

local function fifteenSecondButtonEvent( event )
    local phase = event.phase
    if "ended" == phase then
        mydata.time = 15
        storyboard.gotoScene("play")
    end
end

local function thirtySecondButtonEvent( event )
    local phase = event.phase
    if "ended" == phase then
        mydata.time = 30
        storyboard.gotoScene("play")
    end
end

local function sixtySecondButtonEvent( event )
    local phase = event.phase
    if "ended" == phase then
        mydata.time = 60
        storyboard.gotoScene("play")
    end
end



function scene:createScene( event )
    local group = self.view
    local timeText = display.newText("TIME", 160, 70, "Helvetica", 30)
    group:insert( timeText )

    local fifteenButton = widget.newButton {
        time = 15,
        left = 75,
        top = 150,
        width = 164,
        height = 42,
        defaultFile = "fifteen_button.png",
        overFile = "fifteen_button_pressed.png",
        label = "",
        onRelease = fifteenSecondButtonEvent
    }
    group:insert(fifteenButton)

    local thirtyButton = widget.newButton {
        time = 30,
        left = 75,
        top = 250,
        width = 164,
        height = 42,
        defaultFile = "thirty_button.png",
        overFile = "thirty_button_pressed.png",
        label = "",
        onRelease = thirtySecondButtonEvent
    }
    group:insert(thirtyButton)

    local sixtyButton = widget.newButton {
        time = 60,
        left = 75,
        top = 350,
        width = 164,
        height = 42,
        defaultFile = "sixty_button.png",
        overFile = "sixty_button_pressed.png",
        label = "",
        onRelease = sixtySecondButtonEvent
    }
    group:insert(sixtyButton)
    print( "Number of children in Display Group: " .. group.numChildren )
end

function scene:willEnterScene( event )
    local group = self.view
end

function scene:enterScene( event )
    local group = self.view
end

function scene:exitScene( event )
    local group = self.view
    fifteenButton:removeEventListener( 'onRelease', fifteenSecondButtonEvent ) -- line 92
    thirtyButton:removeEventListener( 'onRelease', thirtySecondButtonEvent )
    sixtyButton:removeEventListener( 'onRelease', sixtySecondButtonEvent )

    timeText:removeSelf()
    timeText = nil
    if fifteenButton then
        fifteenButton:removeSelf()
        fifteenButton = nil
    end

    if thirtyButton then
        thirtyButton:removeSelf()
        thirtyButton = nil
    end

    if sixtyButton then
        sixtyButton:removeSelf()
        sixtyButton = nil
    end

    display.remove(group)
    storyboard.removeScene( "time_select" )

end

function scene:destroyScene( event )
    local group = self.view
end

scene:addEventListener("createScene", scene)
scene:addEventListener("willEnterScene", scene)
scene:addEventListener("enterScene", scene)
scene:addEventListener("exitScene", scene)
scene:addEventListener("destroyScene", scene)

return scene

3 个答案:

答案 0 :(得分:1)

这是因为您正在使用storyboard.loadScene("time_select")。这会加载场景但不会显示,因此您无法看到添加到其视图组的对象。当您没有将对象添加到视图组时,它们会显示出来,因为默认情况下,对象会被置于默认的"根级别"组,称为阶段。来自Group Programming Guide绘图模型部分:

  

未放入特定组的显示对象成为舞台的一部分

改为使用storyboard.gotoScene("time_select"),以便您的应用转换到其他场景(除非您打算将time_select作为叠加层,然后使用storyboard.showOverlay)。

更新:看起来有两个问题,正如您自己的回答所示。我将你的固定代码复制到我的模拟器并执行它,当然,loadScene()我看不到任何东西;我不得不使用gotoScene()

但是,答案中有几件事情是不正确的:

  1. main.lua可以创建第一个场景:scene = storbyboard.newScene("scene1")然后storyboard.gotoScene("uniqueName")并且所有scene1事件处理程序(createScene等)都可以在main.lua中。
  2. 您可以将侦听器功能放在任何您想要的位置。
  3. 当对象调用removeSelf时,在对象上注册的侦听器将自动取消注册。运行时不是显示对象,因此对于像" enterFrame"这样的运行时侦听器,在退出场景时必须明确地删除EventHandler。
  4. 您不需要removeSelf中的destroyScene个对象,因为这会在scene.view被删除后自动完成(destroyScene调用后自动完成)。
  5. 您不应该在removeScene('time_select')中致电time_select.exitScene,这没有任何意义!退出时的removeScene将导致从exitScene调用destroyScene!如果您知道不再需要time_select场景,则可以将其从(例如)主场景enterScene中删除。这将调用time_select的destroyScene,并删除scene.view组。后者将以递归方式删除组中的每个对象(将取消注册这些对象的侦听器)。
  6. 这两点如下所示:我将你的scene1.lua移动到main.lua并相应修复了main.lua;我将handleButtonEvent移出createScene。

    main.lua:

    local storyboard = require "storyboard"
    local widget = require "widget"
    
    local scene = storyboard.newScene("scene1")
    
    local mydata = {} -- require("mydata")
    local widget = require( "widget" )
    
    local centerX = display.contentCenterX
    local centerY = display.contentCenterY
    local _W = display.contentWidth
    local _H = display.contentHeight
    
    mydata.time = 0
    mydata.sides = 0
    mydata.hits = 0
    
    local function handleButtonEvent( event )
        if "ended" == event.phase then
            storyboard.gotoScene("time_select", "fade", 500)
        end
        return true
    end
    
    function scene:createScene( event )
        local group = self.view
        local background = display.newImage( "stripes.png", centerX, centerY )
        background.anchorX, background.anchorY = 0.0,0.0
        background.x, background.y = 0, 0
        group:insert( background )
    
        local disclaimer = display.newText("DISCLAIMER", 300-75, centerY-175, 320, 0, "Helvetica", 30 )
        group:insert( disclaimer )
        local message = display.newText("The creators take no responsibility for\nany damage done by this app, etc.\n", 300-110, centerY-120, 320, 0, "Helvetica", 16)
        group:insert( message )
        local howtoTitle = display.newText("HOW TO PLAY", 300-85, centerY-50,320, 0, "Helvetica", 30)
        group:insert( howtoTitle )
        local howto = display.newText("1. Select Time Frame\n      2.Select Sides\n       3.Have Fun", 300-60, centerY, 320, 0, "Helvetica", 16)
        group:insert( howto )
    
        local playButton = widget.newButton {
            left = 100,
            top = 350,
            width = 105,
            height = 39,
            label = "Play",
            onEvent = handleButtonEvent,
        }
        playButton.isActive = true
        group:insert(playButton)
    end
    
    function scene:enterScene( event )
        local group = self.view
    end
    
    function scene:exitScene( event )
        local group = self.view
    end
    
    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 )
    
    -- load first scene
    storyboard.gotoScene( "scene1", "fade", 400 )
    

    time_select.lua`:

    local storyboard = require("storyboard")
    local widget = require("widget")
    
    local scene = storyboard.newScene()
    
    local mydata = {} -- require("mydata")
    
    local function fifteenSecondButtonEvent( event )
        local phase = event.phase
        if "ended" == phase then
            mydata.time = 15
            storyboard.gotoScene("play")
        end
    end
    
    local function thirtySecondButtonEvent( event )
        local phase = event.phase
        if "ended" == phase then
            mydata.time = 30
            storyboard.gotoScene("play")
        end
    end
    
    local function sixtySecondButtonEvent( event )
        local phase = event.phase
        if "ended" == phase then
            mydata.time = 60
            storyboard.gotoScene("play")
        end
    end
    
    function scene:createScene( event )
        local group = self.view
        local timeText = display.newText("TIME", 160, 70, "Helvetica", 30)
        group:insert( timeText )
    
        local fifteenButton = widget.newButton {
            time = 15,
            left = 75,
            top = 150,
            width = 164,
            height = 42,
            label = "15 Button",
            onRelease = fifteenSecondButtonEvent
        }
        group:insert(fifteenButton)
    
        local thirtyButton = widget.newButton {
            time = 30,
            left = 75,
            top = 250,
            width = 164,
            height = 42,
            label = "30 Button",
            onRelease = thirtySecondButtonEvent
        }
        group:insert(thirtyButton)
    
        local sixtyButton = widget.newButton {
            time = 60,
            left = 75,
            top = 350,
            width = 164,
            height = 42,
            label = "45 Button",
            onRelease = sixtySecondButtonEvent
        }
        group:insert(sixtyButton)
        print( "Number of children in Display Group: " .. group.numChildren )
    end
    
    function scene:willEnterScene( event )
        local group = self.view
    end
    
    local demoNonObjListenerCount
    local function enterFrame(event)
        demoNonObjListenerCount = demoNonObjListenerCount + 1 
    end
    
    function scene:enterScene( event )
        local group = self.view
    
        Runtime:addEventListener('enterFrame', enterFrame)
    end
    
    function scene:exitScene( event )
        local group = self.view
    
        Runtime:removeEventListener('enterFrame', enterFrame)    
    end
    
    function scene:destroyScene( event )
        local group = self.view
        -- self.view will be removed upon return, which will 
        -- remove display objects contained, recursively, so 
        -- here not much else to do
    end
    
    scene:addEventListener("createScene", scene)
    scene:addEventListener("willEnterScene", scene)
    scene:addEventListener("enterScene", scene)
    scene:addEventListener("exitScene", scene)
    scene:addEventListener("destroyScene", scene)
    
    return scene
    

    time_select.lua的内容甚至可以放在main.lua中,如果你更换了"场景"比如," timeSelect"并使用了timeSelect = storyboard.newScene("time_select")。但是,模块化效果更好,因此最好将time_select方案保留在自己的文件中,但scene1不必与main.lu a位于单独的文件中。

答案 1 :(得分:1)

好的,所以我找到了一个可用于构建的示例故事板(2013.2100),我玩它来找到我的问题。我正在main.lua文件中绘制显示对象。似乎是惯例,main.lua的唯一目的是引导你到第一个场景。我将前两个文件分成三个单独的文件,它们都按照它的方式工作。

我相信原因也是@ Schollii答案的一部分:

  

未放入特定组的显示对象成为舞台的一部分

background是舞台的一部分,所以当它切换到下一个场景时,它被舞台上的显示对象覆盖。

@ user3439409我听说你必须把监听器功能放在createScene里面,就像我在下面的代码中一样。至于addEventListener,removeEventListener等。你不应该做addEventListener,因为widget为你做了。但是,我听说你应该删除事件监听器,因为它在内存中徘徊。您可以通过添加有关内存的打印语句来检查内存泄漏。为此,您可以使用storyboard.printMemUsage()

main.lua(现在只有3行):

display.setStatusBar( display.HiddenStatusBar )

local storyboard = require("storyboard")

storyboard.gotoScene( "start", "fade", 500 )

start.lua(我以前的main.lua):

local storyboard = require( "storyboard")
local scene = storyboard.newScene()

mydata = require("mydata")
widget = require( "widget" )

centerX = display.contentCenterX
centerY = display.contentCenterY
_W = display.contentWidth
_H = display.contentHeight

mydata.time = 0
mydata.sides = 0
mydata.hits = 0

function scene:createScene( event )
    local group = self.view
    local background = display.newImage( "stripes.png", centerX, centerY )
    background.anchorX, background.anchorY = 0.0,0.0
    background.x, background.y = 0, 0
    group:insert( background )

    local disclaimer = display.newText("DISCLAIMER", 300-75, centerY-175, 320, 0, "Helvetica", 30 )
    group:insert( disclaimer )
    local message = display.newText("The creators take no responsibility for\nany damage done by this app, etc.\n", 300-110, centerY-120, 320, 0, "Helvetica", 16)
    group:insert( message )
    local howtoTitle = display.newText("HOW TO PLAY", 300-85, centerY-50,320, 0, "Helvetica", 30)
    group:insert( howtoTitle )
    local howto = display.newText("1. Select Time Frame\n      2.Select Sides\n       3.Have Fun", 300-60, centerY, 320, 0, "Helvetica", 16)
    group:insert( howto )

    local playButton = nil
    local function handleButtonEvent( event )
        if "ended" == event.phase then
            storyboard.gotoScene("time_select", "fade", 500)
        end
        return true
    end
    playButton = widget.newButton {
        left = 100,
        top = 350,
        width = 105,
        height = 39,
        defaultFile = "start.png",
        overFile = "start_pressed.png",
        label = "",
        onEvent = handleButtonEvent,
    }
    playButton.isActive = true
    group:insert(playButton)
end

function scene:enterScene( event )
    local group = self.view
end

function scene:exitScene( event )
    local group = self.view
end

function scene:destroyScene( event )
    local group = self.view
end

-- Function to handle button events


scene:addEventListener( "createScene", scene )
scene:addEventListener( "enterScene", scene )
scene:addEventListener( "exitScene", scene )
scene:addEventListener( "destroyScene", scene )

return scene

time_select.lua(我将侦听器函数放在createScene中):

local storyboard = require("storyboard")

local scene = storyboard.newScene()

 local widget = require "widget"

function scene:createScene( event )
    local group = self.view
    --local background = display.newImage("stripes.png", centerX, centerY)
    --group:insert(backgroundz)

    local background = display.newImage( "stripes.png", centerX, centerY )
    background.anchorX, background.anchorY = 0.0,0.0
    background.x, background.y = 0, 0
    group:insert( background )

    local timeText = display.newText("TIME", 0, 0, "Helvetica", 30)
    timeText.x = _W/2
    timeText.y = _H/2 - 150
    timeText:setFillColor( 255, 255, 255 )
    group:insert(timeText)

    local fifteenButton = nil
    local function fifteenSecondButtonEvent( event )
        if "ended" == event.phase then
            mydata.time = 15
            storyboard.gotoScene("sides_selection")
        end
        return true
    end
    fifteenButton = widget.newButton {
        left = 75,
        top = 150,
        width = 164,
        height = 42,
        defaultFile = "fifteen_button.png",
        overFile = "fifteen_button_pressed.png",
        label = "",
        onRelease = fifteenSecondButtonEvent
    }
    fifteenButton.isActive = true
    group:insert(fifteenButton)

    local thirtyButton = nil
    local function thirtySecondButtonEvent( event )
        local phase = event.phase
        if "ended" == phase then
            mydata.time = 30
            storyboard.gotoScene("play")
        end
    end
    thirtyButton = widget.newButton {
        left = 75,
        top = 250,
        width = 164,
        height = 42,
        defaultFile = "thirty_button.png",
        overFile = "thirty_button_pressed.png",
        label = "",
        onRelease = thirtySecondButtonEvent
    }
    thirtyButton.active = true
    group:insert(thirtyButton)

    local sixtySecondButtonEvent = nil
    local function sixtySecondButtonEvent( event )
        local phase = event.phase
        if "ended" == phase then
            mydata.time = 60
            storyboard.gotoScene("play")
        end
    end
    sixtyButton = widget.newButton {
        left = 75,
        top = 350,
        width = 164,
        height = 42,
        defaultFile = "sixty_button.png",
        overFile = "sixty_button_pressed.png",
        label = "",
        onRelease = sixtySecondButtonEvent
    }
    group:insert(sixtyButton)
end

function scene:enterScene( event )
    local group = self.view
end

function scene:exitScene( event )
    local group = self.view
end

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

答案 2 :(得分:0)

如果您使用的是故事板,则需要调用storyboard.removeScene()方法从显示组中删除所有对象。 这是参考。 http://docs.coronalabs.com/api/library/storyboard/removeScene.html http://docs.coronalabs.com/api/library/storyboard/