【问题标题】:Variables Resetting When Using Parallel Function in Lua with ComputerCraft在具有 ComputerCraft 的 Lua 中使用并行函数时的变量重置
【发布时间】:2014-12-19 23:36:39
【问题描述】:

我是一名初学者,在 ComputerCraft (Minecraft) 中设计了一个 Lua 程序,该程序在玩家第一次使用时询问他们的姓名并记录下来。现在,我想要一个程序来检测变量 firstname 是否等于 nil,如果是则询问名称。如果变量不等于 nil,则表示您不需要注册。我目前只有在主菜单中按下5后才调用register()

问题是每次我在提示时将字符串分配给firstname,当主菜单出现时firstname返回为零。我什至把print(firstname)放在菜单末尾来测试一下。

我假设这是由于这一切都运行在并行函数中。我并行运行 MainMenu()Controls(),以便我可以同时监听键盘输入和红石输入。

如何在保留变量的同时保持功能监听和菜单工作?

这里是完整的代码:

    rednet.open("back") --Opens rednet on the back side of computer

    local innerdooropen = false --Stuff to do with the airlock
    local outerdooropen = false

    function reset()  --A handy function for screen reset
      term.clear()
      term.setCursorPos(1,1)
    end

    local function register()  --This is the registration menu system
        if firstname == nil then
            print "Welcome to Obsidian Station!"
            print "You must register before entering"
            print "Please type your first name"

            local firstname = read()

            if firstname ~= "" then
                print("Enter your last name")
                local lastname = read()
                    print("You are now registered "..firstname.." "..lastname)
                    sleep(3)

                    rednet.broadcast(firstname.." "..lastname)

            elseif firstname == "" then
                print "You must register to enter"
                shell.run("startup")
            end
        end
        if firstname ~= nil then
            print("Registration Not Needed")
            sleep(2)
        end

    end

    --Beginning of Section You Don't Have to Read        
    local function MainMenu()
    while true do
    term.clear()
    term.setCursorPos(1, 1)
    if innerdooropen == true then
        rs.setOutput("left", false)
    end
    if outerdooropen == true then
        rs.setOutput("right", false)
    end
    if innerdooropen == false then
        rs.setOutput("left", true)

    end
    if outerdooropen == false then
        rs.setOutput("right", true)
    end




    print "Safety Airlock Control"
    print "~~~~~~~~~~~~~~~~~~~~~~"
    print "[1] Open Outer Door"
    print "[2] Open Inner Door"
    print "[3] Close Both Doors"
    print ""
    print "[4] Open Both Doors - WARNING! DANGEROUS!"
    print ""
    print "[5] Register"
    print(firstname)

    input = read()

    if input == "2" then
      print "Inner Door Open"
      outerdooropen = false
      sleep "1"
      innerdooropen = true

    end

    if input == "1" then
      print "Outer Door Open"
      innerdooropen = false
      sleep "1"
      outerdooropen = true
    end

    if input == "3" then
      print "Both Doors Closed"
    innerdooropen = false
    outerdooropen = false
    end

    if input == "5" then
        reset()
        register()
    end
    if input == "6" then
        print("firstname: "..firstname)
        sleep(3)
    end

    if input == "4" then
      term.clear()
      term.setCursorPos(1, 1)
      print "CONFIRM BOTH DOORS OPEN? [y] [n]"
      input = read()
      if input == "y" then
        print "OPENING AIRLOCK DOORS IN"
        sleep "1"
        print "10"
        sleep "1"
        print "9"
        sleep "1"
        print "8"
        sleep "1"
        print "7"
        sleep "1"
        print "6"
        sleep "1"
        print "5"
        sleep "1"
        print "4"
        sleep "1"
        print "3"
        sleep "1"
        print "2"
        sleep "1"
        print "1"
        sleep "1"
        innerdooropen = true
        outerdooropen = true
        print "DOORS OPEN"
        sleep "1"
      end
     elseif input == "n" then
       term.clear()
       term.setCursorPos(1, 1)
       shell.run("startup")
     end

    end
    end

    --end of section you don't have to read

    local function Controls()
        while true do
                local e = os.pullEvent()
                if e == "redstone" and rs.getInput("bottom") then
                        redstone.setOutput ("left", true)
                        sleep "1"
                        redstone.setOutput ("right", false)
                        innerdooropen = true
                        outerdooropen = false
                end
        end
    end
    while true do
       parallel.waitForAll(MainMenu,Controls)
    end

【问题讨论】:

    标签: function lua minecraft computercraft


    【解决方案1】:

    在并行之外初始化名字。将local firstname 放在代码顶部,将local firstname = read() 更改为firstname = read(),并对姓氏执行相同操作。

    在检查变量是否为 nil 后创建变量,这就是它总是返回 nil 的原因。同样,当函数结束时,firstname 不再存在,因为它是在函数内部调用和创建的。所以它总是返回零。 代码的顶部应该是这样的

    rednet.open("back") --Opens rednet on the back side of computer
    
    local innerdooropen = false --Stuff to do with the airlock
    local outerdooropen = false
    local firstname = ""
    local lastname = ""
    

    其他部分应该如下:

            if firstname == nil then
            print "Welcome to Obsidian Station!"
            print "You must register before entering"
            print "Please type your first name"
    
            firstname = read()
    
            if firstname ~= "" then
                print("Enter your last name")
                lastname = read()
                    print("You are now registered "..firstname.." "..lastname)
                    sleep(3)
    

    【讨论】:

    • 当然。这很有意义。感谢您尽可能清楚地解释这一点。
    【解决方案2】:

    你应该在检查 firstname 是否等于 nil 之前初始化它。

    local firstname = nil; --Move this up here so that you can access it elsewhere.
    local lastname = nil; --This is also needed out here.
    
    local function register()  --This is the registration menu system
        if firstname == nil then
            print "Welcome to Obsidian Station!"
            print "You must register before entering"
            print "Please type your first name"
    
            firstname = read() --Change this to just setting firstname to the read name.
    
            if firstname ~= "" then
                print("Enter your last name")
                lastname = read()
                    print("You are now registered "..firstname.." "..lastname)
                    sleep(3)
    
                    rednet.broadcast(firstname.." "..lastname)
    
            elseif firstname == "" then
                print "You must register to enter"
                shell.run("startup")
            end
        end
        if firstname ~= nil then --Now this will not error as well.
            print("Registration Not Needed")
            sleep(2)
        end
    
    end
    

    这允许在其他地方访问名字,而不仅仅是在第一个 if 语句中。您正在检查未初始化的变量是否等于 nil。

    编辑:看到 purxiz 的回答并意识到您可能还希望 lastname 位于循环之外。我现在在上面的代码中修复了它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-30
      • 2013-03-14
      • 1970-01-01
      • 2011-12-24
      • 2011-11-17
      • 1970-01-01
      相关资源
      最近更新 更多