lua中多个列表的排序

如何按照地图块和人物的y坐标对两个列表进行排序并以正确的顺序绘制它们。我想使用两个列表:

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

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

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

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)

我的函数通过比较y位置列表对id列表进行排序。 id用于按其y位置的先后顺序绘制对象。如何对比两个y位置列表对两个id列表进行排序,然后按顺序绘制它们?

可能在绘制时,根据y,从地图瓷砖切换到人物,但我不知道如何操作。

点赞
用户5352026
用户5352026

可能与你之前的问题很相关:在 Lua 中返回已排序列表的索引

我假设如果你的高度可以是 1、2 和 3(1 为顶部),你首先想要渲染所有 Y1 的图块,然后所有 Y1 的人,接着是 Y2 和 Y3。为了达到这个目的,你需要制作一个合并列表并对其进行排序:

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

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

local all = {}
local map_y = map.y
local offset = #map_y
local people_y = people.y
-- 用地图图块填充列表
for i=1,offset do
    all[i] = {1,i,map_y[i]} --{类型,索引,y}
end
-- 用人物填充列表
for i=1,#people_y do
    all[i+offset] = {2,i,people_y[i]}
end
-- 进行排序
-- 它的工作方式与你之前的问题有点相似:
-- "all" 包含 "引用":
--    它告诉我们它是来自地图/人物的+索引
-- 我们使用其中第三个元素对这些引用进行排序:
--    我们在前两个循环中放置了 "y" 变量
table.sort(all,function(a,b)
    return a[3] < b[3]
end)
-- 打印示例
-- 引用已按对象的“y”字段排序
--    利用 v[1] 我们知道它是来自地图/人物
--    v[2] 告诉我们那个 ^ 表中的索引
--    v[3] 是 "y" 字段。没有真正需要删除它
for k,v in pairs(all) do
    print(v[1] == 1 and "地图" or "人物",v[2],"其 y 为",v[3])
end

输出:

人物 1 其 y 为 0
地图 2 其 y 为 10
地图 3 其 y 为 40
地图 1 其 y 为 60
地图 4 其 y 为 80
人物 2 其 y 为 100

有两件事我想补充说明,它们与我的答案无关:

  • 如果对每个元素都有一个表可能会更容易处理。 你的人物应该是 {0, 0} 和 {100, 1},这可能更容易操作。
  • 如果你喜欢你的东西始终按顺序排列,你可能需要使用这个:Sorted List。如果你保持一个已排序的对象列表,你不需要每次添加/删除一个元素时重新排序列表,甚至更糟糕的情况是每次渲染时重新排序列表。_(根据人物是否移动)如果你打算有很多地图/人物对象,这可能有助于提高性能。(Sorted List 对于当前的数据系统可能有用,也可能对 {y=1,t=1} 有用)_
2016-02-14 11:51:16
用户1847592
用户1847592
```lua
function sortIndex(...)
  sorted = {}  -- 全局变量
  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
      -- 使用 love.graphics.draw() 绘制地图块
    elseif array == people then
      -- 使用 love.graphics.draw() 绘制人物
    end
  end
end

sortIndex(map, people)  -- 为了在同一y轴上绘制地图块和人物,先绘制地图块

```

2016-02-14 12:21:35