【问题标题】:Display objects (button widgets) aren't shown when they are added to the storyboard display group显示对象(按钮小部件)在添加到情节提要显示组时不显示
【发布时间】:2014-04-25 09:53:25
【问题描述】:

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

当我将它们包含到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

【问题讨论】:

    标签: mobile lua storyboard coronasdk


    【解决方案1】:

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

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

    改用storyboard.gotoScene("time_select"),以便您的应用转换到另一个场景(除非您打算将time_select 用作叠加层,否则请使用storyboard.showOverlay)。

    更新:看起来有两个问题,正如您自己的回答所证明的那样。我将您的固定代码复制到我的模拟器并执行它,果然,loadScene() 我什么都看不到;我不得不使用gotoScene()

    但是,您的回答中有几处不正确:

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

    这两点演示如下:我将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.lua 在单独的文件中。

    【讨论】:

    • 你的解释很有道理。我在 main.lua 中将loadScene 换成了gotoScene,但它仍然拒绝出现。我尝试了我找到的其他故事板示例,它们都不起作用,我觉得它可能是我的构建版本(2013.2100)
    • @EjayTumacder 如果没有一个示例适用于您安装的 2100,那么所有的赌注都没有了,但是我相信一旦您找到了适用于开箱即用的 Corona 版本例如,您将不得不按照上述更改您的代码。请注意,2100 是我使用的稳定版本,我会尝试卸载并重新安装。还有你所说的“不工作”是什么意思?
    • 对不起,我应该详细说明“不工作”。他们似乎都给了我空白屏幕。我使用了这个github.com/RevMob/corona-sample-with-storyboard 和附加到这个develephant.net/… 的代码,仅举几例。它们似乎都不起作用
    • 打开 Corona 模拟器后,您会在右侧看到“Doc​​s Samples Forum Learn”吗?从“入门”组中选择一个示例。他们的样本是否运行?
    • 我找到了解决方案,原因似乎是您发布的答案的一部分。我认为我的构建没有任何问题。我想我只是很沮丧:)
    【解决方案2】:

    好的,所以我找到了一个适用于我的构建 (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
    

    【讨论】:

    • +1 表示答案的第二部分。内部不需要监听器,也不需要将第一个场景放在单独的文件中,只有运行时监听器需要显式删除。所以我扩展了我的回答来讨论这些观点,因为它们可能会误导 Corona 的其他新手用户。
    • 感谢您的智慧和指导。拿起 Corona + Lua 很艰难。
    【解决方案3】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-12-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多