문제

I am a beginner designing a Lua program in ComputerCraft (Minecraft) that asks the player for their name the first time they use it, and records it. For now, I want a program that detects if the variable firstnameis equal to nil and asks for the name if it is so. If the variable is not equal to nil, it says that you do not need to register. I currently have register()called only after pressing 5from the main menu.

The problem is that each time I assign a string to firstnameupon being prompted, firstnamereturns to nil when the main menu comes up. I even put print(firstname)at the end of the menu to test this.

I have assumed this is due to the parallel function that this all runs in. I run MainMenu() and Controls()in parallel so that I can listen for keyboard input and redstone input at the same time.

How can I keep both functions listening and the menu working, while preserving variables?

Here is the full code:

    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
도움이 되었습니까?

해결책

Initialize firstname outside of the parallel. Put local firstname up at the top of your code, and change local firstname = read() to just firstname = read(), and do the same for last name.

You are creating the variable after you check whether or not it is nil, which is why it always returns nil. Similarly, when the function ends, firstname no longer exists, since it is called and created inside of the function. So it will always return nil. The top of your code should look like so

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 = ""

And the other section should be as follows:

        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)

다른 팁

You should initialize firstname before you check if it is equal to 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

This allows for firstname to be accessed elsewhere and not just within that first if statement. You were checking if an uninitialized variable was equal to nil or not.

EDIT: Saw purxiz's answer and realized that you also probably want lastname to be outside of the loop. I fixed it in my code above now.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top