2016-12-15 83 views
0

我正在爲一些遊戲製作一個模組,我正在使用一個基本的貼圖地圖,我想要將其擴展到更大的地圖。但是,當我只使用「最近鄰居」類型的縮放比例時,地圖將具有硬方形邊緣。我想阻止這一點。順利地擴大瓷磚地圖?

所以我有一個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 - - - - 

我不知道該怎麼稱呼這個,所以我的搜索沒有多大變動。

我該怎麼做這樣的事情?

請注意,有幾種不同類型的瓷磚,並且沒有中間瓷磚類型。

回答

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-type,即使它們不是整數,這樣就可以縮放網格。我不確定是否有更好的方法,但它有效,看起來不錯。最後,我還在權重中添加了一些隨機數,以使邊緣稍微平直一些,這在縮放非常高的情況下在Factorio中看起來更好。

+1

良好的工作得到一些工作。我想你可能有興趣[看看爲像素藝術開發的一些縮放算法](https://en.wikipedia.org/wiki/Pixel_art_scaling_algorithms),因爲應用程序看起來很相似。 – plast1k