Search code examples
loopsfor-loopluarobloxlua-table

Loop running code 10 times when initiated with :connect


I have this wall with buttons where it emulates how an atm should work. Now when entering the numbers from 0-9 this works well and there are no problems but whenever the enter or back buttons are pressed the function inside the event is run 10 times. (This is just a snippet of the code that's relevant)

(in the folder there are 10 parts with clickDetector inside)

local atmScreen = workspace.ATM.SurfaceGui.Frame.Info
local input = {}
local enterPressed = false
local folder = workspace.ATM.NumberButtons
local insertCard = workspace.ATM.InsertCard.ClickDetector
local back = workspace.ATM.Back.ClickDetector
local reset = workspace.ATM.Reset.ClickDetector
local enter = workspace.ATM.Enter.ClickDetector

--Pin
local pin = "1234"

function keypad()
    for i, v in pairs(folder:GetChildren()) do
        v.ClickDetector.MouseClick:Connect(function()
            table.insert(input,i)
            keyPressed(input)
        end)
        enter.MouseClick:Connect(function()
            enterPressed = true
            local x = keyPressed(input)
            print(x)
            table.clear(input)
            enterPressed = false
            if x == pin then
                atmScreen.Text = ("Pin Correct!")
                wait(1)
            else
                atmScreen.Text = ("Pin Incorrect! Please reenter pin!")
            end
        end)
        reset.MouseClick:Connect(function()
            table.clear(input)
            keyPressed(input)
        end)
        back.MouseClick:Connect(function()
            local index = table.maxn(input)
            print(index)
            table.remove(input,index)
            keyPressed(input)
        end)
    end
end



function keyPressed(input)
    local output = ""
    for _,num in pairs(input) do
        output = output..num
    end
    atmScreen.Text = output
    if enterPressed == true then
        return(output)
    end
end

When the code is run, I put some print statements to test what is outputted when the different buttons are clicked.

I first clicked the 1 2 3 4 5 buttons and then the back button once. Secondly, I clicked 1 2 3 4 buttons that match the pin but the output: "Pin Incorrect Please Reenter Pin!" was outputted on screen gui.

  01:26:34.094  5  -  Server - ATM:139
  01:26:34.094  4  -  Server - ATM:139
  01:26:34.094  3  -  Server - ATM:139
  01:26:34.094  2  -  Server - ATM:139
  01:26:34.094  1  -  Server - ATM:139
  01:26:34.094   ▶ 0 (x5)  -  Server - ATM:139
  01:26:40.894  1234  -  Server - ATM:123
  01:26:40.894   ▶  (x9)  -  Server - ATM:123


Solution

  • According to your output, when you hit the back button at 01:26:34, it fired the event ten times. So it removed all input, as you can see when the input size was counting down to zero and then stayed at 0 for five more times.

    Then (per your description) you pushed 1,2,3,4,ENTER. The key strokes are not logged, but according to your output you hit enter at 01:26:40. Again that event fired ten times. The first time the log shows your string of "1234". The event handler clears that, and the following 9 times it logs the now empty buffer. I suspect in the first event call your screen did show "Pin Correct!", but that was immediately replaced then by "Pin Incorrect Please Reenter Pin!" then following 9 times.

    The reason why those events fire ten times is because you hooked up the handlers inside your loop, which runs once for each of your ten number keys.

    You should rather do this:

    function keypad()
        for i, v in pairs(folder:GetChildren()) do
            v.ClickDetector.MouseClick:Connect(function()
                table.insert(input,i)
                keyPressed(input)
            end)
        end
        enter.MouseClick:Connect(function()
            enterPressed = true
            local x = keyPressed(input)
            print(x)
            table.clear(input)
            enterPressed = false
            if x == pin then
                atmScreen.Text = ("Pin Correct!")
                wait(1)
            else
                atmScreen.Text = ("Pin Incorrect! Please reenter pin!")
            end
        end)
        reset.MouseClick:Connect(function()
            table.clear(input)
            keyPressed(input)
        end)
        back.MouseClick:Connect(function()
            local index = table.maxn(input)
            print(index)
            table.remove(input,index)
            keyPressed(input)
        end)
    end