排序多个列表lua

时间:2016-02-14 11:18:20

标签: sorting lua draw

如何对2个列表OrderBy位置(地图图块和人物)进行排序,并按照y的顺序绘制它们。我想要使​​用的2个列表:

y

我目前可以对单个英雄和盒子列表进行排序和绘制。 排序/绘制代码:

map = {}
map.y = {60,10,40,80}
map.t = {0,0,1,1} -- type

people = {}
people.y = {0,100}
people.t = {0,1} -- type

更新排序:

box1 = love.graphics.newImage("box1.png")
box2 = love.graphics.newImage("box2.png")
box3 = love.graphics.newImage("box3.png")
hero = love.graphics.newImage("hero.png")

object = {
    x = {0, 50,100,200},
    y = {0,200, 50,100},
    g = {0,1,2,3}
}
function sortIndex(item)
    local i
    local id = {}       -- id list
    for i = 1, #item.x do   -- Fill id list (1 to length)
        id[i] = i
    end
--  print( unpack(id) ) -- Check before
    table.sort(id,sortY)-- Sort list
--  print( unpack(id) ) -- Check after
    item.sort = id      -- List added to object.sort
--  Sort id, using item values
    function sortY(a,b)
        return item.y[a] < item.y[b]
    end
end
function drawObject()
    local i,v, g,x,y
    for i = 1, #object.x do
        v = object.sort[i] -- Draw in order
        x = object.x[v]
        y = object.y[v]
        g = object.g[v]
        if      g == 0 then g = hero -- set to an image value
        elseif  g == 1 then g = box1
        elseif  g == 2 then g = box2
        elseif  g == 3 then g = box3
        end
        love.graphics.draw(g,x,y,0,7,7)
    end
end

我的功能会对比较sortIndex(object) 位置列表的id列表进行排序。 y用于按顺序绘制对象id。如何对2个y列表进行排序,比较2个id位置列表,然后按顺序绘制它们?

也许在绘图时,从地图图块切换到依赖y的人,但我不知道如何。

2 个答案:

答案 0 :(得分:1)

可能与您之前的问题有很多关联:Returning A Sorted List's Index in Lua

我假设如果你的身高可以是1,2和3(1位于顶部),你首先想要在Y1渲染所有的牌,然后是Y1的所有牌,然后是Y2和Y3。要做到这一点,你必须制作一个组合列表并对其进行排序:

map = {}
map.y = {60,10,40,80}
map.t = {0,0,1,1} -- type

people = {}
people.y = {0,100}
people.t = {0,1} -- type

local all = {}
local map_y = map.y
local offset = #map_y
local people_y = people.y
-- Fill the list with map tiles
for i=1,offset do
    all[i] = {1,i,map_y[i]} --{type,index,y}
end
-- Fill the list with people
for i=1,#people_y do
    all[i+offset] = {2,i,people_y[i]}
end
-- Do the sorting
-- It works a bit like your previous question:
-- 'all' contains "references":
--    They tell us is it's from map/people + the index
-- We sort the references using the third element in it:
--    The 'y' variable we put there during the first 2 loops
table.sort(all,function(a,b)
    return a[3] < b[3]
end)
-- Printing example
-- The references are sorted using the 'y' field of your objects
--    With v[1] we know if it's from map/people
--    The v[2] tells us the index in that ^ table
--    The v[3] is the 'y'-field. No real need to remove it
for k,v in pairs(all) do
    print(v[1] == 1 and "Map" or "Person",v[2],"with y being",v[3])
end

输出:

Person 1 with y being 0
Map 2    with y being 10
Map 3    with y being 40
Map 1    with y being 60
Map 4    with y being 80
Person 2 with y being 100

我想添加两件事,这与我的答案问题无关:

  • 如果每个元素都有一个表格,也许会更容易。 你的人将是{0,0}和{100,1},这可能更容易操纵。
  • 如果您希望对所有内容进行排序,则可能需要使用:Sorted List。如果保留所有对象的排序列表,则不必在每次添加/删除元素时对列表进行排序,或者每次渲染时更糟。 (取决于人们是否移动)如果您计划拥有大量地图/人物对象,这可能对性能有所帮助。 (排序列表可能对您当前的数据系统很有用,但也适用于{y=1,t=1}

答案 1 :(得分:1)

function sortIndex(...)
  sorted = {}  -- global
  local arrays_order = {}
  for arr_index, array in ipairs{...} do
    arrays_order[array] = arr_index
    for index = 1, #array.y do
      table.insert(sorted, {array = array, index = index})
    end
  end
  table.sort(sorted,
    function (a,b)
      local arr1, arr2 = a.array, b.array
      local ind1, ind2 = a.index, b.index
      return arr1.y[ind1] < arr2.y[ind2] or
        arr1.y[ind1] == arr2.y[ind2] and arrays_order[arr1] < arrays_order[arr2]
    end)
end

function drawAll()
  for _, elem_info in ipairs(sorted) do
    local array = elem_info.array
    local index = elem_info.index
    local x = array.x[index]
    local y = array.y[index]
    if array == map then
      -- draw a map tile with love.graphics.draw()
    elseif array == people then
      -- draw a human with love.graphics.draw()
    end
  end
end

sortIndex(map, people)  -- to draw map tiles before people for the same y