for 循环是不是遍历 Lua 和 Love2d 中的空表?

Posted

技术标签:

【中文标题】for 循环是不是遍历 Lua 和 Love2d 中的空表?【英文标题】:Does a for loop iterate over an empty table in Lua and Love2d?for 循环是否遍历 Lua 和 Love2d 中的空表? 【发布时间】:2021-12-27 03:22:06 【问题描述】:

我不太确定代码现在发生了什么。这一切都是在 VScode 中用 Lua 编写的,所以我一直只使用 Alt+L 和 love 扩展来运行它,因为我实际上并没有设置 Lua 编译器。当我运行代码时,我的想法是我将单击屏幕,子弹会朝那个方向移动,然后在 0.5 秒后它会消失。

但是,发生的情况是,在我生成子弹后,它会存在一段时间(我认为是 0.5 秒,但我不太确定),然后自行移除。这就是我想要的,但随后我为找到子弹应该行进的方向并将其应用于它的 x 和 y 值所做的计算继续发生,即使子弹已从表中移除。我不确定这个术语,而且我只使用 LOVE 一两天,所以我不太清楚发生了什么。

代码如下:

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

当我运行它并按照我之前所说的做时,这是我收到的错误:

Error

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


Traceback

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

第 18 行是这样的:bullets[i][1] = bullets[i][1] + bullets[i][4]*math.cos(bullets[i][3])

我从来没有真正在 Lua 中进行过开发,这是我第一次进入游戏开发领域,所以我只是在试验,因此可能写得很糟糕的代码。感谢您的帮助,谢谢!

【问题讨论】:

lua.org/manual/5.1/manual.html#pdf-table.remove 和 lua.org/manual/5.1/manual.html#2.4.5 仔细阅读此内容,确保您了解问题所在。打印索引、值和表格内容有助于调试这样的事情。 “我索引了一个 nil 值!它是什么值?我期望什么值,为什么它是 nil 呢?” 【参考方案1】:

在数字for 循环中,控制表达式仅在循环的第一次迭代之前计算一次。通过在循环中调用table.remove,您在#bullets 已经被评估之后缩短了bullets,因此它会尝试读取不再存在的元素。 (而且您还为每个删除的元素跳过了一个元素。)在这种情况下,为了快速解决这两个问题,您可以使用 for i=#bullets, 1, -1 do 代替您的循环。

【讨论】:

谢谢,现在这更有意义了。 1, -1 在 for 循环中指的是什么? @progress456 分别是结束值和步长值。

以上是关于for 循环是不是遍历 Lua 和 Love2d 中的空表?的主要内容,如果未能解决你的问题,请参考以下文章

使用lua语言制作贪吃蛇游戏(love2d)蛇对象的设计

Lua中,泛型for循环遍历table时,ipairs和pairs的区别

Love2D(Lua)中的面向对象编程

love2d(lua)中的碰撞检测

Lua,Love2d,不同文件夹下两个类名相同的游戏

LOVE2D-03-完整的LOVE2D程序