【问题标题】:Runtime event listener works, but not object (LUA, SUBLIME TEXT 3, CORONA SDK)运行时事件监听器有效,但不是对象(LUA、SUBLIME TEXT 3、CORONA SDK)
【发布时间】:2017-09-27 20:40:37
【问题描述】:

与之前的主题相关,Piglet 很有帮助地回答了这个问题,他将我引导到这个问题的文档:Using a table in Lua to display text isn't working?... 以供参考。

由于该项目花费了我多长时间,我决定重新设计大部分程序以赶上我的最后期限。我使用文档的帮助来正确修复 .text 显示。但是,我应该有一个功能变化的“vnText”对象,我可以调整它的文本。但是......它仅在我使用运行时事件侦听器时才有效,而不是对象本身。

虽然我很高兴使用运行时事件侦听器在截止日期前完成我的项目,但我想知道为什么 object:addEventListener 没有像往常一样工作。我的代码中是否缺少某些东西,运行时完成了单击“textRect”不会完成的东西?

该行特别是

Runtime:addEventListener("tap", changePage)

当我运行它时,它现在可以完美运行。从表格中提取值,显示命令 print("change text")。

我尝试使用的对象是 textRect,它是在程序前面定义的,上面有几个表。将文本绘制出来并将其放入文本中是行不通的。但是 Runtime 做到了,而我终其一生都无法理解为什么。

然而,一个有趣的事实是,当我使用 textRect 时,会打印“更改文本”。但是函数没有改变 vnText.text ......?这就是我编写程序的全部原因。

我搜索了文档和其他线程,希望能找到答案。然而,代码比我自己的水平要复杂得多,因为我只是一个从课堂PPT学习的高中生;现在我只是在寻找为什么运行时有效的答案?如果有什么我可以做的事情来让这个对象工作。

感谢您的帮助,Stack Overflow 的成员们!在过去的一个月里,你们都帮助我学习了很多东西。

local store = require( "plugin.google.iap.v3" )
local composer = require("composer")
local scene = composer.newScene()

display.setStatusBar( display.HiddenStatusBar )  -- Removes status bar
coins = 5 --[[variable that defines the number of coins player has in the game. It will be different 
in a stand alone game, but as a small app meant to demonstrate function, it's necessary to start off
with a small, defined number in the beginning.]]

local logo = display.newImage("/Images/logo.png", 155, 275) --code for my personal logo, drawn by me. 
--Not actually showcased in the video because of time limit.
logo.alpha = 0

local function makeTitleTrue() --this function makes the title true once the logo has been shown and faded out
    logo:removeSelf() -- removes logo from screen
    print("menu should be TRUE")
    titleScreen() -- calls function titleScreen (which is thetitle menu)
end

local function fadeOut()
    transition.to(logo, {time = 1000, alpha = 0, onComplete = makeTitleTrue})
end

transition.to(logo, {time = 1000, alpha = 1, onComplete = fadeOut}) -- end of logo code

function titleScreen() -- beginning of title code, which is not managed as a separate scene
    title = true 
    titleImg = display.newImage("/Images/vn_bg.png", 155, 275)
    --titleWords = display.newImage("/Images/TitleWords.png", 155, 275)

    --particles that flow across the screen as a cool effect. fix to flow towards the upper right corner.
    local flare = display.newImage("/Images/flare2.png", 40, 30)
    flare.xScale = .5
    flare.yScale = .5
    local flare2 = display.newImage("/Images/flare2.png", 400, 70)
    flare2.xScale = .6
    flare2.yScale = .6
    local flare3 = display.newImage("/Images/flare2.png", -30, 100)
    flare3.xScale = .4
    flare3.yScale = .4
    local flare4 = display.newImage("/Images/flare2.png", 100, 400)
    flare4.xScale = .4
    flare4.yScale = .4
    local flare5 = display.newImage("/Images/flare2.png", 400, 400)
    flare5.xScale = .3
    flare5.yScale = .3
    local flare6 = display.newImage("/Images/flare2.png", 250, 200)
    flare6.xScale = .3
    flare6.yScale = .3

    local function moveFlare1() 
        transition.to(flare, {time=2000, x = math.random(-100, 450), y = math.random(-100, 700), onComplete = moveFlare1})
    end
    local function moveFlare2()
        transition.to(flare2, {time=2000, x = math.random(-100, 450), y = math.random(-100, 700), onComplete = moveFlare2})
    end 
    local function moveFlare3()
        transition.to(flare3, {time=2000, x = math.random(-100, 450), y = math.random(-100, 700), onComplete = moveFlare3})
    end
    local function moveFlare4()
        transition.to(flare4, {time=2000, x = math.random(-100, 450), y = math.random(-100, 700), onComplete = moveFlare4})
    end 
    local function moveFlare5()
        transition.to(flare5, {time=2000, x = math.random(-100, 450), y = math.random(-100, 700), onComplete = moveFlare5})
    end 
    local function moveFlare6()
        transition.to(flare6, {time=2000, x = math.random(-100, 450), y = math.random(-100, 700), onComplete = moveFlare6})
    end 
    transition.to(flare, {time=2000, x = math.random(-100, 450), y = math.random(-100, 700), onComplete = moveFlare1})
    transition.to(flare2, {time=2500, x = math.random(-100, 450), y = math.random(-100, 700), onComplete = moveFlare2}) 
    transition.to(flare3, {time=2000, x = math.random(-100, 450), y = math.random(-100, 700), onComplete = moveFlare3}) 
    transition.to(flare4, {time=2000, x = math.random(-100, 450), y = math.random(-100, 700), onComplete = moveFlare4}) 
    transition.to(flare5, {time=2000, x = math.random(-100, 450), y = math.random(-100, 700), onComplete = moveFlare5}) 
    transition.to(flare6, {time=2000, x = math.random(-100, 450), y = math.random(-100, 700), onComplete = moveFlare6}) 

    --add options that can when the screen is tapped, tap on an option twice to select
    --local newGame_op = display.newImage("", )
    --local cont_op = display.newImage("", )
    --local coin_op = display.newImage("",)
    --local end_op = display.newImage("",)
        -- start story
        -- continue story
        -- coin gambling
        -- end game

    if (title == true) then
        Runtime:addEventListener("tap", sceneVN)
    end

    --coin_op:addEventListener("tap", coinShop)
end

function forceQuit()
    function quit() 
        os.exit() 
        end 
        timer.performWithDelay(1000,quit)
    end

function sceneVNChapter2()
    return
end

function sceneVN() -- the actual visual novel code itself
    display.remove(titleImg)
    display.remove(flare)
    display.remove(flare2)
    display.remove(flare3)
    display.remove(flare4)
    display.remove(flare5)
    display.remove(flare6)
    title = false
    Runtime:removeEventListener()

    page = 0

    local coinSheetData =
    {
        width = 32,
        height = 32,
        numFrames = 8,
    }

    local coinimageSheet = graphics.newImageSheet( "/Images/spinning_coin.png", coinSheetData )

    local sequenceData =
    {
        name= "spinning_coin",
        start = 1, 
        count = 8,
        time = 1000,
        loopCount = 0
    }

    --the properties of the name plate that can be changed ingame by using ".text" property
    local nameOptions = 
    {
        text = "Frankenstein",  
        x = 165,
        y = 450,
        width = 310,
        font = "Charlesworth.ttf",
        fontSize = 22,
        align = "left"
    }
    local bg = display.newImage("/Images/bg4.jpg", 155, 275)
    local bust_display = display.newImage( "/Images/f_bust1.png", 155, 223 )
    textRect = display.newRect(155, 525, 325, 200)
    textRect:setFillColor(.02, .02, .02)
    textRect.alpha = .9

    local frames = display.newImage("/Images/windowframes_gold.png", 155, 275)
    display.newText(nameOptions)

    local scriptIntro =
    {
        [1] = "\"I see. So I\'m supposed to pretend I am\na character in a multi-chapter phone\napp that you\'ve been reading...\"",
        [2] = "\"So the purpose of this game is to flirt\nwith me until the meter fills up, and\nyou earn enough coins for a date?\"",
        [3] = "\"Then let's see how far you get. Charm\nme by picking the right compliments\nto praise me, my lady.\"",
        [4] = "\"When the meter is full, you'll be able\nto ask me on a date to progress the\ngame.\"",
        [5] = "\"Let's start the game, then... Can you\ncharm me, the butler of the Raizel\nhousehold?\""
    }

    vnText = display.newText("\"Good evening. This is a demonstration\nof a visual novel and minigame...\"", 160, 500, "Goudy Old Style Regular.ttf", 17)
    vnText.x = 20 ; vnText.y = 495
    vnText:setFillColor( 1, 1, 1 )
    vnText.anchorX = 0

    local function changePage()
        page = page + 1
        print("change text")
        vnText.text = scriptIntro[page]
    end

    Runtime:addEventListener("tap", changePage)

    function choiceGame()
        local c_Complimented = {
            [1] = "\"Aha... thank you so much. I do my best.\"",
            [2] = "\"Ah, please, you flatter me too much! I\ncannot even begin to compare with\nyour praises.\"",
            [3] = "\"You're making me blush, my lady. Where\ndid you learn such charm?\"",
            [4] = "\"I really don't know what to say... how\nsweet.\""
        }

        local c_Insulted = {
            [1] = "\"Is that really your best attempt at a\nflirt? Pathetic...\"",
            [2] = "\"A butler of the Raizel household can\'t\n even begin to contemplate the idea\n of dating you.\"",
            [3] = "\"Haha... what a wonderful choice... NOT.\nTry again, darling.\"",
            [4] = "\"Such insults are below even your calibre,\n my lady.\""
        }

        local function optionChosen()
            if (compliment == true) then 
                displayStatus.text = c_Complimented[math.random(1,4)]
            else
                displayStatus.text = c_Insulted[math.random(1,4)]
            end
        end 

        displayStatus = display.newText("Haha... I look forward to your attempts\nat flirting with me.", 160, 500, "Goudy Old Style Regular.ttf", 17)

        Runtime:addEventListener("tap", optionChosen)
    end -- end of choice game

    local function flirtComplete()
        local scriptComplete = 
        {
            [1] = "\"Then, seeing as this is a simulation of\n a visual novel dating sim, I have no\n choice but to ask you...\"",
            [2] = "\"My lady, would you go on a date with me?\nFrankenstein... butler of the finest noble,\nCadis Etrama di Raizel?\"",
            [3] = "\"So, have you made a decision about whether\nyou would like to date yet?\""
        }
    end

    if (coins < 10) then
        coinsDigits = 2
    else 
        if (coins > 9) and (coins < 100) then 
            coinsDigits = 3
        else 
            if (coins > 99) and (coins < 1000) then 
                coinsDigits = 4
            else 
                if (coins > 999) and (coins < 10000) then 
                    coinsDigits = 5
                else 
                    if (coins > 9999) and (coins < 100000) then
                        coinsDigits = 6
                    end
                end
            end
        end
    end

    cooin = display.newSprite(coinimageSheet, sequenceData)
    cooin.x = 25
    cooin.y = 30
    cooin:play()

    coinText = display.newText("1", 57 + 4 * coinsDigits, 32, "VCR_OSD_MONO_1.001.ttf", 25)
    coinText.text = coins
    coinTimer = timer.performWithDelay(2000, cooin, 1)
end

function choiceMade( event ) --the scenes where all the choices are made
    if (event.action == "clicked") then 
        local i = event.index
        if (i == 1) then 
            Runtime:removeEventListener()
            titleScreen()
            else
                if (i == 2) then 
                    system.openURL( "https://www.paypal.com/us/home" )
                else
                    if (i == 3) then 
                        return 
                    end
                end
            end
        end
    end -- end of choice scenes

function Outofcoins()
--native alert lack of zero coins
    local alertMessage = "Uh oh, looks like you've run out of coins! Would you like to keep flirting, or buy more?"
    native.showAlert( "Out of coins!", alertMessage, {"Continue flirting", "Purchase coins", "Exit to Menu"}, choiceMade)
end 


function sceneGambleStart()

    function earntCoins()
        numberEarnt = 0
        local coinsGot = display.newImage("/Images/coins_gold.png", 155, 275)
        coinsGot.alpha = 0

        local function fadeOutCoinsEart()
            transition.to(logo, {time = 2000, alpha = 0})
            display.remove(coinsGot)
        end

        local transitionFade = transition.to(logo, {time = 2000, alpha = 1, onComplete = fadeOutCoinsEarnt})
        timer.performWithDelay(2000, transitionFade, 1)
        coinText.text = coins + numberEarnt
    end
end

【问题讨论】:

  • 如果您没有使用scene template 中所述的常用方法(scene:create()scene:show() 等)设置场景,是否有原因。
  • 可能是范围问题。我将在scene:create() 中完成所有这些设置,并在该方法的顶部将所有将保存显示对象的变量声明为local。然后,当您稍后声明侦听器函数(local function changePage 等)时,您知道您的 DisplayObjects 在范围内。
  • display.newText(nameOptions) 没有被分配给任何东西 BTW
  • 啊,我不知道场景模板。我的代码是老师一直向我们展示的。她设置场景的风格从过去的 Javascript 课程中继承下来,所以我从没想过会有另一种方式……看看你发给我的链接,我们几乎没有学到任何涉及的命令。 "if ( phase == "will" )" 和 "( phase == "did" )",以及设置函数的风格——我们从未在函数名中使用冒号,也从未使用过“自我视图”。按原样完成程序对我来说仍然可行,但在项目完成后我会尝试这个建议!谢谢!
  • 我明白了。所以所有这些代码都在你的main.lua 中?我并不是说这就是你对vnText 的问题的原因。

标签: lua coronasdk lua-table event-listener


【解决方案1】:

正如您的代码一样,textRectvnText 在范围内都是全局的,但 scriptIntrolocal 并在 textRect 之后声明。因此,如果您尝试将tap 侦听器添加到引用scriptIntrotextRect,它将无法正常工作。事实上,所有这些变量都可能是local;只需按正确的顺序声明它们:

local scriptIntro = ...  -- an array of strings

local vnText = display.newText(...
vnText.text = scriptIntro[1]

local n = 1
local textRect = display.newRect(...
function textRect:tap( event )
    n = n + 1
    if n > #scriptIntro then
        n = 1
    end
    vnText.text = scriptIntro[n]
    return true
end
textRect:addEventListener( "tap", textRect )

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-04-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多