Cập nhật: Sửa thuật toán kết xuất bản đồ, thêm hình minh họa, thay đổi hình thức.
Có lẽ lợi thế cho kỹ thuật "zig-zag" để ánh xạ các ô tới màn hình có thể nói rằng các ô x
và y
tọa độ nằm trên trục dọc và trục ngang.
Phương pháp "Vẽ trong kim cương":
Bằng cách vẽ một bản đồ đẳng cự bằng cách sử dụng "vẽ trong một viên kim cương", mà tôi tin là chỉ hiển thị bản đồ bằng cách sử dụng một for
-loop lồng nhau trên mảng hai chiều, chẳng hạn như ví dụ này:
tile_map[][] = [[...],...]
for (cellY = 0; cellY < tile_map.size; cellY++):
for (cellX = 0; cellX < tile_map[cellY].size cellX++):
draw(
tile_map[cellX][cellY],
screenX = (cellX * tile_width / 2) + (cellY * tile_width / 2)
screenY = (cellY * tile_height / 2) - (cellX * tile_height / 2)
)
Lợi thế:
Ưu điểm của phương pháp này là nó là một cái lồng đơn giản for
với logic khá thẳng về phía trước, hoạt động nhất quán trong tất cả các ô.
Bất lợi:
Một nhược điểm của cách tiếp cận đó là x
và y
tọa độ của các ô trên bản đồ sẽ tăng theo các đường chéo, điều này có thể gây khó khăn hơn cho việc ánh xạ trực quan vị trí trên màn hình vào bản đồ được biểu thị dưới dạng một mảng:
Tuy nhiên, sẽ có một khó khăn khi thực hiện mã ví dụ trên - thứ tự kết xuất sẽ khiến các ô được cho là nằm sau các ô nhất định được vẽ trên đầu các ô ở phía trước:
Để sửa đổi vấn đề này, for
thứ tự của vòng trong phải được đảo ngược - bắt đầu từ giá trị cao nhất và hiển thị về giá trị thấp hơn:
tile_map[][] = [[...],...]
for (i = 0; i < tile_map.size; i++):
for (j = tile_map[i].size; j >= 0; j--): // Changed loop condition here.
draw(
tile_map[i][j],
x = (j * tile_width / 2) + (i * tile_width / 2)
y = (i * tile_height / 2) - (j * tile_height / 2)
)
Với cách khắc phục ở trên, việc hiển thị bản đồ cần được sửa:
Phương pháp "Zig-zag":
Lợi thế:
Có lẽ ưu điểm của phương pháp "zig-zag" là bản đồ được hiển thị có thể nhỏ gọn hơn một chút so với phương pháp "kim cương":
Bất lợi:
Từ việc cố gắng thực hiện kỹ thuật zig-zag, nhược điểm có thể là khó hơn một chút để viết mã kết xuất bởi vì nó không thể được viết đơn giản như một for
-loop lồng trên mỗi phần tử trong một mảng:
tile_map[][] = [[...],...]
for (i = 0; i < tile_map.size; i++):
if i is odd:
offset_x = tile_width / 2
else:
offset_x = 0
for (j = 0; j < tile_map[i].size; j++):
draw(
tile_map[i][j],
x = (j * tile_width) + offset_x,
y = i * tile_height / 2
)
Ngoài ra, có thể hơi khó khăn để cố gắng tìm ra tọa độ của ô do tính chất so le của thứ tự kết xuất:
Lưu ý: Các hình minh họa có trong câu trả lời này được tạo ra bằng cách triển khai Java mã mã kết xuất gạch, với int
mảng sau là bản đồ:
tileMap = new int[][] {
{0, 1, 2, 3},
{3, 2, 1, 0},
{0, 0, 1, 1},
{2, 2, 3, 3}
};
Các hình ảnh gạch là:
tileImage[0] ->
Một hộp có một hộp bên trong.
tileImage[1] ->
Một hộp đen.
tileImage[2] ->
Một hộp màu trắng.
tileImage[3] ->
Một hộp có một vật màu xám cao trong đó.
Lưu ý về chiều rộng và chiều cao của gạch
Các biến tile_width
và tile_height
được sử dụng trong các ví dụ mã ở trên đề cập đến chiều rộng và chiều cao của lát nền trong hình ảnh đại diện cho ô:
Sử dụng kích thước của hình ảnh sẽ hoạt động, miễn là kích thước hình ảnh và kích thước ô phù hợp. Mặt khác, bản đồ ô có thể được hiển thị với các khoảng trống giữa các ô.