[Mem-posting ulang pertanyaan ini dari stackoverflow, seperti yang ditunjukkan lebih cocok di sini.]
Saya saat ini porting mesin gim 2D saya ke Jawa. Saya melihat beberapa perpustakaan permainan yang ditunjukkan di sini di stackoverflow. Namun, yang saya lihat agak sederhana dan bahkan tidak menyatakan jika mereka mendukung hal-hal seperti transparansi alpha, jadi saya memutuskan untuk port render C ++ saya yang sudah saya tuliskan logikanya.
Renderer ini adalah renderer perangkat lunak murni yang menggunakan ubin untuk menghindari rendering ulang yang tidak perlu. Saya mengoptimalkan kinerja penggulirannya dengan membuat "buffer layar" yang sedikit lebih besar dari panel output saya, dan menyaring buffer layar ini ke output saya di setiap frame. Dengan cara ini, saya bisa menghindari menggambar ubin dengan sia-sia hanya karena saya menggulir piksel pada peta.
Saya menggunakan AWT Java untuk mengimplementasikannya, menggunakan BufferedImage besar untuk buffer offscreen. Penggunaan CPU baik-baik saja (sekitar dua kali lipat dari yang saya miliki di C ++), tetapi ada masalah aneh dengan pengguliran terus-menerus, di mana setiap detik atau lebih, renderer akan tertinggal sekitar 0,2 detik.
Karena tidak ada apa pun dalam kode saya yang akan terjadi pada periode ini, dan karena lonjakan hilang jika saya tidak menarik buffer layar saya ke tampilan utama, saya hanya dapat menyimpulkan bahwa Java melakukan beberapa optimasi internal sendiri. Namun, saya tidak yakin apa fungsinya, saya juga tidak tahu mana dari optimasi saya sendiri yang harus saya hapus untuk menyingkirkan paku. Juga, mungkin java AWT tidak dibuat dengan pengguliran FPS yang berkelanjutan dan tinggi, dan itu sama sekali tidak dapat digunakan untuk tujuan ini.
Apakah ada cara bagi saya untuk menyingkirkan paku ini?
Jawaban:
Meskipun saya tidak bisa memastikan tanpa melihat kode Anda, sepertinya masalah Anda adalah pengumpul sampah. Di Jawa, Anda memiliki pengumpulan sampah besar dan kecil yang terjadi setiap saat. Minor menggunakan beberapa cpu Anda, tetapi tidak akan terlalu banyak mengganggu Anda. Koleksi utama dapat menjadi masalah nyata untuk aplikasi waktu nyata seperti game karena mereka benar-benar akan menjeda semuanya saat sedang berjalan.
Ada dua opsi untuk menyelesaikan ini. Pertama, Anda dapat men-tweak JVM untuk memastikan koleksi kurang besar terjadi. Kedua (dan disarankan), Anda dapat memastikan Anda tidak meninggalkan terlalu banyak sampah. Cukup periksa di mana di aplikasi Anda, Anda membuat banyak objek (dalam game saya itu biasanya kelas vektor3) dan pastikan Anda menggunakannya kembali sebanyak mungkin (terutama di loop batin dll).
sumber
Iya.
Untuk game berbasis sprite 2D, AWT dapat digunakan untuk menangani rendering dengan efek besar. Bahkan dapat dipercepat perangkat keras , tergantung pada perangkat keras yang tersedia.
Tanpa kode atau cuplikan profil yang terperinci, sulit untuk mengatakan apa masalahnya. Yang terbaik yang bisa saya lakukan adalah menawarkan beberapa tips dasar untuk bekerja dengan Java dan AWT ketika membangun game.
Bekerja dengan Pengumpul Sampah
GC di Jawa adalah sesuatu yang harus kita ingat ketika kita sedang membangun game kita. Ini akan berjalan secara berkala dan mencari objek yang tidak memiliki referensi kepada mereka, dan menghapusnya dari memori. Proses penghapusan ini lambat dan kemungkinan merupakan penyebab hitching yang Anda alami.
Saran saya adalah untuk menghindari membuat referensi objek yang tidak akan disimpan selama eksekusi (atau setidaknya, sebanyak mungkin). Tujuan yang ideal adalah untuk memastikan bahwa GC tidak memiliki sesuatu untuk dilakukan setiap kali ia berjalan.
Dalam praktiknya, Anda mungkin berakhir dengan banyak variabel statis yang Anda gunakan kembali sepanjang permainan. Berikut adalah contoh yang sangat dibuat-buat tentang bagaimana saya cenderung menghadapinya:
Selama memuat layar adalah tempat Anda dapat menumbuhkan atau mengecilkan
Map
instance Anda menggunakannew
kata kunci. Tetapi selama bermain, Anda harus menghindari itu sebanyak mungkin. Jika ada sesuatu yang hancur saat bermain, atur bendera pada objek sehingga Anda tahu itu bukan sesuatu yang sedang aktif. Jika Anda perlu menelurkan objek baru, telusuri objek AndaMap
hingga Anda menemukan yang tidak aktif, dan atur properti itu dan tandai sebagai aktif.Ini adalah sesuatu yang Anda harus ingat ketika menggunakan Java untuk aplikasi yang sensitif terhadap kinerja terlepas dari apakah Anda menggunakan AWT, JavaFX, atau OpenGL untuk melakukan rendering.
Kanvas
Khususnya untuk AWT, saya sangat merekomendasikan menggunakan kelas Canvas untuk merender semuanya dengan berbagai alasan:
sumber