Pemrograman game Java 2D: Berbagai pendekatan untuk membuat lingkaran game

10

Saya baru mengenal pemrograman game Java, tetapi semakin saya membaca semakin saya bingung, karena saya telah melihat beberapa pendekatan berbeda untuk membuat loop game: 1. Pendekatan standar, yang menggunakan kelas Timer (tampaknya kurang tepat). 2. Pendekatan yang lebih tepat yang menggunakan System.nanoTime. 3. Pendekatan sederhana yang menggunakan scheduleAtFixedRate.

Yang mana yang secara umum lebih disukai dan di mana keuntungan / kerugian dari setiap pendekatan? Terima kasih sebelumnya atas info apa pun.

pengguna1812379
sumber

Jawaban:

7

Untuk loop game dasar, Anda akan menjalankan loop sementara, di mana Anda akan mendapatkan waktu menggunakan nanoTime (), tentukan berapa banyak waktu yang telah berlalu sejak frame terakhir, kemudian perbarui gamestate dan render Anda.

Dengan menggunakan http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/System.html#nanoTime%28%29 , Anda dapat melakukan polling untuk waktu yang telah berlalu. Pada dasarnya ...

public static void main(String [ ] args)
{
    long current_frame_time = system.nanoTime();
    long last_frame_time = current_frame_time;

    while(gameIsRunning)
    {
        last_frame_time = current_frame_time;
        current_frame_time = system.nanoTime();

        long timeTaken = current_frame_time - last_frame_time;

        //update and render game here
    }
}

Metode dasar ini dapat diperbaiki, misalnya http://www.koonsolo.com/news/dewitters-gameloop/ dan http://gafferongames.com/game-physics/fix-your-timestep/ .

Atau, Anda dapat membuat timer dan mengatur timer ini untuk menjalankan pembaruan Anda dan merender setiap X milidetik. Tapi, ada beberapa kerugian untuk membangun gameloop seperti itu.

Menurut http://docs.oracle.com/javase/1.5.0/docs/api/java/util/Timer.html : " Sesuai dengan masing-masing objek Timer adalah utas latar belakang tunggal yang digunakan untuk mengeksekusi semua timer. tugas, secara berurutan, tugas Timer harus diselesaikan dengan cepat. Jika tugas timer membutuhkan waktu yang berlebihan untuk menyelesaikan, itu "babi" utas pelaksanaan tugas timer. Ini dapat, pada gilirannya, menunda pelaksanaan tugas berikutnya, yang mungkin "berkumpul" dan mengeksekusi dalam suksesi cepat ketika (dan jika) tugas yang menyinggung akhirnya selesai. "

Menurut http://docs.oracle.com/javase/1.5.0/docs/api/java/util/Timer.html#scheduleAtFixedRate%28java.util.TimerTask,%20java.util.Date , % 20long%29 : " Dalam eksekusi tarif tetap, setiap eksekusi dijadwalkan relatif terhadap waktu eksekusi dijadwalkan pada eksekusi awal. Jika eksekusi ditunda karena alasan apa pun (seperti pengumpulan sampah atau kegiatan latar belakang lainnya), dua eksekusi atau lebih akan terjadi dalam suksesi cepat untuk "mengejar ketinggalan." Dalam jangka panjang, frekuensi eksekusi akan persis kebalikan dari periode yang ditentukan (dengan asumsi jam sistem yang mendasari Object.wait (lama) akurat). "

Karena Anda biasanya tidak tahu sebelumnya berapa lama loop game, mengatur timer untuk mengeksekusi gameloop Anda setiap X milidetik (tergantung pada frame rate target) dapat menyebabkan beberapa frame berkumpul, yang akan dieksekusi setiap kali frame berada selesai bukan saat bingkai dijadwalkan. Ketika itu terjadi ... mengapa menggunakan timer?

Sekarang, jangan salah paham, timer bukan kelas yang buruk, tetapi biasanya lebih cocok untuk tugas-tugas kecil yang perlu dilakukan secara berkala atau pada waktu tertentu, misalnya klien email mungkin ingin memeriksa email baru setiap 5 menit, atau penghitung dapat dikurangi setiap detik untuk menampilkan hitungan mundur sebelum dimulainya perlombaan.

Exilyth
sumber
Pertanyaannya adalah tentang loop game sehingga informasi awt / swing di luar topik. Namun sepertinya informasi itu relevan karena garis yang tidak relevan dan membingungkan dalam pertanyaan, jadi saya menghapusnya.
jhocking
Saya mengadaptasi jawaban saya untuk mencerminkan perubahan yang dibuat pada pertanyaan.
Exilyth
7

Saya tidak akan meletakkan loop utama di timer. Sebaliknya saya akan membuat 'while' loop yang memproses setiap frame dan kemudian menggunakan semacam fungsi ketepatan waktu (kedengarannya seperti di Jawa yang akan menjadi System.nanoTime) untuk menghitung berapa banyak waktu yang telah berlalu sejak frame terakhir / iterasi terakhir dari lingkaran.

Bahasa-bahasa tertentu adalah pengecualian di sini (mis. JavaScript, ActionScript) karena bahasa-bahasa tersebut beroperasi dalam lingkungan yang memiliki loop utama implisit untuk dihubungkan ke (misalnya browser, Flash Player) tetapi pengecualian itu tidak berlaku untuk Java.

jhocking
sumber