love2d教程-第七章:表和for循环

Dahuang published on
9 min, 1715 words

Categories: 游戏开发

Tags: LOVE2D

我们可以在表里储存一组变量。

我们用一对花括号({})来创建表。

function love.load()
    fruits = {}
end

这样,我们就创建了一个叫fruit的表。现在我们可以往里面储存值了。要往表里储存值,有许多方法。

其中一种办法是在创建表时,在花括号里加入值。

function love.load()
    -- 不同的值间用逗号分开
    fruits = {"apple", "banana"}
end

或者使用函数table.insert()。第一个参数是表的名字,第二个参数是你希望储存的值。

function love.load()
    --Each value is separated by a comma, just like with parameters and arguments
    fruits = {"apple", "banana"}
    table.insert(fruits, "pear")
end

现在,当love.load()结束后,我们的表里应该包括了"apple","banana"和"pear"。为了证明这一点,我们将他们打印到屏幕上。我们将使用函数love.graphics.print(text, x, y)。第一个参数text是你要打印的内容,后两个xy是你希望打印的位置。

function love.draw()
    --Arguments: (text, x-position, y-position)
    love.graphics.print("Test", 100, 100)
end

当你运行游戏,你应该看到"Test"出现在你的游戏窗口里。那么怎么打印表里的内容呢?要访问表中的内容,我们用表的名字加上一对方括号([]),在方括号里,我们加入要访问的值的位置。

就像我说的,表是一个值的列表。我们首先加入了"apple"和"banana",所以它们分别在表的第一和第二个位置上。接下来我们增加了"pear",所以它是第三个。第四个位置上还没有值,所以是nil

所以如果我们希望打印"apple",我们就要访问表中的第一个值。

function love.draw()
    love.graphics.print(fruits[1], 100, 100)
end

现在运行游戏,窗口中应该绘制了“apple”,如果你把[1]换成[2],那么就是"banana",[3]就是“pear”。

现在我们要打印所有表中的全部3个水果。你当然可以使用三次love.graphics.print…

function love.draw()
    love.graphics.print(fruits[1], 100, 100)
    love.graphics.print(fruits[2], 100, 200)
    love.graphics.print(fruits[3], 100, 300)
end

但是如果表里有100个值怎么办?用100次love.graphics.print?万幸的是,我们不必这么做——我们可以使用——


for循环

for循环是一种让一段代码重复运行多次的办法。

要创建一个for循环,你可以这么写:

function love.load()
    fruits = {"apple", "banana"}
    table.insert(fruits, "pear")

    for i=1,10 do
        print("hello", i)
    end
end

如果你运行游戏,控制台上就应该会输出:hello 1,hello 2,hello 3,直到hello 10。

要创建一个for循环,首先用保留字for开头。然后创建一个变量并且赋给它一个数值。这个变量可以用任何名字,但是通常我们用i。这个变量只能在for循环内部使用。然后用逗号,再跟上一个数值(我们设它为j)。每次循环结束,i的值都会+1,直到i的值达到j,循环结束。所以循环将会执行(j-i+1)次。

还有一个可选的第三个数字。for i=6,18,4 do意味着:从6开始,每次加4,直到18。你还可以这样:for i=114514,1,-1,意思是从114514开始,每次减1,直到1。

我们的表从1开始,里面一共有三个值,所以我们这样:

function love.load()
    fruits = {"apple", "banana"}
    table.insert(fruits, "pear")

    for i=1,3 do
        print(fruits[i])
    end
end

当你运行游戏,你将看到控制台输出了所有的3个水果。在第一个循环中,它打印fruits[1],然后在第二个循环中打印fruits[2],最后在第三个循环中打印fruits[3]


编辑表

如果我们又往表中添加或者移除了一个值,怎么办?我们当然可以把3改成对应的数字。但是有更好的办法,我们可以用#fruits#可以用来获取一个表的长度(也就是表中元素的数量)。

function love.load()
    fruits = {"apple", "banana"}

    print(#fruits)
    --Output: 2

    table.insert(fruits, "pear")

    print(#fruits)
    --Output: 3

    for i=1,#fruits do
        print(fruits[i])
    end
end

现在我们将试着在游戏的窗口上绘制这三种水果。

function love.draw()
    for i=1,#fruits do
        love.graphics.print(fruits[i], 100, 100)
    end
end

如果你运行游戏,你会发现确实绘制了3种水果,但是重叠在一起,我们可以这样修复这个问题:

function love.draw()
    for i=1,#fruits do
        love.graphics.print(fruits[i], 100, 100 + 50 * i)
    end
end

这样,"apple"将在y=100+50*1处绘制,"banana"在200,“pear”在250。

如果我们要添加其他水果,则无需进行任何更改。它将自动绘制。让我们添加“pineapple”。

function love.load()
    fruits = {"apple", "banana"}
    table.insert(fruits, "pear")
    table.insert(fruits, "pineapple")
    table.remove(fruits, 2)
end

我们也可以从表中移除值,通过table.remove。第一个参数是我们希望从中移除元素的表的名字,第二个参数是我们希望移除的元素的位置。所以如果我们希望移除banana,我们这么做:

function love.load()
    fruits = {"apple", "banana"}
    table.insert(fruits, "pear")
    table.insert(fruits, "pineapple")
    table.remove(fruits, 2)
end

现在当你运行游戏,banana不再会被绘制,并且pear和pinapple的位置会向前移动。

当你使用table.remove从表中移除元素时,所有在被移除元素之后的元素都会向前移动一个位置。所以原本在第3位的pear移动到了第2位。

你也可以改变已经存储在表中的值。举个例子,你可以把apple改成tomato。


ipairs

现在我们回到for循环。当你需要用循环遍历一个表时,有一个更简单的办法,那就是使用ipairs

function love.load()
    fruits = {"apple", "banana"}
    table.insert(fruits, "pear")
    table.insert(fruits, "pineapple")
    table.remove(fruits, 2)
    fruits[1] = "tomato"

    for i,v in ipairs(fruits) do
        print(i, v)
    end
    --Output:
    --1, "tomato"
    --2, "pear"
    --3, "pineapple"
end

上面的这个for循环,我们也叫它迭代器。我们用迭代器来遍历一个表。变量i告诉我们我们现在在表中的位置,v是在该位置处的值。你可以认为vfruits[i]的简便写法。举个例子,在第一次迭代中i的值为1,v的值为"apple",而在第二次迭代中,iv将分别是2和“pear”。

但是这究竟是这么工作的?ipairs函数的原理究竟是什么?不过那些都是另外一回事了。现在你只需要知道ipairs基本上是这样的:

for i=1, #fruits do
    v = fruits[i]
end

让我们用ipairs绘制表:

function love.draw()
    -- i and v are variables, so we can name them whatever we want
    for i,frt in ipairs(fruits) do
        love.graphics.print(frt, 100, 100 + 50 * i)
    end
end

总结

表是我们可以在其中存储值的列表。我们在创建表时使用table.inserttable_name[1]=“some_value”存储这些值。我们可以使用#table_name获取表的长度。使用for循环,我们可以多次重复一段代码。我们还可以使用for循环遍历表。