function - 在 ComputerCraft 中使用 Lua 中的并行函数时的变量重置

标签 function lua minecraft computercraft

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

问题是,每次我在提示时将字符串分配给 firstname 时,当主菜单出现时,firstname 都会返回 nil。我什至将 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

最佳答案

在并行之外初始化名字。将 local firstname 放在代码顶部,然后将 local firstname = read() 更改为 firstname = read(),然后执行姓氏也一样。

您在检查变量是否为 nil 后创建变量,这就是它总是返回 nil 的原因。类似地,当函数结束时,名字不再存在,因为它是在函数内部调用和创建的。所以它总是返回零。 代码的顶部应该如下所示

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)

关于function - 在 ComputerCraft 中使用 Lua 中的并行函数时的变量重置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15017770/

相关文章:

lua - 有关 Lua C API 函数参数的详细信息

lua - ld : warning: ignoring file liblua. a,为 macOS-x86_64 构建,但尝试链接为未知不支持的文件格式构建的文件(0x21 0x3C

java - 更改我的世界中的 "SuperFlat"世界生成器

python - Collat​​z 函数未正确退出

c - 函数未传递给 main

javascript - 使用 JavaScript 构建猜数游戏程序

lua - 将值存储在 lua 的 userdata 对象中

java - Bukkit/JavaPlugin - 设置现有制作配方的结果不起作用

java - 不知道为什么玩家能够从 bukkit GUI 中获取

php - 从 laravel 4 中的 Controller 调用自定义模型方法