问题描述
-- This is minecraft,but 2D,and in Lua.
-- **************************************
-- ID 0: Air
-- ID 1: Stone
-- ID 2 Logs
-- ID 3: Leaves
-- ID 4: Planks
-- ID 5: Crafting Table
-- ID 6: Furnance
-- ID 7: Player position detector block
-- **************************************
blockTable = { -- Stores all the blocks
{0,0},{0,7,{6,6,6}
}
tableRow = 1 -- Y value for block render pointer
tableColumn = 1 -- X value for block render pointer
runOnce = true -- Run a loop once
tickNum = 0 -- Number of ticks since startup
function renderBlock(X,Y,K) -- Render a block
if K == 1 then -- if blockID == 1,draw a grey square
screen.setColor(100,100,100)
print(X,Y)
screen.drawRectF(X,8,8)
end
if K == 6 then -- If the blockID == draw a grey square
screen.setColor(100,100)
screen.drawRectF(X,8)
end
end
function renderBlocks() -- Render all the blocks (Scans though the blockTable in a raster pattern)
while runOnce == true -- Run this code once
do
while #blockTable >= tableRow
do
while #blockTable[tableRow] >= tableColumn
do
print("TC " .. tableColumn)
tableColumn = tableColumn + 1
blockID = blockTable[tableRow][tableColumn]
renderBlock(tableRow,tableColumn,blockID)
if tableColumn > #blockTable[tableRow] then tableColumn = 1 end
end
runOnce = false
end
print("TR " .. tableRow)
tableRow = tableRow + 1
end
end
function onTick()
print("Tick! Tick count: " .. tickNum) -- Print the current tick,as well as say that there has been a tick
tickNum = tickNum + 1
end
function onDraw()
while runOnce == true -- Run this code once
do
renderBlocks()
runOnce = false
end
end
我不知道为什么会这样,我在这里不知所措。
解决方法
在对表进行循环时,使用 for 循环比使用 while 或 repeat 循环要好得多,后者更难理解和修正错误。
如果您想获取索引(表中的数字)和关联的值,请使用 for index,value in ipairs(yourtable) do
或如果您想获取键(通常用作值的键的字符串),请使用 for key,value in pairs(yourtable) do
: yourTable["key"] = 0
) 以及与之关联的值。
for row,innerTable in ipairs(blockTable) do
for col,value in ipairs(innerTable) do
print("TC " .. col)
blockID = value
renderBlock(row,col,blockID)
end
end
最后一个应该在你的 renderBlocks 函数中完成。但是:
while runOnce == true do
-- Doing something
runOnce = false
end
不是很好的东西。如果它只被调用一次,不要把它放入循环中!
此外,更好的代码识别有助于更快地了解正在发生的事情。并在处理不同问题的代码块之间添加一些空间。
编辑:因此您的函数可能如下所示:
function renderBlocks()
if runOnce then
runOnce = false
for row,innerTable in ipairs(blockTable) do
for col,value in ipairs(innerTable) do
blockID = value
renderBlock(row,blockID)
end
end
end
end
,
您的 renderBlocks()
函数中有几个问题
function renderBlocks()
while runOnce == true do
while #blockTable >= tableRow do
while #blockTable[tableRow] >= tableColumn do
print("TC " .. tableColumn)
tableColumn = tableColumn + 1
blockID = blockTable[tableRow][tableColumn]
renderBlock(tableRow,tableColumn,blockID)
if tableColumn > #blockTable[tableRow] then
tableColumn = 1
end
end
runOnce = false
end
print("TR " .. tableRow)
tableRow = tableRow + 1
end
end
首先我们可以看看最里面的循环。这里我们遇到了用于评估循环的悔恨以及它是如何递增的问题。
while #blockTable[tableRow] >= tableColumn do
print("TC " .. tableColumn)
tableColumn = tableColumn + 1 -- incremented here
blockID = blockTable[tableRow][tableColumn]
renderBlock(tableRow,blockID)
if tableColumn > #blockTable[tableRow] then
tableColumn = 1 -- reset here
end
end
在循环体中执行 tableColumn = tableColumn + 1
之后在同一个体中执行 if tableColumn > #blockTable[tableRow] then tableColumn = 1 end
所以当 tableColumn
增加到会结束我们重置的循环的值时,这是一个问题它 1
防止循环永远结束。
现在让我们看看下一个循环。这里我们从不增加 tableRow
它是在这个循环结束后增加的,所以循环不可能结束。
while #blockTable >= tableRow do
while #blockTable[tableRow] >= tableColumn do
...
end
runOnce = false
end
我相信你是故意的
print("TR " .. tableRow)
tableRow = tableRow + 1
发生在这个循环内而不是在它之外。
,您在这里遗漏了一些块定义。不要认为这就是将它发送到无限循环的原因,否则您可能看不到结果。
function renderBlock(X,Y,blockID) -- Render a block
if blockID == 0 then -- Air
-- screen.setColor(10,20,220,0) -- is there an alpha channel?
screen.setColor(10,220)
elseif blockID == 1 then -- Stone
screen.setColor(100,100,100)
elseif blockID == 2 then -- Logs
screen.setColor(200,50,50)
elseif blockID == 3 then -- Leaves
screen.setColor(20,40)
elseif blockID == 4 then -- Planks
screen.setColor(180,30,10)
elseif blockID == 5 then -- Craft Table
screen.setColor(180,10)
elseif blockID == 6 then -- Furnace
screen.setColor(100,100)
elseif blockID == 7 then -- Player detect
screen.setColor(220,30)
end
print(X,Y)
screen.drawRectF(X,8,8)
end
使用 for
循环很容易。设置初始条件,然后设置最终完成条件,让它运行课程。
function renderBlocks() -- Render all blocks (Scans though blockTable in a raster pattern)
for row = 1,#blockTable do
for col = 1,#blockTable[row] do
print("TC " ..col)
local blockID = blockTable[row][col]
renderBlock(row,blockID)
end
print("TR " ..row)
end
end
您可能不需要那个runOnce
。如果你发现你做了别的事情,继续,但嵌套 for 循环不应该需要它。
function onDraw()
renderBlocks()
end