平滑地放大瓷砖地图?

时间:2016-12-15 23:14:58

标签: smoothing

我正在为一些游戏制作一个mod,而我正在使用一个基本的tile-map,我希望它可以扩展为更大的地图。但是,当我只使用“最近邻”类缩放时,地图将具有硬方边。我想阻止这一点。

所以我有一个tilemap,如下所示:

- - X -
- X X X
X X X X
X X - -

根据我目前的缩放比例,我得到了类似的内容:

- - - - X X - -
- - - - X X - -
- - X X X X X X 
- - X X X X X X
X X X X X X X X
X X X X X X X X
X X X X - - - -
X X X X - - - - 

你可以看到它有一些硬边。我希望他们更顺利:

- - - - X X - -
- - - X X X X -
- - X X X X X X 
- X X X X X X X
X X X X X X X X
X X X X X X X X
X X X X X X - -
X X X X - - - - 

我不知道该怎么称呼它,所以我的搜索没有太多。

我该怎么办?

请注意,有几种不同类型的切片,并且没有中间切片类型。

1 个答案:

答案 0 :(得分:0)

所以我自己玩了一下,发现了一些看起来效果很好的东西。

这就是我做的事(Lua):

--First get the cells you're between (x and y are real numbers, not ints)
local top = math.floor(y)
local bottom = (top + 1)
local left = math.floor(x)
local right = (left + 1)
--Then calculate weights. These are basically 1 - the distance. The distance is scaled to be between 0 and 1.
local sqrt2 = math.sqrt(2)
local w_top_left = 1 - math.sqrt((top - y)*(top - y) + (left - x)*(left - x)) / sqrt2
local w_top_right = 1 - math.sqrt((top - y)*(top - y) + (right - x)*(right - x)) / sqrt2
local w_bottom_left = 1 - math.sqrt((bottom - y)*(bottom - y) + (left - x)*(left - x)) / sqrt2
local w_bottom_right = 1 - math.sqrt((bottom - y)*(bottom - y) + (right - x)*(right - x)) / sqrt2
--Then square these weights, which makes it look better
w_top_left = w_top_left * w_top_left
w_top_right = w_top_right * w_top_right
w_bottom_left = w_bottom_left * w_bottom_left
w_bottom_right = w_bottom_right * w_bottom_right
--Now get the codes (or types) of the surrounding tiles
local c_top_left = decompressed_map_data[top % height][left % width]
local c_top_right = decompressed_map_data[top % height][right % width]
local c_bottom_left = decompressed_map_data[bottom % height][left % width]
local c_bottom_right = decompressed_map_data[bottom % height][right % width]
--Next calculate total weights for codes
-- So add together the weights of surrounding tiles if they have the same type
local totals = {}
add_to_total(totals, w_top_left, c_top_left) --see below for this helper func
add_to_total(totals, w_top_right, c_top_right)
add_to_total(totals, w_bottom_left, c_bottom_left)
add_to_total(totals, w_bottom_right, c_bottom_right)
--Lastly choose final code, which is the tile-type with the highest weight
local code = nil
local weight = 0
for _, total in pairs(totals) do
    if total.weight > weight then
        code = total.code
        weight = total.weight
    end
end
return terrain_codes[code]

-- Helper function
local function add_to_total(totals, weight, code)
    if totals[code] == nil then
        totals[code] = {code=code, weight=weight}
    else
        totals[code].weight = totals[code].weight + weight
    end
end

瞧。这为任何x / y值选择精确的tile类型,即使它们不是整数,因此可以扩展网格。我不确定是否有更好的方法,但它有效并且看起来很好。最后,我还在权重中添加了一些随机数,使边缘略微变直,当缩放非常高时,在Factorio中看起来更好。