Saya telah bekerja pada pengembangan aplikasi dengan banyak sistem GUI "yang dipertahankan" (di bawah ini lebih lanjut tentang apa yang saya maksud dengan itu) seperti MFC, QT, Forms, SWING, dan beberapa kerangka kerja web-GUI beberapa tahun yang lalu. Saya selalu menemukan konsep kebanyakan sistem GUI terlalu rumit dan canggung. Jumlah peristiwa panggilan balik, pendengar, salinan data, sesuatu untuk dirangkai dengan sesuatu - konversi (dan sebagainya) selalu menjadi sumber kesalahan dan sakit kepala dibandingkan dengan bagian lain dalam aplikasi. (Bahkan dengan penggunaan "Binding / Model Data" yang tepat).
Sekarang saya sedang menulis game komputer :). Saya bekerja dengan satu GUI sejauh ini: Miyagi (tidak terkenal, tetapi pada dasarnya Ide yang sama dengan semua sistem lainnya.)
Itu mengerikan.
Untuk lingkungan render waktu nyata seperti Game, saya merasa bahwa sistem GUI "yang dipertahankan" bahkan lebih usang. Antarmuka pengguna biasanya tidak perlu ditata secara otomatis atau memiliki jendela resizable on-the-fly. Sebaliknya, mereka perlu berinteraksi sangat efisien dengan data yang selalu berubah (seperti posisi 3d model di dunia)
Beberapa tahun yang lalu, saya menemukan "IMGUI" yang pada dasarnya seperti mode Grafis Langsung, tetapi untuk antarmuka pengguna. Saya tidak memberi terlalu banyak perhatian, karena saya masih dalam pengembangan aplikasi dan adegan IMGUI itu sendiri tampaknya tidak terlalu luas atau tidak berhasil. Namun pendekatan yang mereka ambil tampaknya sangat seksi dan elegan, sehingga saya ingin menulis sesuatu untuk proyek selanjutnya menggunakan UI seperti ini (saya gagal meyakinkan siapa pun di tempat kerja: (...)
izinkan saya meringkas apa yang saya maksud dengan "dipertahankan" dan "segera":
Retensi GUI: Dalam fase inisialisasi terpisah, Anda membuat "kontrol GUI" seperti Label, Tombol, Kotak Teks dll. Dan menggunakan beberapa cara deskriptif (atau terprogram) untuk menempatkannya di layar - semua sebelum apa pun diberikan. Kontrol menahan sebagian besar statusnya dalam memori seperti X, lokasi Y, ukuran, batas, kontrol anak, teks label, gambar, dan sebagainya. Anda dapat menambahkan panggilan balik dan pendengar untuk mendapat informasi tentang acara dan memperbarui data dalam kontrol GUI.
GUI Langsung: Pustaka GUI terdiri dari satu-fungsi "RenderButton", "RenderLabel", "RenderTextBox" ... fungsi (sunting: jangan bingung dengan Renderawalan. Fungsi-fungsi ini juga melakukan logika di balik kontrol seperti polling input pengguna, memasukkan karakter, menangani karakter-repeat-speed ketika pengguna menekan tombol dan sebagainya ...) yang dapat Anda panggil untuk "segera" membuat kontrol (tidak "Harus segera ditulis ke GPU. Biasanya diingat untuk frame saat ini dan diurutkan ke dalam batch yang sesuai nanti). Perpustakaan tidak memiliki "keadaan" untuk ini. Jika Anda ingin menyembunyikan tombol ... jangan panggil fungsi RenderButton. Semua fungsi RenderXXX yang memiliki interaksi pengguna seperti tombol atau kotak centang memiliki nilai kembali yang menunjukkan apakah misalnya pengguna mengklik tombol. Jadi "RenderGUI" Anda fungsi tampak seperti fungsi if / else besar di mana Anda memanggil atau tidak memanggil fungsi RenderXXX Anda tergantung pada kondisi permainan Anda dan semua logika pembaruan data (ketika tombol ditekan) terjalin ke dalam aliran. Semua penyimpanan data "di luar" gui dan diteruskan sesuai permintaan ke fungsi Render. (Tentu saja, Anda akan membagi fungsi-fungsi besar menjadi beberapa yang atau menggunakan beberapa abstraksi kelas untuk mengelompokkan bagian-bagian gui. Kami tidak menulis kode seperti pada tahun 1980 lagi, kan?;))
Sekarang saya menemukan bahwa Unity3D sebenarnya menggunakan pendekatan dasar yang sama untuk sistem GUI bawaan mereka. Mungkin ada beberapa GUI dengan pendekatan ini di luar sana juga?
Namun .. ketika melihat sekeliling, sepertinya ada bias yang kuat terhadap sistem GUI yang dipertahankan? Setidaknya saya belum menemukan pendekatan ini kecuali di Unity3D dan komunitas IMGUI asli tampaknya agak .... tenang.
Jadi, ada yang bekerja dengan kedua ide dan memiliki pendapat yang kuat?
Sunting: Saya sangat tertarik dengan pendapat yang berasal dari pengalaman dunia nyata. Saya pikir ada banyak diskusi hangat di forum IMGUI tentang "kelemahan teoritis" dari pendekatan GUI langsung, tetapi saya selalu merasa lebih mencerahkan untuk mengetahui tentang kelemahan dunia nyata .
Jawaban:
Bahkan. Saya telah melakukan pekerjaan gamedev berbayar pada GUI 'mode yang dipertahankan' yang mengerikan dan pada GUI 'mode langsung' yang mengerikan dan meskipun keduanya membuat saya ingin mengalihkan pandangan, pendekatan mode tetap masih jelas yang lebih baik.
Kelemahan dari mode langsung banyak:
Moda langsung GUI menggoda bagi pemrogram tunggal yang menginginkan sistem HUD cepat, dan untuk itu mereka hebat. Untuk hal lain ... katakan saja tidak.
sumber
Sebagai seseorang dengan lima atau enam tahun pengalaman aktual dengan IMGUI di desktop, saya merasa berkewajiban untuk mempertahankannya. Semua tanggapan (dan pertanyaan itu sendiri) didasarkan pada definisi IMGUI yang sangat terbatas, dan tampaknya ada banyak klaim yang dipertanyakan.
Banyak yang berasal dari asumsi bahwa perpustakaan IMGUI tidak dapat menyimpan data apa pun di bawah tenda. Ini tidak benar sama sekali. Perpustakaan IMGUI yang canggih sebenarnya akan menyimpan sebanyak mungkin data yang setara dengan perpustakaan RMGUI. Perbedaannya adalah bahwa pustaka IMGUI sebagian besar menyimpan hasil, sedangkan pustaka RMGUI mempertahankan status otoritatif. Dalam IMGUI, aplikasi menyediakan fungsi yang mengambil status model saat ini dan menghasilkan GUI untuk status itu. Ini adalah definisi otoritatif dari GUI. Perpustakaan bertanggung jawab untuk memastikan bahwa GUI di layar cocok dengan hasil dari fungsi itu. Ini tidak berarti bahwa itu perlu mengevaluasi sepenuhnya fungsi itu setiap frame dan sepenuhnya membangun kembali GUI. Itulah tujuan dari caching.
Dengan tampilan IMGUI ini, Anda sebenarnya bisa melakukan tata letak yang canggih, dan kinerjanya cukup masuk akal. Anda juga dapat mempertahankan status otoritatif yang sebenarnya jika membuat antarmuka lebih mudah. Maksud dari IMGUI bukanlah untuk membuat aplikasi mempertahankan segalanya. Aplikasi mungkin tidak ingin harus menyimpan posisi setiap scrollbar dan status diperluas / diciutkan dari setiap simpul pohon. Intinya adalah untuk dapat secara prosedural menentukan isi dari simpul pohon tersebut dan keberadaannya.
Saya akan membahas dan menanggapi semua kritik IMGUI poin demi poin, tetapi saya tidak terlalu mengerti banyak dari mereka. Sebagian besar dari mereka tampaknya berasal dari beberapa kepercayaan mendasar bahwa IMGUI adalah peretasan dan RMGUI terstruktur dengan baik, yang saya kira berasal dari kesalahpahaman di atas. Tidak ada alasan yang melekat bahwa perpustakaan IMGUI harus memiliki masalah dengan kompleksitas atau harus dikotori dengan global atau campuran logika dengan presentasi. Saya akan mengatakan bahwa keuntungan dari IMGUI menjadi kurang penting semakin konten yang digerakkan oleh artis, tapi saya tidak yakin mengapa itu akan menjadi lebih buruk untuk konten yang digerakkan oleh artis. (Saya pribadi tidak menggunakan konten yang digerakkan oleh artis, selain dari style sheet untuk hal-hal seperti warna, ukuran font / perbatasan, dll., Tapi saya tidak mengerti mengapa itu akan lebih sulit untuk diterapkan daripada untuk RMGUI.)
Dalam pikiran saya, IMGUI tidak diragukan lagi adalah hal yang baik. Ini memberi Anda model yang jauh lebih baik untuk alasan tentang GUI Anda. Ini menjadi jauh lebih fungsional dan reaktif, dan Anda meminimalkan jumlah keadaan bisa berubah yang harus Anda pertimbangkan. Di sisi lain, menerapkan perpustakaan IMGUI yang canggih merupakan tantangan, dan jelas lebih sulit daripada menerapkan perpustakaan RMGUI yang setara. Ini adalah tradeoff antara kompleksitas perpustakaan dan kompleksitas aplikasi. Jika Anda berencana membuat aplikasi yang kompleks (atau bahkan banyak aplikasi sederhana), pengorbanannya sangat bagus. Jika Anda melakukan ini untuk satu aplikasi tunggal, dan itu cukup sederhana, Anda mungkin akan mencapai tujuan Anda lebih cepat dengan RMGUI.
Bagaimanapun, semoga berhasil!
sumber
Saya akan mengatakan bahwa ini bukan perpustakaan GUI. Itu hanya sekelompok fungsi rendering.
Merender GUI adalah bagian termudah untuk membuat GUI. Ambil kotak teks misalnya. Saya akan mengasumsikan kasus termudah yang mungkin: kotak teks entri baris tunggal sederhana.
RenderTextBox
hanya akan menggambar kotak teks. Ini akan melakukan beberapa pengukuran teks sederhana dan menggambar mesin terbang di layar. Ini akan tidakSaya bisa terus berjalan, tetapi saya pikir poin saya jelas. Jika Anda ingin menggunakan
RenderTextBox
untuk menggambar kotak teks, yang Anda dapatkan hanyalah kotak teks statis yang tidak berfungsi. Setiap fungsi aktual harus diterapkan oleh Anda.Melakukan pengukuran teks dan menggambar mesin terbang? Itu bagian yang mudah dari pekerjaan GUI. GUI adalah singkatan dari "Graphical User Interface". Dua kata terakhir, di mana Anda mengambil input dari pengguna dan melakukan sesuatu dengannya, adalah bagian yang sulit.
Pemain game berharap kontrol GUI bekerja dengan wajar. Dalam lingkungan bergaya PC (yaitu: mouse dan keyboard), jika pemain melihat kotak teks, mereka berharap itu berfungsi seperti kotak teks biasa. Mereka berharap dapat bergerak di dalamnya dengan tombol panah, melompat ke depan dan akhiri dengan rumah dan menghapus, memilih huruf di dalamnya, dll.
Itu berarti Anda harus menerapkan semua kode UI ini. Anda harus menguji kontrol apa yang diklik. Anda kemudian harus melakukan sesuatu berdasarkan kontrol mana yang diklik. Anda harus memiliki konsep kontrol "aktif", yang mendapat input keyboard. Kontrol yang berbeda harus merespons secara berbeda terhadap berbagai jenis interaksi pengguna.
Pada dasarnya, Anda akan membutuhkan
TextBoxWindow
kelas.Katakanlah Anda menerapkan layar opsi permainan. Jadi Anda memiliki grup opsi yang berbeda: gameplay, grafik, suara, kontrol, dll. Jadi, Anda memiliki daftar grup yang berbeda di sisi kiri layar. Setiap grup menampilkan serangkaian kontrol yang dapat dimanipulasi pengguna. Apa yang terjadi ketika pengguna menekan tombol Tab?
Yah, itu tergantung pada kontrol apa yang aktif. Jika salah satu kontrol grup aktif (paling baru diklik), maka itu akan pindah ke grup berikutnya. Jika alih-alih salah satu kontrol di dalam grup aktif, maka itu akan pindah ke kontrol berikutnya di grup itu. Begitulah sistem dimaksudkan untuk bekerja.
Jadi tidak hanya harus input keyboard proses kontrol aktif, itu juga harus menanam input yang belum diproses ke kontrol yang memilikinya . Entah itu, atau kontrol harus ada dalam semacam daftar tertaut, sehingga dapat bolak-balik. Itu berarti perlu ada perilaku default di setiap kontrol.
Ini terdengar lebih dan lebih seperti GUI yang dipertahankan, bukan? Satu-satunya perbedaan adalah bahwa ... kaulah yang melakukan kerja keras. Menggunakan orang lain GUI seharusnya menjadi cara untuk melakukan lebih sedikit pekerjaan. Namun upaya yang diperlukan untuk membuat respons GUI seperti yang diharapkan pengguna tidak sepele.
Ingat: UI bukan untuk Anda, itu untuk pengguna Anda . Ini untuk pemain. Itu harus berperilaku seperti yang mereka harapkan. Dan jika tidak, maka Anda telah gagal.
Itu adalah pemikiran yang terbatas dan membatasi.
Saya bisa memberikan spiel tentang game yang berbeda yang memiliki kebutuhan UI yang berbeda, bahwa beberapa game memang membutuhkan jendela yang dapat diubah ukurannya dan sebagainya. Tapi ada masalah yang jauh lebih besar.
Jenis pemikiran Anda mengarah ke masalah Pertempuran Luar Angkasa yang serampangan.
Jika Anda belum pernah memainkan game itu, itu adalah game yang murah, indie, dan sangat berat GUI. Gameplay yang sebenarnya semuanya dilakukan dalam GUI (ini adalah jenis "setup unit dan saksikan mereka bertarung"). Masalah?
GUI TIDAK BISA DIADAPKAN!
Oh, ini bagus jika Anda menggunakan monitor normal atau memiliki penglihatan normal. Tetapi jika Anda saya, misalnya, yang menjalankan monitor yang sangat besar (satu yang sangat besar sehingga Windows Anda memperbesar ukuran semua teks sehingga Anda dapat membacanya), ini mengerikan . Teksnya mikroskopis. Tidak ada cara untuk mengubah ukuran font.
Memang, GSB adalah game berbasis GUI, jadi itu benar-benar tidak bisa dimaafkan bagi mereka. GUI-lite game mungkin bisa lolos begitu saja.
Jangan pernah berasumsi bahwa pengguna Anda melihat permainan mereka persis seperti Anda. Melakukannya adalah kebodohan.
Memiliki sistem GUI yang dapat mengubah skala dirinya sendiri ke resolusi pengguna, GUI yang benar-benar bebas resolusi, memerlukan tata letak untuk menjadi bagian dari sistem GUI itu sendiri. Jika Anda tidak akan menyediakannya, maka teks Anda akan tampak kecil di monitor raksasa seseorang. Ini bukan hal yang baik.
Jadi saya akan mengatakan bahwa pemikiran Anda tentang hal ini adalah picik. Anda memang membutuhkan barang itu. Anda membutuhkan apa yang disediakan oleh GUI. Oh, Anda mungkin tidak membutuhkan semua yang disediakan oleh sistem GUI tertentu. Tetapi Anda membutuhkannya.
Pekerjaan boilerplate yang perlu Anda lakukan untuk mendapatkan data ke sistem adalah harga kecil yang harus dibayar di samping memiliki jaminan yang masuk akal bahwa pengguna dapat berinteraksi dengan kontrol dengan benar dan akan mengubah ukurannya sendiri agar sesuai dengan kebutuhan pemain.
Anda mungkin bisa lolos dengan GUI mode langsung jika Anda tidak mengambil banyak input pengguna dari pemain. Tapi itu saja.
sumber
RenderTextBox
itu fungsi , bukan kelas. Jadi pembagian Anda antara "mode langsung" dan "mode dipertahankan" tampaknya berada di sekitar tempat data disimpan, bukan siapa yang mengelolanya. Jika demikian, Anda perlu membuat perbedaan itu lebih jelas dalam pertanyaan Anda, karena itu menunjukkan bahwa "GUI mode langsung" hanya menggambar hal-hal di layar. Itu tidak bisa mendapatkan input (karena itu akan membutuhkan status persisten) dan semacamnya. Jadi yang mana?Beberapa waktu yang lalu IMGUI juga menarik minat saya, sebagai ujian saya menulis beberapa tutorial untuk membiasakan diri dengan teknik (mulai di sini jika Anda tertarik, tapi itu tidak lebih dari C # / XNA + 'tutorial' asli di sini ) .
Saya benar-benar menyukai IMGUI untuk sementara waktu karena info yang ditampilkan selalu mutakhir dan benar (karena tidak ada keadaan Anda selalu memberi makan ke data aktual). Tetapi pada akhirnya saya kehilangan minat sehingga biasanya sekarang saya menggunakan GUI yang ditahan lagi.
Pada akhirnya saya berpikir bahwa keteraturan GUI membuatnya lebih sulit untuk memisahkan GUI dari data dan kadang-kadang saya mencoba untuk memisahkan hal-hal dengan memperkenalkan beberapa negara, melanggar keanggunan IMGUI. Saya juga tidak berpikir bahwa menulis kode untuk GUI yang disimpan lebih berfungsi daripada menulis kode untuk IMGUI dan saya suka bahwa GUI yang ditahan dapat dipecat dan dilupakan, dan saya sangat suka acara :).
Namun, setiap kali seseorang menyebut IMGUI sesuatu di dalam diriku ingin mencoba lagi, dan berusaha lebih keras untuk memperbaikinya, karena memang ada keanggunan di sana, aku hanya tidak 100% yakin apakah itu akan selalu membuat pekerjaanmu lebih mudah. Saya akan mengatakan mencobanya, mungkin mencoba seperti yang saya lakukan dan menulis beberapa tutorial (Saya menemukan cara terbaik untuk mempelajari teknik baru adalah dengan menjelaskannya kepada orang lain).
sumber
Saya banyak bekerja dengan sistem GUI Unity3D, yang berfungsi seperti yang Anda jelaskan. Dan harus saya katakan, saya benci itu dengan hasrat.
Pendekatan "Segera" bekerja sangat baik dalam beberapa kasus. Pertama, ketika Anda hanya perlu beberapa tombol dan label - pikirkan penembak HUD, misalnya. Menciptakannya dengan pendekatan "tetap" tidak terlalu sulit, tetapi sangat mudah dengan UnityGUI. Kasus kedua adalah ketika Anda perlu banyak hal kontrol di layar, tetapi tidak terlalu peduli tentang tata letak. Terutama ketika kontrol yang tepat hanya diketahui saat runtime. Ini sebenarnya tidak berguna di game apa pun, tetapi sangat membantu saat membuat alat berjalan di dalam editor Unity.
Namun, setiap GUI setengah kompleks - untuk RPG (MMO) atau permainan strategi, misalnya - pasti akan berubah menjadi kekacauan kode kode yang tidak dapat diuraikan, penuh dengan kasus khusus dan memecah banyak cara. Saat membangun GUI seperti itu, Anda biasanya memiliki tata letak yang cukup spesifik yang harus bekerja untuk resolusi apa pun dan dapat menampilkan data apa pun yang Anda kirim. Anda memerlukan hal-hal seperti, misalnya, memindahkan beberapa tombol lebih rendah untuk memberi jalan pada teks yang lebih panjang. Dengan GUI "retained", Anda dapat memiliki kontrol yang melakukan itu secara otomatis. Dengan mode "langsung", tidak ada kontrol, jadi Anda harus melakukan semuanya secara eksplisit.
Masalah lain dengan UnityGUI (tidak yakin apakah itu terjadi pada semua GUI mode langsung) adalah bahwa, misalnya,
Button()
panggilan berfungsi tanpa mempertimbangkan panggilan GUI lainnya. Jadi, jika satu tombol di atas yang lain, satu klik akan menekan kedua tombol pada saat yang sama. Ini jelas bukan yang diharapkan pengguna, jadi ini menambahkan kasus khusus lain untuk ditangani.Untuk hidup dengan semua ini, saya selalu menulis bungkus saya sendiri di sekitar UnityGUI yang mengubahnya menjadi sistem mode "dipertahankan": kontrol yang menyimpan status mereka sendiri dan hanya memanggil
GUI
fungsi yang diperlukan setiap frame untuk saya.Saya tidak bisa mengatakan bahwa mode "langsung" jelas lebih buruk daripada "dipertahankan", tetapi saya tentu merasa jauh lebih baik bekerja dalam mode "tetap".
sumber
Saya akan membela IMGUI di sini karena beberapa masalah yang didaftar sebelumnya dapat diselesaikan jika Anda bersedia menulis kode untuk itu. Selain itu jika Anda menulis kode untuk itu, maka Anda memiliki perpustakaan yang kuat yang dapat digunakan kembali dan hanya sangat jarang membutuhkan modifikasi.
mungkin pada awalnya tampaknya seniman tidak memiliki banyak fleksibilitas dengan IMGUI, ini diselesaikan atau ditingkatkan dengan memuat tata letak GUI dari skema xml atau JSON.
masalah ini diselesaikan dengan pengurutan, Anda harus membuat kelas UI Manager yang mengurutkan urutan pengundian, saya memecahkan masalah ini dalam C # XNA dengan panel yang dapat dipindah-pindahkan dan dapat diklik yang menggambar di atas satu sama lain. Saya dapat memposting kode semu jika diminta.
dapatkah Anda menggambar string dari array? dapatkah Anda menentukan area persegi panjang dari tinggi dan lebar font string tersebut? dapatkah Anda membuat rasio ukuran tombol gulir Anda dengan ketinggian semua persegi panjang yang ditambahkan bersamaan? Kemudian Anda setengah jalan untuk membuat listbox dengan tombol yang dapat digulir untuk bergerak ke atas atau ke bawah. Saya pikir itu akan sulit, tetapi ternyata jauh lebih sederhana daripada yang saya kira. tidak ada buffer, tidak ada negara bagian, tidak ada panggilan balik yang terlibat.
jangan biarkan panel, tombol, kotak individual menyimpan data. Saya tahu bahwa pada upaya IMGUI pertama saya adalah langsung tetapi hanya dalam arti grafis. Saya membuat kesalahan dengan menyimpan data di UI. Itu hampir merupakan perubahan filosofis untuk berpikir secara berbeda di mana menempatkan dan memodifikasi data melalui perubahan UI.
ini adalah batas dan fungsionalitas kode SDK, bukan milikmu. Saya menemukan bahwa SDK UI (Hammer, Unity, UDK) hampir merupakan bahasa baru untuk dipelajari. Bahkan mereka mirip dengan saya sebagai Windows. Bentuknya, keduanya diatur untuk kemungkinan terluas dan karenanya memiliki bobot tambahan dalam kompleksitas.
dan terakhir tonton ini> http://mollyrocket.com/861
sumber
Itu tergantung pada genre dan game yang dimaksud. Sistem manajemen persediaan yang baik sangat penting untuk sebagian besar RPG. Anda akan menginginkan sesuatu yang menangani tata letak untuk Anda, mendukung bilah gulir, seret n 'drop, tooltips, dan fitur lainnya yang jauh lebih mudah diimplementasikan menggunakan Retained GUI.
Saya tidak bisa memikirkan cara untuk menyeret n 'drop dengan GUI langsung yang tidak memerlukan banyak juggling atau penghematan keadaan pengguna seperti mengubah buffer Z sementara dan menyimpan info waktu untuk mengesampingkan klik yang terjadi untuk memindahkan sebuah sedikit.
Tapi dari perspektif desain saya kesulitan membayangkan dunia tanpa acara GUI saya. Juga GUI Segera tidak kompatibel dengan OOP yang memaksa Anda menggunakan pemrograman prosedural.
Kesederhanaan yang diberikan oleh GUI langsung datang dengan biaya kompleksitas tambahan dalam kode Anda yang tumbuh dengan cepat seiring meningkatnya kompleksitas yang dibutuhkan oleh Anda UI; dimana sebagai GUI yang dipertahankan dengan baik pada awalnya lebih kompleks tetapi berskala lebih baik. Jadi di bawah titik kompleksitas tertentu, GUI langsung cukup tetapi untuk sebagian besar situasi saya lebih suka GUI yang dipertahankan.
sumber