Apakah mungkin untuk menggambarkan tata letak "optimal" (dalam hal kinerja) untuk loop permainan penggulung sisi 2D? Dalam konteks ini "loop game" mengambil input pengguna, memperbarui status objek game dan menggambar objek game.
Misalnya memiliki kelas dasar GameObject dengan hierarki warisan yang dalam bisa bagus untuk pemeliharaan ... Anda dapat melakukan sesuatu seperti berikut:
foreach(GameObject g in gameObjects) g.update();
Namun saya pikir pendekatan ini dapat menciptakan masalah kinerja.
Di sisi lain, semua data dan fungsi objek game bisa bersifat global. Yang akan menjadi sakit kepala pemeliharaan tetapi mungkin lebih dekat ke loop game yang berkinerja optimal.
Adakah pikiran? Saya tertarik pada aplikasi praktis dari struktur loop game yang hampir optimal ... bahkan jika saya mendapatkan sakit kepala pemeliharaan dengan imbalan kinerja yang luar biasa.
sumber
Jawaban:
Sebenarnya, hierarki yang dalam umumnya lebih buruk untuk perawatan daripada yang dangkal, dan gaya arsitektur modern untuk objek game cenderung mengarah ke pendekatan berbasis agregasi yang dangkal .
Loop yang Anda tunjukkan berpotensi memiliki masalah kinerja, tetapi tidak, seperti yang tersirat oleh pernyataan Anda selanjutnya, karena Anda memiliki data instan dan fungsi anggota di
GameObject
kelas. Alih-alih, masalahnya adalah Anda jika Anda memperlakukan setiap objek dalam game sama persis, Anda mungkin tidak mengelompokkan objek-objek tersebut secara cerdas - mereka kemungkinan tersebar secara acak di seluruh daftar itu. Maka, berpotensi setiap panggilan ke metode pembaruan untuk objek itu (apakah metode itu adalah fungsi global atau tidak, dan apakah objek memiliki data contoh atau "data global" yang melayang-layang di beberapa tabel tempat Anda mengindeks atau apa pun) berbeda dari panggilan pembaruan di iterasi loop terakhir.Ini dapat menambah tekanan pada sistem karena Anda mungkin perlu halaman memori dengan fungsi yang relevan masuk dan keluar dari memori dan mengisi ulang cache instruksi lebih sering, menghasilkan loop yang lebih lambat. Apakah ini dapat diamati atau tidak dengan mata telanjang (atau bahkan dalam profiler) tergantung pada apa yang dianggap sebagai "objek game", berapa banyak dari mereka yang ada rata-rata, dan apa lagi yang terjadi dalam aplikasi Anda.
Sistem objek berorientasi komponen adalah tren populer saat ini, memanfaatkan filosofi bahwa agregasi lebih disukai daripada warisan . Sistem seperti itu berpotensi memungkinkan Anda untuk membagi "perbarui" logika komponen (di mana "komponen" secara kasar didefinisikan sebagai beberapa unit fungsi, seperti benda yang mewakili bagian yang disimulasikan secara fisik dari beberapa objek, yang diproses oleh sistem fisika ) ke beberapa utas - dibedakan berdasarkan jenis komponen - jika mungkin dan diinginkan, yang dapat memperoleh peningkatan kinerja. Paling tidak Anda dapat mengatur komponen sedemikian rupa sehingga semua komponen dari pembaruan jenis yang diberikan bersama , memanfaatkan cache CPU secara optimal. Contoh dari sistem berorientasi komponen seperti itu dibahas dalam utas ini .
Sistem seperti ini seringkali sangat terpisah, yang merupakan keuntungan bagi pemeliharaan juga.
Desain berorientasi data adalah pendekatan terkait - ini tentang mengarahkan diri Anda di sekitar data yang dibutuhkan objek sebagai prioritas pertama, sehingga data dapat diproses secara efektif dalam jumlah besar (misalnya). Ini umumnya berarti organisasi yang mencoba untuk menjaga data yang digunakan untuk cluster tujuan yang sama bersama-sama dan dioperasikan sekaligus. Ini pada dasarnya tidak kompatibel dengan desain OO, dan Anda dapat menemukan beberapa obrolan tentang masalah ini di sini di GDSE dalam pertanyaan ini .
Akibatnya, pendekatan yang lebih optimal untuk loop game akan, bukan yang asli Anda
sesuatu yang lebih seperti
Dalam dunia seperti itu, masing-masing
GameObject
mungkin memiliki pointer atau referensi sendiriPhysicsData
atauScript
atauRenderData
, untuk kasus-kasus di mana Anda mungkin perlu untuk berinteraksi dengan objek secara individual, tetapi sebenarnyaPhysicsData
,Scripts
,RenderData
, dan sebagainya semua akan dimiliki oleh subsistem masing-masing (simulator fisika, lingkungan hosting skrip, renderer) dan diproses secara massal seperti yang ditunjukkan di atas.Sangat penting untuk dicatat bahwa pendekatan ini bukan peluru ajaib dan tidak akan selalu menghasilkan peningkatan kinerja (meskipun umumnya desain yang lebih baik daripada pohon warisan yang mendalam). Pada dasarnya Anda mungkin akan melihat pada dasarnya tidak ada perbedaan kinerja jika Anda memiliki sangat sedikit objek, atau sangat banyak objek yang tidak dapat Anda pisahkan dengan pembaruan secara efektif.
Sayangnya, tidak ada loop ajaib seperti itu yang paling optimal - setiap permainan berbeda dan mungkin memerlukan penyetelan kinerja dengan cara yang berbeda. Jadi sangat penting untuk mengukur (profil) hal-hal sebelum Anda secara membabi buta mengambil saran dari beberapa pria acak di internet.
sumber
Gaya pemrograman game-objek baik-baik saja untuk proyek yang lebih kecil. Ketika proyek menjadi sangat besar Anda akan berakhir dengan hierarki warisan yang mendalam dan basis game-objek akan menjadi sangat berat!
Sebagai contoh ... Misalkan Anda mulai membuat basis objek-Game dengan atribut minimum mengatakan Posisi (untuk x dan y), displayObject (ini merujuk pada gambar jika elemen gambarnya), lebar, tinggi dll ...
Sekarang nanti jika kita perlu menambahkan sub kelas yang akan memiliki status animasi, maka Anda mungkin memindahkan 'kode kontrol animasi' (katakanlah CurrentAnimationId, Jumlah frame untuk animasi ini, dll.) Ke GameObjectBase dengan anggapan bahwa sebagian besar objek akan memiliki animasi.
Nanti jika Anda ingin menambahkan tubuh kaku yang statis (tidak memiliki animasi apa pun), Anda perlu memeriksa 'kode kendali animasi' di fungsi pembaruan GameObject Base (walaupun ada tanda centang apakah animasi ada atau tidak. ..itu penting!) Bertentangan dengan ini jika Anda mengikuti Struktur berbasis Komponen, Anda akan memiliki 'Komponen Kontrol animasi' yang melekat pada objek Anda. Jika diperlukan Anda akan melampirkannya. Untuk tubuh statis Anda tidak akan memasang komponen itu. Ini cara, kita dapat menghindari pemeriksaan yang tidak perlu.
Jadi, pemilihan memilih gaya tergantung pada ukuran proyek. Struktur objek Game hanya mudah dikuasai untuk proyek yang lebih kecil. Semoga ini bisa membantu sedikit.
sumber