Pembaruan: Algoritma perenderan peta yang dikoreksi, menambahkan lebih banyak ilustrasi, pemformatan berubah.
Mungkin keuntungan untuk teknik "zig-zag" untuk memetakan ubin ke layar dapat dikatakan bahwa ubin x
dan y
koordinat berada pada sumbu vertikal dan horizontal.
Pendekatan "Menggambar berlian":
Dengan menggambar peta isometrik menggunakan "drawing in a diamond", yang saya yakini hanya merujuk pada rendering peta dengan menggunakan nested for
-loop pada array dua dimensi, seperti contoh ini:
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)
)
Keuntungan:
Keuntungan dari pendekatan ini adalah ia bersarang sederhana for
sarang-loop dengan logika yang cukup lurus ke depan yang bekerja secara konsisten di semua ubin.
Kerugian:
Satu kelemahan dari pendekatan itu adalah bahwa x
dan y
koordinat ubin pada peta akan meningkat dalam garis diagonal, yang mungkin membuatnya lebih sulit untuk secara visual memetakan lokasi di layar ke peta yang direpresentasikan sebagai sebuah array:
Namun, akan ada kesulitan untuk mengimplementasikan kode contoh di atas - urutan rendering akan menyebabkan ubin yang seharusnya berada di belakang ubin tertentu yang akan ditarik di atas ubin di depan:
Untuk memperbaiki masalah ini, urutan inner- for
loop harus dibalik - mulai dari nilai tertinggi, dan merender ke nilai yang lebih rendah:
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)
)
Dengan perbaikan di atas, rendering peta harus diperbaiki:
Pendekatan "Zig-zag":
Keuntungan:
Mungkin keuntungan dari pendekatan "zig-zag" adalah bahwa peta yang diberikan mungkin tampak sedikit lebih kompak secara vertikal daripada pendekatan "berlian":
Kerugian:
Dari mencoba menerapkan teknik zig-zag, kerugiannya mungkin sedikit lebih sulit untuk menulis kode rendering karena itu tidak dapat ditulis sesederhana seperti bersarang-di for
atas setiap elemen dalam sebuah array:
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
)
Selain itu, mungkin agak sulit untuk mencoba mencari tahu koordinat dari ubin karena sifat urutan pembuatan yang dibuat:
Catatan: Ilustrasi yang disertakan dalam jawaban ini dibuat dengan implementasi Java dari kode render ubin yang disajikan, dengan int
larik berikut sebagai peta:
tileMap = new int[][] {
{0, 1, 2, 3},
{3, 2, 1, 0},
{0, 0, 1, 1},
{2, 2, 3, 3}
};
Gambar ubin adalah:
tileImage[0] ->
Sebuah kotak dengan kotak di dalamnya.
tileImage[1] ->
Kotak hitam.
tileImage[2] ->
Kotak putih.
tileImage[3] ->
Sebuah kotak dengan benda abu-abu tinggi di dalamnya.
Catatan tentang Lebar dan Ketinggian Ubin
Variabel tile_width
dan tile_height
yang digunakan dalam contoh kode di atas merujuk pada lebar dan tinggi ubin tanah di gambar yang mewakili ubin:
Menggunakan dimensi gambar akan berfungsi, selama dimensi gambar dan dimensi ubin cocok. Kalau tidak, peta ubin bisa diberikan dengan celah di antara ubin.
j = (2 * x - 4 * y) / tilewidth * 0.5; i = (p.x * 2 / tilewidth) - j;
.Either way menyelesaikan pekerjaan. Saya berasumsi bahwa dengan zigzag Anda berarti sesuatu seperti ini: (angka adalah urutan render)
Maksud Anda berlian:
Metode pertama membutuhkan lebih banyak ubin yang diberikan sehingga layar penuh digambar, tetapi Anda dapat dengan mudah melakukan pemeriksaan batas dan melewati semua ubin sepenuhnya di luar layar. Kedua metode akan memerlukan beberapa angka untuk mengetahui apa lokasi ubin 01. Pada akhirnya, kedua metode kira-kira sama dalam hal matematika yang diperlukan untuk tingkat efisiensi tertentu.
sumber
Jika Anda memiliki beberapa ubin yang melebihi batas berlian Anda, saya sarankan menggambar dalam urutan mendalam:
sumber
Jawaban Coobird adalah jawaban yang benar dan lengkap. Namun, saya menggabungkan petunjuknya dengan yang ada di situs lain untuk membuat kode yang berfungsi di aplikasi saya (iOS / Objective-C), yang ingin saya bagikan dengan siapa saja yang datang ke sini mencari hal seperti itu. Tolong, jika Anda suka / pilih suara jawaban ini, lakukan hal yang sama untuk aslinya; yang saya lakukan adalah "berdiri di atas bahu raksasa."
Adapun sort-order, teknik saya adalah algoritma pelukis yang dimodifikasi: setiap objek memiliki (a) ketinggian basis (saya sebut "level") dan (b) X / Y untuk "base" atau "foot" dari gambar (contoh: pangkalan avatar ada di kakinya; pangkal pohon ada di akarnya; pangkalan pesawat terbang adalah gambar tengah, dll.) Lalu saya hanya menyortir terendah ke level tertinggi, lalu terendah (layar tertinggi) ke basis tertinggi- Y, lalu terendah (paling kiri) ke basis-X tertinggi. Ini membuat ubin seperti yang diharapkan.
Kode untuk mengkonversi layar (titik) ke ubin (sel) dan kembali:
sumber
Anda dapat menggunakan jarak euclidean dari titik tertinggi dan terdekat pemirsa, kecuali itu tidak tepat. Ini menghasilkan urutan semacam bola. Anda bisa meluruskannya dengan melihat dari jauh. Lebih jauh kelengkungan menjadi rata. Jadi tambahkan saja 1000 ke masing-masing komponen x, y dan z untuk memberikan x ', y' dan z '. Sortir pada x '* x' + y '* y' + z '* z'.
sumber
Masalah sebenarnya adalah ketika Anda perlu menggambar beberapa ubin / sprite memotong / merentang dua atau lebih ubin lainnya.
Setelah 2 (analisis) masalah pribadi saya akhirnya menemukan dan menerapkan "gambar render yang benar" untuk permainan cocos2d-js baru saya. Solusi terdiri dalam pemetaan, untuk setiap ubin (rentan), yang sprite adalah "depan, belakang, atas dan belakang". Setelah melakukan itu, Anda dapat menggambar mereka mengikuti "logika rekursif".
sumber