Disclamer: Saya tahu apa pola sistem entitas dan saya tidak menggunakannya.
Saya telah membaca banyak tentang memisahkan objek dan rendering. Tentang fakta bahwa logika permainan harus independen dari mesin rendering yang mendasarinya. Itu semua bagus dan keren dan itu masuk akal, tetapi itu menyebabkan banyak kesakitan lainnya juga:
- perlu untuk sinkronisasi antara objek logika dan objek rendering (salah satu yang membuat keadaan animasi, sprite dll)
- perlu membuka objek logika kepada publik agar objek rendering membaca keadaan aktual objek logika (sering mengarahkan objek logika untuk dengan mudah mentransformasikannya menjadi objek pengambil dan penyetel bodoh)
Ini kedengarannya bukan solusi yang baik untuk saya. Di sisi lain, sangat intuitif untuk membayangkan objek sebagai representasi 3d (atau 2d) dan juga sangat mudah untuk dipelihara (dan mungkin jauh lebih dienkapsulasi juga).
Apakah ada cara untuk mempertahankan representasi grafis dan logika game yang digabungkan bersama (menghindari masalah sinkronisasi) tetapi memisahkan mesin rendering? Atau adakah cara untuk memisahkan logika game dan rendering yang tidak menyebabkan kelemahan di atas?
(mungkin dengan contoh, saya tidak pandai memahami pembicaraan abstrak)
sumber
Jawaban:
Misalkan Anda memiliki adegan yang terdiri dari dunia , pemain , dan bos. Oh, dan ini adalah permainan orang ketiga, jadi Anda juga memiliki kamera .
Jadi adegan Anda terlihat seperti ini:
(Setidaknya, itulah data dasar . Bagaimana Anda menyimpan data, terserah Anda.)
Anda hanya ingin memperbarui dan membuat adegan ketika Anda memainkan game, bukan ketika dijeda, atau di menu utama ... sehingga Anda melampirkannya ke status permainan!
Sekarang kondisi permainan Anda memiliki heboh. Selanjutnya, Anda ingin menjalankan logika di tempat kejadian, dan membuat adegan. Untuk logika, Anda hanya menjalankan fungsi pembaruan.
Dengan begitu Anda bisa menyimpan semua logika game di
Scene
kelas. Dan hanya untuk referensi, sistem komponen entitas dapat melakukannya seperti ini sebagai gantinya:Ngomong-ngomong, kini Anda berhasil memperbarui adegan Anda. Sekarang Anda ingin menampilkannya! Untuk itu kami melakukan sesuatu yang mirip dengan di atas:
Ini dia. Sistem render membaca informasi dari tempat kejadian, dan menampilkan gambar yang sesuai. Sederhana, metode untuk rendering adegan mungkin terlihat seperti ini:
Sangat sederhana, Anda masih perlu, misalnya, menerapkan rotasi dan terjemahan berdasarkan di mana pemain Anda berada dan di mana dia melihat. (Contoh saya adalah game 3D, jika Anda menggunakan 2D, itu akan menjadi jalan-jalan di taman).
Saya harap ini yang Anda cari? Seperti yang mudah-mudahan dapat Anda ingat dari hal di atas, sistem render tidak peduli dengan logika permainan . Itu hanya menggunakan keadaan saat ini adegan untuk membuat, yaitu itu menarik informasi yang diperlukan darinya, untuk membuat. Dan logika game? Tidak peduli apa yang dilakukan penyaji. Heck, tidak peduli apakah itu ditampilkan sama sekali!
Dan Anda tidak perlu melampirkan informasi render ke tempat kejadian juga. Seharusnya cukup bahwa pemberi render tahu perlu membuat sebuah orc. Anda sudah memuat model orc, yang kemudian ditampilkan oleh renderer untuk ditampilkan.
Ini harus memenuhi persyaratan Anda. Representasi grafis dan logika digabungkan , karena keduanya menggunakan data yang sama. Namun mereka terpisah , karena tidak ada yang bergantung pada yang lain!
EDIT: Dan hanya untuk menjawab mengapa orang melakukannya seperti ini? Karena lebih mudah adalah alasan paling sederhana. Anda tidak perlu memikirkan "ini dan itu terjadi, sekarang saya harus memperbarui grafik". Alih-alih Anda membuat hal-hal terjadi, dan setiap bingkai permainan melihat apa yang sedang terjadi, dan menafsirkannya dengan cara tertentu, memberi Anda hasil di layar.
sumber
Judul Anda menanyakan pertanyaan yang berbeda dari konten tubuh Anda. Dalam judul, Anda bertanya mengapa logika dan rendering harus dipisahkan, tetapi di dalam tubuh Anda meminta implementasi sistem logika / grafik / rendering.
Pertanyaan kedua telah diatasi sebelumnya , jadi saya akan fokus pada pertanyaan pertama.
Alasan untuk memisahkan logika dan rendering:
Dalam pengaturan OOP instantiating objek baru memiliki biaya, tetapi dalam pengalaman saya biaya untuk sumber daya sistem adalah harga kecil untuk membayar kemampuan untuk memikirkan dan mengimplementasikan hal-hal spesifik yang perlu saya lakukan.
sumber
Jawaban ini hanya untuk membangun intuisi mengapa pemisahan rendering dan logika itu penting, daripada langsung menyarankan contoh-contoh praktis.
Anggaplah kita memiliki seekor gajah besar , tidak ada seorang pun di ruangan itu yang dapat melihat seluruh gajah. mungkin semua orang bahkan tidak setuju tentang apa itu sebenarnya. Karena semua orang melihat bagian yang berbeda dari gajah dan hanya bisa berurusan dengan bagian itu. Tetapi pada akhirnya ini tidak mengubah fakta bahwa itu adalah gajah yang besar.
Gajah mewakili objek permainan dengan semua perinciannya. Tapi tidak ada yang benar-benar perlu tahu segalanya tentang gajah (objek game) untuk dapat melakukan fungsinya.
Menggabungkan logika game dan rendering sebenarnya seperti membuat semua orang melihat seluruh gajah. Jika sesuatu berubah, semua orang perlu mengetahuinya. Sementara dalam kebanyakan kasus mereka hanya perlu melihat bagian yang mereka hanya tertarik. Jika sesuatu mengubah orang yang tahu tentang hal itu, hanya perlu memberi tahu orang lain tentang hasil dari perubahan itu, itulah yang hanya penting baginya (anggap ini sebagai komunikasi melalui pesan atau antarmuka).
Poin yang Anda sebutkan bukan drawback, mereka hanya drawback jika ada lebih banyak ketergantungan daripada yang seharusnya ada di mesin, dengan kata lain, sistem melihat bagian gajah lebih dari yang seharusnya. Dan ini berarti mesinnya tidak dirancang dengan "benar".
Anda hanya perlu sinkronisasi dengan definisi formal itu jika Anda menggunakan mesin multi-threaded di mana ia menempatkan logika dan rendering dalam dua utas yang berbeda, dan bahkan mesin yang membutuhkan banyak sinkronisasi antara sistem tidak terlalu banyak dirancang.
Kalau tidak, cara alami untuk menangani kasus tersebut, adalah merancang sistem sebagai input / output. Pembaruan melakukan logika dan menampilkan hasilnya. Rendering hanya umpan dengan hasil dari pembaruan. Anda tidak perlu mengungkapkan semuanya. Anda hanya mengekspos Antarmuka yang berkomunikasi antara dua tahap. Komunikasi antara berbagai bagian mesin harus melalui abstraksi (antarmuka) dan / atau pesan. Tidak ada logika atau keadaan internal yang harus diekspos.
Mari kita ambil contoh grafik adegan sederhana untuk menjelaskan ide tersebut.
Pembaruan biasanya dilakukan melalui satu loop yang disebut loop game (atau mungkin melalui beberapa loop game, masing-masing berjalan di utas terpisah). Setelah loop diperbarui objek game yang pernah ada. Hanya perlu memberi tahu melalui pesan atau antarmuka yang objek 1 dan 2 di mana diperbarui dan memberi makan dengan transformasi akhir.
Sistem rendering hanya mengambil transformasi akhir dan tidak tahu apa yang sebenarnya berubah tentang objek (misalnya tabrakan spesifik terjadi dll). Sekarang untuk membuat objek itu hanya perlu ID objek itu dan transformasi akhir. Setelah itu pemberi render akan memberi makan api rendering dengan mesh dan transformasi akhir tanpa mengetahui hal lain.
sumber