Aktualizacja: poprawiony algorytm renderowania mapy, dodano więcej ilustracji, zmieniono formatowanie.
Być może zaletą techniki „zygzakowatości” mapowania kafelków na ekran można powiedzieć, że kafelki x
i y
współrzędne są na osi pionowej i poziomej.
Podejście „ciągnąc za diament”:
Rysując mapę izometryczną za pomocą „rysowania w diamentie”, co moim zdaniem odnosi się do renderowania mapy za pomocą zagnieżdżonej for
pętli nad dwuwymiarową tablicą, na przykład w tym przykładzie:
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)
)
Korzyść:
Zaletą tego podejścia jest to, że jest to prosta zagnieżdżona for
pętla z dość prostą logiką, która działa konsekwentnie na wszystkich płytkach.
Niekorzyść:
Jednym minusem tej metody jest to, że x
i y
współrzędne płytki na mapie wzrośnie w ukośne linie, które mogłyby utrudnić wizualnie map lokalizację na ekranie mapie reprezentowane jako tablica:
Jednak zaimplementowanie powyższego przykładowego kodu będzie pułapką - kolejność renderowania spowoduje, że płytki, które powinny znajdować się za niektórymi płytkami, zostaną narysowane na wierzchu płytek z przodu:
Aby rozwiązać ten problem, for
kolejność pętli wewnętrznej musi zostać odwrócona - zaczynając od najwyższej wartości i renderując w kierunku niższej wartości:
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)
)
Przy powyższej poprawce renderowanie mapy powinno zostać poprawione:
Podejście „zygzakowate”:
Korzyść:
Być może zaletą podejścia „zygzakowatego” jest to, że renderowana mapa może wydawać się nieco bardziej zwarta w pionie niż podejście „diamentowe”:
Niekorzyść:
Próbując wdrożyć technikę zygzakowatą, wadą może być to, że nieco trudniej jest napisać kod renderujący, ponieważ nie można go napisać tak prosto, jak zagnieżdżona for
pętla nad każdym elementem w tablicy:
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
)
Ponadto może być trochę trudna próba ustalenia współrzędnych płytki ze względu na rozłożony charakter kolejności renderowania:
Uwaga: ilustracje zawarte w tej odpowiedzi zostały utworzone przy użyciu implementacji Java przedstawionego kodu renderowania kafelków, z następującą int
tablicą jako mapą:
tileMap = new int[][] {
{0, 1, 2, 3},
{3, 2, 1, 0},
{0, 0, 1, 1},
{2, 2, 3, 3}
};
Obrazy kafelków to:
tileImage[0] ->
Pudełko z pudełkiem w środku.
tileImage[1] ->
Czarna skrzynka.
tileImage[2] ->
Białe pudełko.
tileImage[3] ->
Pudełko z wysokim szarym przedmiotem.
Uwaga na temat szerokości i wysokości płytek
Zmienne tile_width
i tile_height
które są stosowane w powyższych przykładach kodu odnoszą się do szerokości i wysokości płyty naziemnej w obrazie reprezentującym płytki:
Korzystanie z wymiarów obrazu będzie działać, o ile wymiary obrazu i wymiary kafelków będą takie same. W przeciwnym razie mapę kafelków można renderować z przerwami między kafelkami.