Pertama-tama, saya tahu persis apa masalah menggambar saya, dan saya memiliki berbagai ide tentang cara pendekatan untuk menyelesaikannya. Saya di sini untuk mencari cara menyesuaikan frame mana yang digambar sehingga "ilusi" isometrik dipertahankan.
Saya sedang menulis game 2D, pandangan burung yang berlangsung di luar angkasa. Saya mencoba menggunakan grafik isometrik di dunia di mana Up adalah Utara, tidak ada putaran dunia game seperti di game isometrik tradisional (ingat, permainan berlangsung di ruang angkasa, tidak ada medan). Berikut adalah contoh sprite yang saya coba gunakan: http://cell.stat-life.com/images/stories/AsteroidOutpost/Spaceship64.png Diputar 64 kali tentang sumbu vertikalnya sendiri dengan sudut pandang 35 derajat (alias, iso). Gambar itu dihasilkan, jadi ini bisa diubah.
Demi kejelasan, saya telah menentukan bahwa Utara (Atas) adalah 0 derajat, dan Timur (Kanan) adalah 90.
Masalah saya adalah sprite saya tidak selalu terlihat seperti menghadap ke tempat permainan berpikir itu karena perbedaan dalam pesawat 3D yang digunakan. Tidak yakin apakah saya menggunakan terminologi dengan benar, tetapi pesawat ruang angkasa saya diputar pada satu pesawat, dan pesawat pandangan mengharapkan hal-hal yang akan diputar pada pesawatnya sendiri. Berikut gambaran masalah:
http://cell.stat-life.com/images/stories/AsteroidOutpost/ProjectionIssue.png Di sebelah kiri, saya memiliki tampilan samping, di sebelah kanan saya memiliki tampilan top-down. Di bagian atas, saya memiliki tampilan kapal ruang / sprite dunia. Di bagian bawah, saya memiliki apa yang tampak seperti sprite ketika ditarik ke layar.
Di kanan atas adalah versi yang disederhanakan tentang bagaimana pesawat ruang angkasa saya diputar (pemisahan derajat antara setiap frame). Di kanan bawah adalah sudut yang sprite tampak menghadap ketika sudut tertentu digambar di layar. Masalahnya paling jelas sekitar 45 derajat. Berikut adalah gambar yang dilapis dengan garis "layar pesawat" yang mengarah ke arah yang seharusnya dihadapi kapal: http://cell.stat-life.com/images/stories/AsteroidOutpost/Spaceship64RedLine.png Garis merah harus selalu menunjuk ke arah yang sama persis seperti kapal, tetapi seperti yang Anda lihat, masalah proyeksi menyebabkan masalah. Saya harap saya menggambarkan masalah ini dengan cukup baik.
EDIT: Garis merah diputar pada bidang layar, sedangkan kapal ruang diputar pada "bidang pesawat", maka perbedaan besar antara sudut kapal dan sudut layar ketika digambar. AKHIR EDIT
Terlihat agak aneh ketika kapal ini menembakkan sinar laser ke target yang mengarah ke satu sisi, padahal seharusnya menembak lurus ke depan.
Jadi ... solusi yang saya buat adalah:
- Berhentilah mencoba memalsukan tampilan isometrik, pergi besar atau pulang. Putar duniaku. (PS: ini akan memperbaiki masalah saya, kan?)
- Ubah lembar sprite saya (entah bagaimana) untuk memiliki bingkai yang mewakili "sudut layar" di mana model akan dilihat. Jadi ketika saya meminta gambar 45 derajat, itu akan benar-benar terlihat seperti menghadap 45 derajat di layar.
- Ubah sistem rendering sprite saya untuk mengambil bingkai yang berbeda dari lembar sprite (entah bagaimana), mengetahui bahwa mengambil frame "normal" akan terlihat lucu. Jadi, alih-alih meraih frame 45 derajat, ia akan mengambil ... frame 33 derajat (hanya menebak) sehingga terlihat benar bagi pengguna.
- Cukup gunakan 3D! Jauh lebih mudah
Untuk satu: Solusi mana yang akan Anda rekomendasikan? Saya condong ke arah 2, meskipun saya tahu itu salah. Ingat bahwa saya memiliki akses penuh ke alat pembangkit sprite. Metode 3 akan menjadi pilihan kedua saya. Kedua metode ini hanya mengharuskan saya menerapkan beberapa matematika ke sudut (s) untuk mendapatkan hasil yang saya inginkan. Btw, saya menambahkan # 4 di sana sebagai lelucon, saya tidak ingin pindah ke 3D.
Untuk dua: Menggunakan metode 2 atau 3, bagaimana cara menyesuaikan sudut input atau output? Saya tidak terlalu bagus dengan proyeksi 3D, dan matriks 3D (apalagi matriks 2D), dan apa pun matematika lain yang dapat digunakan untuk mencapai hasil yang saya inginkan.
Berpikir keras di sini: jika saya mengambil unit vektor menghadap ke arah yang saya ingin kapal melihat (di layar pesawat), kemudian proyeksikan itu ke pesawat kapal, lalu cari tahu apa sudut antara garis yang diproyeksikan dan garis pesawat utara adalah, saya harus memiliki sudut grafik kapal yang ingin saya tampilkan. Baik? (solusi untuk # 3?) Man ... Saya tidak bisa menyelesaikannya.
EDIT:
Saya tahu masalahnya sulit untuk divisualisasikan dengan gambar statis, jadi saya telah memenuhi Sprite Library Visual Tester saya untuk menampilkan masalah: http://cell.stat-life.com/downloads/SpriteLibVisualTest.zip Diperlukan XNA 4.0 Aplikasi ini cukup memutar sprite, dan menggambar garis dari titik pusatnya ke luar pada sudut permainan berpikir kapal harus menghadap.
EDIT 8 September
Melanjutkan paragraf "berpikir keras": Alih-alih menggunakan proyeksi (karena terlihat keras), saya berpikir saya bisa mengambil vektor satuan yang menghadap ke utara (0x, 1y, 0z), gunakan matriks untuk memutarnya ke sudut sprite sebenarnya menghadap, kemudian putar lagi dari "pesawat melihat" ke luar ke "pesawat sprite" di sekitar sumbu X, lalu ... ratakan? vektor (pada dasarnya memproyeksikannya) kembali ke bidang tampilan dengan hanya menggunakan X dan Y (mengabaikan Z). Kemudian menggunakan vektor rata yang baru, saya bisa menentukan sudutnya dan menggunakannya untuk ... sesuatu. Saya akan berpikir lebih banyak nanti.
EDIT 8 September (2)
Saya mencoba mengikuti ide saya dari atas dengan beberapa keberhasilan, yay! Jadi ... untuk mendapatkan garis merah agar terlihat seperti langsung keluar dari pesawat ruang angkasa saya (tujuan pengujian saja), saya melakukan yang berikut:
Vector3 vect = new Vector3(0, 1, 0);
vect = Vector3.Transform(vect, Matrix.CreateRotationZ(rotation));
vect = Vector3.Transform(vect, Matrix.CreateRotationY((float)((Math.PI / 2) - MathHelper.ToRadians(AngleFromHorizon))));
Vector2 flattenedVect = new Vector2(vect.X, vect.Y);
float adjustedRotation = (float)(getAngle(flattenedVect.X, flattenedVect.Y));
Di mana rotation
sudut layar dan adjustedRotation
sekarang sudut layar terlihat pada bidang sprite. Saya tidak tahu mengapa saya perlu memutar Y alih-alih X, tapi itu mungkin ada hubungannya dengan 3D yang tidak saya ketahui.
Jadi, sekarang saya memiliki informasi tambahan, tetapi bagaimana saya menggunakan ini untuk memilih kerangka yang lebih tepat? Mungkin alih-alih memutar dari bidang pandangan ke bidang sprite, lalu memproyeksikan kembali, saya harus mencoba melakukannya sebaliknya. Inilah sprite saya dengan garis merah yang disesuaikan, tetapi yang ingin saya lakukan adalah menyesuaikan modelnya, bukan garisnya: http://cell.stat-life.com/images/stories/AsteroidOutpost/Spaceship64RedLineCorrected.png
Sunting 9 September
HORAY! Sudah diperbaiki! Saya akan menjelaskan apa yang saya lakukan untuk memperbaikinya:
Saya mengikuti saran eBusiness dan "diperas" oleh sistem koordinat dunia (atau ditarik ...?). Ini pada dasarnya solusi # 1, meskipun saya mendapat kesan bahwa saya harus memutar sistem koordinat dunia saya sehubungan dengan sistem coord layar. Tidak benar! Naik masih + y, dan Kanan masih + x. Saya memodifikasi metode WorldToScreen dan ScreenToWorld saya untuk mengkonversi antara dunia dan koordinat layar dengan benar. Metode ini mungkin tidak optimal, tetapi hanya ada dua metode dalam basis kode saya yang harus diubah.
public Vector2 ScreenToWorld(float x, float y)
{
float deltaX = x - (size.Width / 2f);
float deltaY = y - (size.Height / 2f);
deltaX = deltaX * scaleFactor / (float)Math.Sqrt(3);
deltaY = deltaY * scaleFactor;
return new Vector2(focusWorldPoint.X + deltaX, focusWorldPoint.Y + deltaY);
}
public Vector2 WorldToScreen(float x, float y)
{
float deltaX = x - focusWorldPoint.X;
float deltaY = y - focusWorldPoint.Y;
deltaX = deltaX / scaleFactor * (float)Math.Sqrt(3);
deltaY = deltaY / scaleFactor;
return new Vector2(size.Width / 2f + deltaX, size.Height / 2f + deltaY);
}
Itu dia! Mengubah kedua metode tersebut memengaruhi segalanya: apa yang saya lihat, di mana objek di mana ditarik, di mana saya mengklik, semuanya. Pesawat ruang angkasa saya sekarang melihat langsung ke target yang ditembakkan, dan semuanya jatuh ke tempatnya. Saya akan bereksperimen dengan proyeksi ortografi, melihat apakah itu membuat semuanya tampak lebih 'nyata'.
sumber
Jawaban:
Ketika Anda memilih perspektif isometrik, Anda perlu mengoreksi skala antara sumbu X dan sumbu Y. Jika jarak yang diberikan memproyeksikan ke 1 pada layar Y-axis maka jarak yang sama akan memproyeksikan ke sqrt (3) pada layar X-axis. Jadi, jika Anda menggambar sesuatu dengan rata di layar, Anda akan melakukan sesuatu seperti:
Catatan tanpa jawaban:
sumber
Bagaimana sprite diputar dihasilkan? Apakah screenshot ini dari model 3D yang berputar? Sudut menghadap dapat dimatikan karena perspektif kamera alat pemodelan 3D. Perspektif isometrik bukan representasi akurat dari ruang 3D. Barang yang jauh dari 'kamera' tidak semakin kecil.
Jika Anda hanya ingin perbaikan cepat. Solusi 2 mungkin sulit untuk diperbaiki. Solusi 3 tampaknya mudah hanya menukar frame yang tidak cocok dengan sudut yang cocok dengan sudut yang lebih baik.
Laser terkadang masih mati. Karena Anda tidak melakukan rotasi yang halus tetapi menunjukkan bingkai yang berbeda untuk rentang derajat tertentu.
EDIT:
Masalah Anda adalah tangkapan layar yang dihasilkan bukan perspektif isometrik, melainkan tampilan kamera 3D normal.
Tampilan isometrik mensimulasikan ruang 3D tetapi bukan representasi yang akurat. Hal-hal menjadi lebih kecil dengan meningkatnya jarak dari kamera. Ini tidak dilakukan untuk perspektif isometrik karena ini akan menyebabkan artefak penskalaan jelek pada sprite.
Tangkapan layar kapal ruang angkasa Anda dibuat dengan perspektif kamera 3D. Karena itulah pemotretan laser tidak aktif. Bandingkan garis merah di 'isometrik' dan 'perspektif'.
Generator sprite Anda harus menggunakan Matrix.CreateOrthographic (), bukan Matrix.CreatePerspective () untuk matriks proyeksi.
sumber
Saya pikir apa yang Anda dapat di sini hanyalah bagaimana penampilan isometrik. Anda benar dalam hal itu, secara visual, tampaknya ada perbedaan yang lebih besar antara 0deg dan 10deg daripada antara 90deg dan 100deg. . . tapi itu karena isometrik secara intrinsik memampatkan satu sumbu. Jika Anda tidak ingin tampilan itu, Anda tidak ingin isometrik.
Yang mengatakan, saya pikir masalah visual yang Anda alami berkat tidak memiliki titik referensi visual. Otak Anda berasumsi Anda memandangnya dari atas ke bawah - hei, ini ruang, mengapa Anda tidak jadi - dan menafsirkannya sebagai tampilan top-down standar. Demi pengujian, coba tambahkan beberapa titik referensi holografik mengambang. Grid miring 45 derajat, misalnya, atau satu set lingkaran jangkauan di sekitar pesawat ruang angkasa Anda. Pastikan mereka terdistorsi dengan tepat seolah-olah mereka berada di bidang isometrik yang sama dengan yang digunakan pesawat ruang angkasa Anda. Saya berani bertaruh bahwa otak Anda akan mengetahui perspektif dan tiba-tiba akan terlihat benar.
Sekarang, cari tahu cara menyampaikannya kepada pengguna Anda. . . itu masalah lain sama sekali.
sumber