Saya tiba di sini dengan Googling masalah ini sendiri, membaca artikel yang ditautkan, dan menghasilkan solusi yang relatif ringkas yang menghasilkan 47 ubin. Ini membutuhkan 2x3 tileset untuk bahan autotiled seperti ini:
Dengan varian ubin tunggal di kiri atas, sudut dalam di kanan atas, dan empat ubin sudut luar di bagian bawah (Anda dapat mengenali pengaturan ini dari RPG Maker).
Caranya adalah memecah setiap ubin peta "logis" menjadi 4 ubin setengah untuk dirender. lebih jauh lagi, setengah ubin di ubin hanya dapat berada di posisi itu di ubin yang dihasilkan, sehingga ubin setengah kiri atas hanya dapat digunakan di posisi kiri atas.
Pembatasan ini berarti bahwa Anda hanya perlu memeriksa 3 tetangga ubin penuh per ubin setengah, bukan semua 8 ubin tetangga.
Saya mengimplementasikan ide ini dengan cepat untuk mengujinya. Berikut kode proof-of-concept (TypeScript):
//const dirs = { N: 1, E: 2, S: 4, W:8, NE: 16, SE: 32, SW: 64, NW: 128 };
const edges = { A: 1+8+128, B: 1+2+16, C: 4+8+64, D: 4+2+32 };
const mapA = { 0:8, 128:8, 1:16, 8:10, 9:2, 137:18, 136:10, 129:16 };
const mapB = { 0:11, 16:11, 1:19, 2:9, 3:3, 19:17, 18:9, 17:19 };
const mapC = { 0:20, 64:20, 4:12, 8:22, 12:6, 76:14, 72:22, 68:12 };
const mapD = { 0:23, 32:23, 4:15, 2:21, 6:7, 38:13, 34:21, 36:15 };
export function GenerateAutotileMap(_map: number[][], _tile: integer): number[][]
{
var result = [];
for (var y=0; y < _map.length; y++) {
const row = _map[y];
const Y = y*2;
// half-tiles
result[Y] = [];
result[Y+1] = [];
// each row
for (var x=0; x < row.length; x++) {
// get the tile
const t = row[x];
const X = x*2;
if (t != _tile) continue;
// Check nearby tile materials.
const neighbors = (North(_map, x, y) == t? 1:0)
+ (East(_map, x, y) == t? 2:0)
+ (South(_map, x, y) == t? 4:0)
+ (West(_map, x, y) == t? 8:0)
+ (NorthEast(_map, x, y) == t? 16:0)
+ (SouthEast(_map, x, y) == t? 32:0)
+ (SouthWest(_map, x, y) == t? 64:0)
+ (NorthWest(_map, x, y) == t? 128:0);
// Isolated tile
if (neighbors == 0) {
result[Y][X] = 0;
result[Y][X+1] = 1;
result[Y+1][X] = 4;
result[Y+1][X+1] = 5;
continue;
}
// Find half-tiles.
result[Y][X] = mapA[neighbors & edges.A];
result[Y][X+1] = mapB[neighbors & edges.B];
result[Y+1][X] = mapC[neighbors & edges.C];
result[Y+1][X+1] = mapD[neighbors & edges.D];
}
}
return result;
}
Penjelasan:
A
adalah bagian kiri atas ubin, B
adalah kanan atas, C
adalah kiri bawah, D
adalah kanan bawah.
edges
memegang bitmasks untuk masing-masing, sehingga kami hanya dapat mengambil info tetangga yang relevan.
map*
adalah kamus yang memetakan negara tetangga ke indeks grafik pada gambar tileset (0..24).
- karena setiap ubin setengah memeriksa 3 tetangga, masing-masing memiliki 2 ^ 3 = 8 negara.
_tile
adalah ubin yang ditargetkan untuk autotiling.
- Karena petak logis kami dua kali lebih besar dari petak rendering kami, semua autotile coords (x, y) harus digandakan dalam peta rendering.
Bagaimanapun, berikut hasilnya (dengan hanya satu ubin, toh):