从循环索引创建的值不正确
value created from loop index incorrect
我可能忽略了一些简单的事情。
我正在遍历一个二维数组,为数组中每个对象中的变量赋值。但是,当 'j' 递增时,分配给 gameArray[1][1].x 的值从 100 变为 400,而在初始分配后不应更改。
--create tilemap 5x5 array
for i = 1, gridSize.x, 1 do
gameArray[i] = {}
for j = 1, gridSize.y, 1 do
gameArray[i][j] = tileArray[math.random(numTiles)]
gameArray[i][j].x = (i * 100)
gameArray[i][j].y = (j * 100)
debug.debug()
end
end
tileArray[x] 是一个包含 4 个整数和从 PNG 加载的 love2D 图像的对象。
--tUD
tileArray[1].u = 1
tileArray[1].r = 0
tileArray[1].d = 1
tileArray[1].l = 0
tileArray[1].img = love.graphics.newImage('tiles/tUD.png')
下面是测试时调试控制台的副本:
lua_debug> print(gameArray[1][1].y)
100
lua_debug> cont
lua_debug> print(gameArray[1][1].y)
100
lua_debug> cont
lua_debug> print(gameArray[1][1].y)
100
lua_debug> cont
lua_debug> print(gameArray[1][1].y)
400
lua_debug>
知道是什么原因造成的吗?
您的内部循环正在覆盖 gameArray[i][j].y
中先前存储的值。这是因为这一行:
gameArray[i][j] = tileArray[math.random(numTiles)]
这里,一个随机数,大概是从 1 到 25,用于 select 一个方块。但是,同一个图块很可能会被 select 编辑多次,导致写入 gameArray[i][1].y
的第一个值在 j
较大时被覆盖。我不知道你在这里想要什么功能,但一个解决方案是建立一个索引数组,并在 select 一个图块时随机 select 一个索引,从列表中删除索引所以不能再 selected 了。
这是一个如何实现的例子。我包含了一些虚拟初始化,以便代码运行并显示结果:
-- Dummy initializations
tileArray = {}
for i = 1, 25 do
tileArray[i] = {}
end
gameArray = {}
gridSize = {}
-- Initialize gridSize
gridSize.x = 5
gridSize.y = 5
-- List of available tile indices
indices = {}
for i = 1, 25 do
indices[i] = i
end
-- Create tilemap 5x5 array
for i = 1, gridSize.x do
gameArray[i] = {}
for j = 1, gridSize.y do
k = math.random(#indices)
index = indices[k]
table.remove(indices, k)
gameArray[i][j] = tileArray[index]
gameArray[i][j].x = (i * 100)
gameArray[i][j].y = (j * 100)
end
end
-- Display results
for i = 1, gridSize.x do
for j = 1, gridSize.y do
fmt = string.format("[%d][%d].x = %d, [%d][%d].y = %d\n",
i, j, gameArray[i][j].x, i, j, gameArray[i][j].y)
io.write(fmt)
end
end
程序输出:
[1][1].x = 100, [1][1].y = 100
[1][2].x = 100, [1][2].y = 200
[1][3].x = 100, [1][3].y = 300
[1][4].x = 100, [1][4].y = 400
[1][5].x = 100, [1][5].y = 500
[2][1].x = 200, [2][1].y = 100
[2][2].x = 200, [2][2].y = 200
[2][3].x = 200, [2][3].y = 300
[2][4].x = 200, [2][4].y = 400
[2][5].x = 200, [2][5].y = 500
[3][1].x = 300, [3][1].y = 100
[3][2].x = 300, [3][2].y = 200
[3][3].x = 300, [3][3].y = 300
[3][4].x = 300, [3][4].y = 400
[3][5].x = 300, [3][5].y = 500
[4][1].x = 400, [4][1].y = 100
[4][2].x = 400, [4][2].y = 200
[4][3].x = 400, [4][3].y = 300
[4][4].x = 400, [4][4].y = 400
[4][5].x = 400, [4][5].y = 500
[5][1].x = 500, [5][1].y = 100
[5][2].x = 500, [5][2].y = 200
[5][3].x = 500, [5][3].y = 300
[5][4].x = 500, [5][4].y = 400
[5][5].x = 500, [5][5].y = 500
更新
鉴于有关 OP 代码目标的更多信息,很明显您需要能够多次使用 tileArray
中的图块。问题在于,通过将 tileArray
中的一个元素分配给 gameArray[i][j]
,然后修改 gameArray[i][j]
,您还修改了原始 tile 元素。
解决方案是将 tile 元素的 copy 分配给 gameArray[i][j]
。 Lua 没有复制 table 的功能,但您可以 look at this link 阅读有关复制 table 的方法。对于只需要浅拷贝的简单 table,链接的页面提供了一个名为 shallowcopy()
的函数。这是使用 shallowcopy()
:
对上述代码的修改
function shallowcopy(orig)
local orig_type = type(orig)
local copy
if orig_type == 'table' then
copy = {}
for orig_key, orig_value in pairs(orig) do
copy[orig_key] = orig_value
end
else -- number, string, boolean, etc
copy = orig
end
return copy
end
-- Dummy initializations
numTiles = 5
tileArray = {}
for i = 1, numTiles do
tileArray[i] = {}
tileArray[i].tile_type = i
end
gameArray = {}
gridSize = {}
-- Initialize gridSize
gridSize.x = 5
gridSize.y = 5
-- Create tilemap 5x5 array
for i = 1, gridSize.x do
gameArray[i] = {}
for j = 1, gridSize.y do
gameArray[i][j] = shallowcopy(tileArray[math.random(numTiles)])
gameArray[i][j].x = (i * 100)
gameArray[i][j].y = (j * 100)
end
end
-- Display results
for i = 1, gridSize.x do
for j = 1, gridSize.y do
fmt = string.format("[%d][%d].x = %d, [%d][%d].y = %d : type %d\n",
i, j, gameArray[i][j].x, i, j, gameArray[i][j].y,
gameArray[i][j].tile_type)
io.write(fmt)
end
end
程序输出:
[1][1].x = 100, [1][1].y = 100 : type 1
[1][2].x = 100, [1][2].y = 200 : type 1
[1][3].x = 100, [1][3].y = 300 : type 5
[1][4].x = 100, [1][4].y = 400 : type 2
[1][5].x = 100, [1][5].y = 500 : type 3
[2][1].x = 200, [2][1].y = 100 : type 5
[2][2].x = 200, [2][2].y = 200 : type 4
[2][3].x = 200, [2][3].y = 300 : type 2
[2][4].x = 200, [2][4].y = 400 : type 4
[2][5].x = 200, [2][5].y = 500 : type 3
[3][1].x = 300, [3][1].y = 100 : type 3
[3][2].x = 300, [3][2].y = 200 : type 5
[3][3].x = 300, [3][3].y = 300 : type 2
[3][4].x = 300, [3][4].y = 400 : type 4
[3][5].x = 300, [3][5].y = 500 : type 3
[4][1].x = 400, [4][1].y = 100 : type 4
[4][2].x = 400, [4][2].y = 200 : type 3
[4][3].x = 400, [4][3].y = 300 : type 5
[4][4].x = 400, [4][4].y = 400 : type 2
[4][5].x = 400, [4][5].y = 500 : type 2
[5][1].x = 500, [5][1].y = 100 : type 5
[5][2].x = 500, [5][2].y = 200 : type 5
[5][3].x = 500, [5][3].y = 300 : type 1
[5][4].x = 500, [5][4].y = 400 : type 5
[5][5].x = 500, [5][5].y = 500 : type 3
虽然 David Bowling 编写的上述答案有效并且是漂亮的代码,但它并没有解决原来的问题,因为作为修复的一部分,瓷砖的重复被阻止了。
原来的问题已通过 table 的浅拷贝功能解决。这是从以下网站借来的:
http://lua-users.org/wiki/CopyTable
换行
gameArray[i][j] = tileArray[math.random(numTiles)]
至
gameArray[i][j] = shallowcopy(tileArray[math.random(numTiles)])
添加这个是对任何有类似问题的人的第二个答案
我可能忽略了一些简单的事情。
我正在遍历一个二维数组,为数组中每个对象中的变量赋值。但是,当 'j' 递增时,分配给 gameArray[1][1].x 的值从 100 变为 400,而在初始分配后不应更改。
--create tilemap 5x5 array
for i = 1, gridSize.x, 1 do
gameArray[i] = {}
for j = 1, gridSize.y, 1 do
gameArray[i][j] = tileArray[math.random(numTiles)]
gameArray[i][j].x = (i * 100)
gameArray[i][j].y = (j * 100)
debug.debug()
end
end
tileArray[x] 是一个包含 4 个整数和从 PNG 加载的 love2D 图像的对象。
--tUD
tileArray[1].u = 1
tileArray[1].r = 0
tileArray[1].d = 1
tileArray[1].l = 0
tileArray[1].img = love.graphics.newImage('tiles/tUD.png')
下面是测试时调试控制台的副本:
lua_debug> print(gameArray[1][1].y)
100
lua_debug> cont
lua_debug> print(gameArray[1][1].y)
100
lua_debug> cont
lua_debug> print(gameArray[1][1].y)
100
lua_debug> cont
lua_debug> print(gameArray[1][1].y)
400
lua_debug>
知道是什么原因造成的吗?
您的内部循环正在覆盖 gameArray[i][j].y
中先前存储的值。这是因为这一行:
gameArray[i][j] = tileArray[math.random(numTiles)]
这里,一个随机数,大概是从 1 到 25,用于 select 一个方块。但是,同一个图块很可能会被 select 编辑多次,导致写入 gameArray[i][1].y
的第一个值在 j
较大时被覆盖。我不知道你在这里想要什么功能,但一个解决方案是建立一个索引数组,并在 select 一个图块时随机 select 一个索引,从列表中删除索引所以不能再 selected 了。
这是一个如何实现的例子。我包含了一些虚拟初始化,以便代码运行并显示结果:
-- Dummy initializations
tileArray = {}
for i = 1, 25 do
tileArray[i] = {}
end
gameArray = {}
gridSize = {}
-- Initialize gridSize
gridSize.x = 5
gridSize.y = 5
-- List of available tile indices
indices = {}
for i = 1, 25 do
indices[i] = i
end
-- Create tilemap 5x5 array
for i = 1, gridSize.x do
gameArray[i] = {}
for j = 1, gridSize.y do
k = math.random(#indices)
index = indices[k]
table.remove(indices, k)
gameArray[i][j] = tileArray[index]
gameArray[i][j].x = (i * 100)
gameArray[i][j].y = (j * 100)
end
end
-- Display results
for i = 1, gridSize.x do
for j = 1, gridSize.y do
fmt = string.format("[%d][%d].x = %d, [%d][%d].y = %d\n",
i, j, gameArray[i][j].x, i, j, gameArray[i][j].y)
io.write(fmt)
end
end
程序输出:
[1][1].x = 100, [1][1].y = 100
[1][2].x = 100, [1][2].y = 200
[1][3].x = 100, [1][3].y = 300
[1][4].x = 100, [1][4].y = 400
[1][5].x = 100, [1][5].y = 500
[2][1].x = 200, [2][1].y = 100
[2][2].x = 200, [2][2].y = 200
[2][3].x = 200, [2][3].y = 300
[2][4].x = 200, [2][4].y = 400
[2][5].x = 200, [2][5].y = 500
[3][1].x = 300, [3][1].y = 100
[3][2].x = 300, [3][2].y = 200
[3][3].x = 300, [3][3].y = 300
[3][4].x = 300, [3][4].y = 400
[3][5].x = 300, [3][5].y = 500
[4][1].x = 400, [4][1].y = 100
[4][2].x = 400, [4][2].y = 200
[4][3].x = 400, [4][3].y = 300
[4][4].x = 400, [4][4].y = 400
[4][5].x = 400, [4][5].y = 500
[5][1].x = 500, [5][1].y = 100
[5][2].x = 500, [5][2].y = 200
[5][3].x = 500, [5][3].y = 300
[5][4].x = 500, [5][4].y = 400
[5][5].x = 500, [5][5].y = 500
更新
鉴于有关 OP 代码目标的更多信息,很明显您需要能够多次使用 tileArray
中的图块。问题在于,通过将 tileArray
中的一个元素分配给 gameArray[i][j]
,然后修改 gameArray[i][j]
,您还修改了原始 tile 元素。
解决方案是将 tile 元素的 copy 分配给 gameArray[i][j]
。 Lua 没有复制 table 的功能,但您可以 look at this link 阅读有关复制 table 的方法。对于只需要浅拷贝的简单 table,链接的页面提供了一个名为 shallowcopy()
的函数。这是使用 shallowcopy()
:
function shallowcopy(orig)
local orig_type = type(orig)
local copy
if orig_type == 'table' then
copy = {}
for orig_key, orig_value in pairs(orig) do
copy[orig_key] = orig_value
end
else -- number, string, boolean, etc
copy = orig
end
return copy
end
-- Dummy initializations
numTiles = 5
tileArray = {}
for i = 1, numTiles do
tileArray[i] = {}
tileArray[i].tile_type = i
end
gameArray = {}
gridSize = {}
-- Initialize gridSize
gridSize.x = 5
gridSize.y = 5
-- Create tilemap 5x5 array
for i = 1, gridSize.x do
gameArray[i] = {}
for j = 1, gridSize.y do
gameArray[i][j] = shallowcopy(tileArray[math.random(numTiles)])
gameArray[i][j].x = (i * 100)
gameArray[i][j].y = (j * 100)
end
end
-- Display results
for i = 1, gridSize.x do
for j = 1, gridSize.y do
fmt = string.format("[%d][%d].x = %d, [%d][%d].y = %d : type %d\n",
i, j, gameArray[i][j].x, i, j, gameArray[i][j].y,
gameArray[i][j].tile_type)
io.write(fmt)
end
end
程序输出:
[1][1].x = 100, [1][1].y = 100 : type 1
[1][2].x = 100, [1][2].y = 200 : type 1
[1][3].x = 100, [1][3].y = 300 : type 5
[1][4].x = 100, [1][4].y = 400 : type 2
[1][5].x = 100, [1][5].y = 500 : type 3
[2][1].x = 200, [2][1].y = 100 : type 5
[2][2].x = 200, [2][2].y = 200 : type 4
[2][3].x = 200, [2][3].y = 300 : type 2
[2][4].x = 200, [2][4].y = 400 : type 4
[2][5].x = 200, [2][5].y = 500 : type 3
[3][1].x = 300, [3][1].y = 100 : type 3
[3][2].x = 300, [3][2].y = 200 : type 5
[3][3].x = 300, [3][3].y = 300 : type 2
[3][4].x = 300, [3][4].y = 400 : type 4
[3][5].x = 300, [3][5].y = 500 : type 3
[4][1].x = 400, [4][1].y = 100 : type 4
[4][2].x = 400, [4][2].y = 200 : type 3
[4][3].x = 400, [4][3].y = 300 : type 5
[4][4].x = 400, [4][4].y = 400 : type 2
[4][5].x = 400, [4][5].y = 500 : type 2
[5][1].x = 500, [5][1].y = 100 : type 5
[5][2].x = 500, [5][2].y = 200 : type 5
[5][3].x = 500, [5][3].y = 300 : type 1
[5][4].x = 500, [5][4].y = 400 : type 5
[5][5].x = 500, [5][5].y = 500 : type 3
虽然 David Bowling 编写的上述答案有效并且是漂亮的代码,但它并没有解决原来的问题,因为作为修复的一部分,瓷砖的重复被阻止了。
原来的问题已通过 table 的浅拷贝功能解决。这是从以下网站借来的: http://lua-users.org/wiki/CopyTable
换行
gameArray[i][j] = tileArray[math.random(numTiles)]
至
gameArray[i][j] = shallowcopy(tileArray[math.random(numTiles)])
添加这个是对任何有类似问题的人的第二个答案