2

私は ComputerCraft (Minecraft) で Lua プログラムを設計する初心者です。これは、プレイヤーが初めて使用するときに名前を尋ね、それを記録します。今のところ、変数firstnameが nil に等しいかどうかを検出し、そうであれば名前を尋ねるプログラムが必要です。変数が nil に等しくない場合は、登録する必要はありません。現在、メイン メニューからregister()を押した後にのみ電話をかけています。5

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
4

2 に答える 2

2

並列の外側で firstname を初期化します。コードlocal firstnameの先頭に配置し、 local firstname = read()justfirstname = read()に変更し、姓についても同じことを行います。

変数が nil かどうかを確認した後で変数を作成しているため、常に nil が返されます。同様に、関数が終了すると、firstname は関数内で呼び出されて作成されるため、存在しなくなります。したがって、常に 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)
于 2013-02-22T05:59:27.543 に答える
2

nil に等しいかどうかを確認する前に、firstname を初期化する必要があります。

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 ステートメント内だけでなく、他の場所で firstname にアクセスできます。初期化されていない変数が nil に等しいかどうかをチェックしていました。

編集:purxizの答えを見て、おそらくlastnameもループの外に置きたいと思っていることに気づきました。上記のコードで修正しました。

于 2013-02-22T06:00:38.913 に答える