Tôi đã đến đây bằng cách tự mình giải quyết vấn đề này, đọc các bài viết được liên kết và tạo ra một giải pháp tương đối nhỏ gọn tạo ra bộ 47 gạch chung. Nó đòi hỏi một lát 2x3 cho vật liệu tự động như thế này:
Với một biến thể gạch đơn ở phía trên bên trái, các góc bên trong ở trên cùng bên phải và bốn ô góc bên ngoài ở phía dưới (bạn có thể nhận ra sự sắp xếp này từ RPG Maker).
Mẹo nhỏ là chia mỗi ô bản đồ "hợp lý" thành 4 nửa ô để hiển thị. hơn nữa, một nửa ô trong ô xếp chỉ có thể ở vị trí đó trong ô được tạo, do đó, một nửa ô trên cùng bên trái chỉ có thể được sử dụng ở vị trí trên cùng bên trái.
Những hạn chế này có nghĩa là bạn chỉ cần kiểm tra 3 hàng xóm đầy đủ cho mỗi nửa ô, thay vì tất cả 8 ô lân cận.
Tôi thực hiện ý tưởng này một cách nhanh chóng để kiểm tra nó. Đây là mã bằng chứng khái niệm (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;
}
Giải trình:
A
là phần trên cùng bên trái của gạch, B
là trên cùng bên phải, C
là dưới cùng bên trái, D
là dưới cùng bên phải.
edges
giữ bitmasks cho mỗi trong số này, vì vậy chúng tôi chỉ có thể lấy thông tin hàng xóm có liên quan.
map*
là từ điển ánh xạ các trạng thái lân cận tới các chỉ số đồ họa trong hình ảnh lát (0..24).
- vì mỗi nửa ô kiểm tra 3 hàng xóm, mỗi ô có 2 ^ 3 = 8 trạng thái.
_tile
là gạch nhắm mục tiêu tự động.
- Vì các ô logic của chúng tôi lớn gấp đôi các ô hiển thị của chúng tôi, nên tất cả các chuỗi tự động (x, y) phải được nhân đôi trong bản đồ kết xuất.
Dù sao, đây là kết quả (dù sao chỉ có một ô):