Teknik terbaik untuk menggambar ubin isometrik

8

Saya sedang berpikir untuk membuat game isometrik sederhana dengan HTML5 Canvas, dan bertanya-tanya apa cara tercepat untuk membuat ubin.

Karena ubin berbentuk berlian, tetapi drawImage menggambar segi empat, saya harus meninggalkan sudut (bagian hitam di bawah):

contoh ubin berlian

Saya pikir itu membuat saya dengan tiga opsi:

  1. Gunakan objek Gambar dengan saluran alfa (.png). Saya khawatir ini akan mematikan kinerja.
  2. Gunakan jalur kliping. Jika penyaji dioptimalkan ini bisa sangat cepat.
  3. Ubin persegi prerender, seperti ini:

ubin persegi prerendered

Saya akan memiliki kotak hitam sebagai satu ubin yang sebenarnya dalam memori, dan saya akan menggambar ubin seperti itu untuk bidang hijau, dan semua bidang di sebelahnya, atau di atas dan di bawah. Bidang diagonal (biru) terdiri dari sudut-sudut ubin persegi panjang. Ini akan menghindari saluran kliping atau alfa, tetapi saya harus mempratinjau semua kemungkinan kombinasi ubin, dan sepertinya terlalu berlebihan.

Apa cara terbaik atau tercepat untuk melakukan ubin isometrik? Apa yang digunakan gim lain, seperti FarmVille?

jdm
sumber
1
Saya pikir "teknik terbaik" adalah jenis yang dimuat, dan akan tergantung pada persyaratan permainan, dan teknologi yang digunakan dan pengembang membuat game.
MichaelHouse
1
Masalah apa yang sebenarnya Anda alami? Sepertinya Anda telah memberikan tiga jawaban untuk pertanyaan Anda sendiri di dalam teks pertanyaan?
Trevor Powell
1
Ini tidak memiliki suara yang cukup: BESSSSSSST TERBAIK TERBAIK! argh?
Jimmy
1
Kira Anda harus mengikuti saran yang ditemukan di sini: meta.gamedev.stackexchange.com/a/638/7191
MichaelHouse
1
Jadi, Anda tidak tahu bahwa ini sebenarnya masalah kinerja? Anda hanya mencoba mengoptimalkan kode sebelum ditulis? Dalam hal ini, -1 dan memberikan suara untuk menutup.
Trevor Powell

Jawaban:

11

Saya sarankan untuk menggunakan transparansi (saluran alfa).

Ini berarti bahwa ketika Anda menginginkan objek vertikal pada ubin seperti ini:

ubin dengan pohon

Maka Anda dapat melakukannya dengan mudah jika penyaji Anda menggambar ubin back-to-front yaitu algoritma pelukis.

KREDIT GAMBAR: Ubin Reiner.

MarkR
sumber
9

Sementara metode yang dijelaskan oleh sws dan MarkR juga merupakan pilihan saya, saya ingin menyajikan pendekatan alternatif.

Opsi peretasan untuk membuat tampilan isometrik dengan upaya minimal adalah dengan benar-benar menggunakan ubin ortogonal, dan menggunakan context.transform untuk mengatur matriks proyeksi yang membuat peta tampak isometrik (atau kombinasi dari konteks. Perlindungan dan konteks. Skala ketika Anda tidak t tahu cara kerja matriks proyeksi).

Lihat spesifikasi untuk metode transformasi kanvas untuk detailnya.

Gambar ubin:

gambar ubin dasar

Kode gambar:

    for (var x = 0; x < 5; x++) {
        for (var y = 0; y < 5; y++) {
            ctx.drawImage(img, x * img.width, y * img.height);
        }
    }

Hasil sebelum aplikasi matriks:

tanpa matriks transformasi diterapkan

Kode yang sama dengan gambar ubin yang sama setelah menerapkan matriks transformasi ini:

    ctx.transform(  1,   0.5,
                   -1,   0.5,
                  160,   0    );

dengan matriks transformasi

Dengan kisi putus-putus dihapus dari gambar ubin dan mengubah offset ubin dalam kode gambar ke img.width - 1dan img.height - 1untuk menghilangkan celah yang disebabkan oleh transformasi. Tiba-tiba ubin terlihat setengah jelek:

dengan matriks dan beberapa tweak

Kelemahan utama dari metode ini adalah bahwa ketika Anda mendesain ubin Anda dalam editor grafis, mereka tidak akan benar-benar menjadi apa yang Anda lihat adalah apa yang Anda dapatkan. Anda juga akan mengalami masalah ketika Anda ingin menggambar benda yang tidak di lantai tetapi berdiri tegak. Untuk ini, Anda dapat mematikan matriks transformasi sebelum menggambar mereka, tetapi kemudian Anda harus menghitung posisi sendiri. Anda dapat menggunakan rumus ini untuk itu:

var xScreen = xWorld * 1   + yWorld * -1  + 160;
var yScreen = xWorld * 0.5 + yWorld * 0.5 + 0;  

(perhatikan bagaimana angka-angka dari matriks transformasi muncul kembali dalam formula ini - Anda melakukan sendiri perkalian matriks di sini).

Jadi mengapa saya harus melakukan ini?

Metode ini bagus ketika Anda:

  1. tidak berpengalaman dalam mendesain ubin isometrik, tetapi Anda memiliki ubin ortogonal
  2. tidak ingin menghabiskan banyak waktu untuk mengembangkan mesin grafis isometrik, yang agak lebih sulit daripada yang ortogonal.

Fitur menarik lainnya adalah ketika Anda mengetahui cara penghitungan matriks, Anda dapat memodifikasi matriks proyeksi antara bingkai untuk memperbesar, memiringkan dan memutar peta secara real-time untuk beberapa efek palsu-3d yang bagus (coba lakukan ITU dengan ubin isometrik) .

Tetapi ketika Anda tahu cara menangani ubin isometrik, baik secara artistik dan teknis, dan Anda tidak memerlukan tipuan perspektif palsu, saya lebih suka menyarankan Anda menggunakan ubin berbentuk berlian dengan transparansi.

Philipp
sumber
Tentu mungkin untuk melakukan ini. Dengan cara ini Anda dapat memiliki ubin "rata" atau "atas-bawah". Namun, itu berarti bahwa elemen "3d" di ubin tidak dapat dilakukan dengan mudah. Saya lebih suka melakukan transformasi ini sebelumnya.
MarkR
+1 jika tidak hanya untuk penjelasan ahli! Sudah selesai dilakukan dengan baik.
Luceos
@ MarkR: Saya banyak memperluas jawaban saya setelah Anda membuat komentar, Anda mungkin ingin melihatnya jika masih berlaku.
Philipp
1
Terima kasih untuk artikel lengkapnya! Itu teknik yang sangat menarik, saya tidak berpikir untuk melakukan itu sebelumnya. Namun, karena saya mulai dari awal (dan saya sama buruknya dalam menggambar ubin isometrik dan bujur sangkar ;-)), saya akan menggunakan ubin isometrik yang sebenarnya. Juga, ini sepertinya tidak terlalu cepat. Saya melakukan patokan kecil, dan menyaring ubin tanpa matriks transformasi ke posisi piksel integer adalah sekitar 3x lebih cepat daripada dengan transformasi pada PC saya. Masih saya mungkin menggunakan ini untuk beberapa efek khusus.
jdm
Adakah cara untuk menambahkan beberapa level z ke peta ini?
Tarion
3
  1. Anda menggunakan context.drawImage untuk menyalin data piksel dari satu sumber (Gambar, atau kanvas layar) ke yang lain (kanvas layar atau layar), yang menangani alfa dengan anggun di luar kotak. Canvas adalah akselerasi perangkat keras, jadi pengujian akan memungkinkan Anda untuk menentukan apakah ada perbedaan yang terlihat dalam kecepatan rendering wrt alfa-vs opaque-piksel.

  2. Kliping akan mengharuskan Anda untuk mendorong / pop negara konteks ketika mendefinisikan jalur kliping sekali per ubin, yang bisa menjadi operasi yang mahal mengingat penarikan berlebih isometrik.

  3. Ubin prerendered akan, seperti yang Anda sebutkan, membutuhkan ubin 'konektor' dalam jumlah besar untuk ditarik, yang mungkin atau mungkin tidak layak. (Saya lebih condong ke arah "mungkin tidak".)

Solusi keempat adalah mengadopsi "potongan" (PRC) ubin yang dibuat sebelumnya, dihasilkan satu kali untuk kanvas layar, dan kemudian menutupi layar dengan PRC satu kali per frame. Masih akan ada overdraw, tetapi membangun RRC satu kali dan merendernya dengan offset yang ditentukan oleh posisi karakter pemain (atau melihat kamera) relatif terhadap RRT harus merupakan operasi yang relatif sederhana. Ini akan memungkinkan Anda untuk menggabungkan rendering dengan opsi # 1, yang merupakan IMO pilihan terbaik jika kinerja bukan pertimbangan (karena ini paling sederhana untuk diterapkan).

sws
sumber
3

Saluran alpha kecil tidak terlalu menyakitkan, tetapi jika Anda ingin menghindarinya pertimbangkan untuk menggunakan dua perempat ubin, ini juga memberi Anda ruang untuk membuat transisi ubin yang bagus tanpa melakukan banyak gambar yang berbeda, yang mungkin merupakan keuntungan terbesar:

Pola sub-ubin persegi panjang

aaaaaaaaaaaa
sumber