Home > database >  Does a for loop iterate over an empty table in Lua and Love2d?
Does a for loop iterate over an empty table in Lua and Love2d?

Time:11-16

I'm not quite sure on what's happening with the code right now. It's all written in Lua in VScode so I've been using only Alt L to run it with the love extension, as I don't actually have a Lua compiler set up. When I run the code, the idea is it that I will click the screen and a bullet will travel in that direction, then after 0.5s it will disappear.

However, what's happening is that after I spawn a bullet, it will exist for a time (I think 0.5s but I'm not quite sure) and then remove itself. That's all what I want, but then the calculations I did to find the direction the bullet should travel in and apply it to it's x and y values continues to occur even though the bullet is removed from the table. I'm not sure on this terminology and I've only been using LOVE for a day or two, so I don't quite know what's going on.

Here's the code:

function love.load()
    window = {}
    window.x, window.y = love.graphics.getDimensions()

    player = {}
    player.speed = 5
    player.x = window.x/2
    player.y = window.y/2
    player.r = 15
    player.w = {15, 0.5} --speed, duration

    bullets = {} --x, y, direction, speed, duration
    direction = 0
end

function love.update(dt)
    for i=1, #bullets do
        bullets[i][1] = bullets[i][1]   bullets[i][4]*math.cos(bullets[i][3])
        bullets[i][2] = bullets[i][2]   bullets[i][4]*math.sin(bullets[i][3])
        bullets[i][5] = bullets[i][5] - dt
        if bullets[i][5] <= 0 then
            table.remove(bullets, i)
        end
    end
end

function love.draw()
    love.graphics.circle('fill', player.x, player.y, player.r)
    love.graphics.print(direction)
    love.graphics.print('('..love.mouse.getX()..','..love.mouse.getY()..')',0,50)
    love.graphics.print('('..player.x..','..player.y..')',0,100)
    for i=1, #bullets do
        love.graphics.circle('fill', bullets[i][1], bullets[i][2], 5)
    end
end

function love.mousepressed(x, y, button, istouch, presses)
    if button == 1 then
        direction = math.atan((y-player.y)/(x-player.x))
        if player.x > x then direction = direction   math.pi end
        direction = direction   math.random(-10, 10) * math.pi/180
        table.insert(bullets, {player.x, player.y, direction, player.w[1],player.w[2]})
    end
end

When I run it and do what I said before, this is the error I recieve:

Error

main.lua:18: attempt to index a nil value


Traceback

main.lua:18: in function 'update'
[C]: in function 'xpcall'

Line 18 is this: bullets[i][1] = bullets[i][1] bullets[i][4]*math.cos(bullets[i][3])

I have never really developed in Lua and this is my first time getting into game dev so I'm just experimenting, hence the probably very poorly written code. I appreciate any help, thanks!

CodePudding user response:

In a numeric for loop, the control expressions are only evaluated once, before the first iteration of the loop. By calling table.remove in the loop, you're shortening bullets after #bullets has already been evaluated, so it tries to read elements that don't exist anymore. (And you were also skipping over an element for each one you removed.) For a quick fix to both of those problems in this case, you can use for i=#bullets, 1, -1 do for your loop instead.

  • Related