SpinRoleDevelop
SpinRoleDevelop

Reputation: 55

Attempt to index a nil value, love2d, lua

I am learning about gui and statemachine with love2d. I made a simple app which have menu, run and ended state. However I got an problem in the ended state with the buttons. Here is the update and exit part of ended.lua:

function m:update(dt, _stateMachine)

    for i = 1, #self.buttons do
        
        self.buttons[i]:detect(dt) ------ Attempt to index a nil value

        if self.buttons[i].waitAnimEnded == true then
                
            if i == 1 then
                    
                _stateMachine:change(gstates.run)

            elseif i == 2 then

                _stateMachine:change(gstates.menu)

            end

        end

    end

function m:exit()

    if gstates.run.score > gstates.run.maxScore then
        
        gstates.run.maxScore = gstates.run.score

    end

    self.buttons = {}
end

However, I got no error with the run.lua, I wrote it with the same way as the ended.lua. run.lua:

function m:update(dt, _stateMachine)

    for i = 1, #self.buttons do
        
        self.buttons[i]:detect(dt)

        if self.buttons[i].waitAnimEnded == true then

            if i == 1 then
            
                self.score = self.score + 1

                self.buttons[i].waitAnimEnded = false

            elseif i == 2 then

                _stateMachine:change(gstates.ended)

            end

        end

    end
    
end

function m:exit()

    self.buttons = {}
    
end

And here is the stateMachine.lua

sm = {}

sm.currentState = gstates.menu

function sm:change(_newState)

    self.lastState = self.currentState

    self.currentState = _newState
        
    self.lastState:exit()

    self.currentState:enter()

end

function sm:update(dt)
    
    self.currentState:update(dt, self)

end

function sm:render()
    
    self.currentState:render()

end

return sm

After I did a little changed in ended.lua, the error fixed, but idk why would that happened.

function m:update(dt, _stateMachine)

    for i = 1, #self.buttons do

        if not(#self.buttons == 0) then ---- I changed here -----
        
            self.buttons[i]:detect(dt)

            if self.buttons[i].waitAnimEnded == true then
                
                if i == 1 then
                    
                    _stateMachine:change(gstates.run)

                elseif i == 2 then

                    _stateMachine:change(gstates.menu)

                end

            end
        end

    end
    
end

If you have an idea of this problem, please tell me. Thank you.

Upvotes: 0

Views: 225

Answers (1)

Luke100000
Luke100000

Reputation: 1539

Let's assume self.buttons contains two values.

for i = 1, #self.buttons do
    print(self.buttons[i])
    _stateMachine:change(gstates.ended)
end

This will print a button, and nil. And this nil causes the attempt to index a nil value. Why? Because in _stateMachine:change you call self.lastState:exit(), and in exit you remove all buttons via self.buttons = { } and then the second button no longer exists.

If you change the state, break the button loop.

Upvotes: 1

Related Questions