Input polling vs event driven

19

Saya mengembangkan game menggunakan polling untuk metode input. Namun, sekarang saya sedang menggali lebih dalam ke menu game dan komponen UI lainnya, saya menemukan bahwa saya mungkin ingin memiliki input event driven. Mungkin bahkan memiliki keduanya, menggunakan event driven untuk UI dan polling untuk input "dunia". Saya ingin tahu apa cara terbaik untuk pergi.

Saya mendefinisikan polling sebagai: setiap loop pembaruan saya memeriksa tombol apa yang ditekan, di mana mouse berada, tombol ditekan, kemudian jalankan melalui mereka dan melakukan tindakan berdasarkan info yang dikumpulkan.

Saya mendefinisikan event driven sebagai: peristiwa berbasis interupsi, ketika suatu peristiwa terjadi dan interupsi dipicu dan blok kode dijalankan berdasarkan pada peristiwa tersebut.

Apakah Anda pikir yang terbaik adalah menjalankan semua acara, semua polling, atau kombinasi keduanya dapat diterima? Jika Anda memiliki pro dan kontra untuk keduanya, silakan daftarkan mereka. Terima kasih.

EDIT

Gim ini berbasis Java / OpenGL, jadi akan dirilis ke Windows / Mac / Linux. Kemungkinan memperluas itu ke perangkat seluler rendah. Permainan ini bergaya RTS, 3D orang ke-3.

EDIT 2

Saya masih tidak sepenuhnya senang dengan cara saya menerapkan ini, tapi apa yang saya tuju adalah menangkap peristiwa di UI saya dan jika mereka tidak ditangani oleh komponen UI saya, saya meneruskan acara tersebut ke "Dunia" untuk memilih / memilih. Sesuatu seperti:

@Override  
private boolean handleEvent(Event event) {  
    if(hud.handleEvent(event)) {  
        return true;  
    }  
    return WORLD.handleEvent(event);  
}

Dengan cara ini saya tidak mendapatkan klik bocor melalui UI untuk memilih objek di balik tombol dan apa yang tidak.

Saat ini kontrol kamera saya masih didasarkan pada polling, dan itu tampaknya berfungsi untuk saat ini, tetapi saya dapat memperbaruinya nanti.

Saya menghargai semua jawaban, maaf saya hanya bisa memilih satu!

MichaelHouse
sumber
6
Saya tidak yakin di Jawa, tetapi secara umum Anda selalu harus polling input. Anda kemudian dapat memposting peristiwa ketika hal-hal berubah, tetapi ini masih didasarkan pada sistem pemungutan suara.
James
Titik fokus yang paling relevan menurut saya adalah mendesain loop acara yang bebas dari segala macam layload selain dari pengumpulan input. Biarkan saya jelaskan: sistem operasi akan melakukan interupsi yang didorong input dan memperlakukannya di "utas masukan" global, maka OS-utas ini akan mengarahkan pesan ke aplikasi yang saat ini dalam fokus dan menulis intel ke dalam antrian pesannya. Antrian pesan harus disurvei oleh PeekMessage, atau GetMessage. Cara tercepat untuk mendapatkan ini adalah dengan menggunakan GetMessage dan biarkan penjadwal membangunkan Anda, Anda kemudian dapat mencatat waktu pesan dengan sangat tepat.
v.oddou

Jawaban:

17

Itu tergantung pada persyaratan gim dan perangkat keras Anda. Sebagian besar game biasanya tertarik pada perubahan pada kondisi input, yaitu pengguna menekan tombol api dan senjatanya mulai menembak, pengguna melepaskan kunci api dan senjatanya berhenti menembak, pengguna menekan tombol pindah dan mulai bergerak, melepaskan tombol bergerak dan berhenti bergerak , dll., sehingga sistem input yang digerakkan oleh peristiwa masuk akal dalam kasus-kasus tersebut karena informasi tersebut sudah dalam format yang sesuai. Plus di platform Windows, Anda sudah menerima acara untuk perubahan pada kondisi keyboard dan mouse, jadi sering kali konversi 1: 1 dari acara input tingkat rendah ke acara game tingkat tinggi. Dengan polling, Anda akan sering harus membuat acara seperti itu secara manual dengan membandingkan keadaan antara frame saat ini dan yang terakhir. Pada dasarnya, "tombol mana yang ditekan sekarang?"

Yang sedang berkata, pada platform tertentu Anda terjebak dengan jajak pendapat input pada tingkat rendah dan tidak ada cara di sekitar memeriksa sendiri tepi. Namun, saya selalu mencapai hasil terbaik menggunakan peristiwa untuk semua logika tingkat tinggi karena itu adalah bagaimana sistem cenderung beroperasi.

Skyler York
sumber
Terima kasih, saya telah memasukkan informasi tambahan tentang platform dan tujuan permainan.
MichaelHouse
1
Perhatikan bahwa GetAsyncKeyStateini adalah cara sederhana untuk menggunakan polling di Win32.
Macke
Derp, saya mengajukan pertanyaan dalam komentar Nate Bross yang Anda tangani di sini, jadi saya rasa saya akan memperbaikinya. Apakah semua PC menawarkan interupsi perangkat keras 1: 1 ke hubungan peristiwa keyboard OS, dan platform apa yang terbatas pada polling tingkat rendah?
michael.bartnett
@Macke: kadang-kadang antivirus melaporkan program yang menggunakan API ini karena mereka dapat menerima penekanan tombol dari seluruh sistem global, sehingga memungkinkan keylogging berbahaya. Artikel paling mengagumkan tentang hal itu di seluruh internet (saya tahu) adalah yang ini: securelist.com/analysis/publications/36358/…
v.oddou
7

Saya tidak melihat alasan bahwa Anda tidak dapat melakukan keduanya, dan mendapatkan yang terbaik dari kedua dunia.

Acara Input dihasilkan oleh polling (pada tingkat tertentu driver melakukan polling perangkat keras untuk melihat statusnya), dan karena loop utama Anda melakukan polling semua perangkat input, Anda dapat dengan mudah mengimplementasikan perangkat Anda sendiri. Sesuatu yang sederhana seperti di bawah ini adalah apa yang saya gunakan di masa lalu.

mouseInput = GetMouse();
kbInput = GetKeyboard();


// refactor this out to its own method if it makes sense
if menuState == Showing
    if mouseInput.LeftButton == State.Pressed
        LeftButton(mouseInput.X, mouseInput.Y)

// rest of game input code processing

void LeftButton(int x, int y)
{
    // left button event handler
}

Saya tahu bahwa Anda mendefinisikan acara sebagai interupsi dan apa yang saya taruh di sini bukan "benar-benar berdasarkan peristiwa", tapi saya tidak melihat apa yang di atas tidak memberi Anda bahwa interupsi memang memberi Anda - sebagian besar pengguna tidak akan melihat frame tunggal hilang, kecuali game Anda berjalan pada frame rate yang sangat rendah.

Nate
sumber
1
Saya ingin tahu tentang sifat mendapatkan input dari perangkat. Apakah acara keyboard dikirim oleh OS sebagai hasil polling di tingkat driver perangkat? Atau apakah acara keyboard sesuai dengan interupsi? Atau ada interupsi, tetapi OS mendukung mereka dan mengirimkannya jika dianggap cocok?
michael.bartnett
Saya tidak positif tentang cara kerjanya pada tingkat itu, tetapi ini paling mendasar, beberapa perangkat lunak berjalan dalam satu lingkaran dan memeriksa keadaan keyboard dan membandingkannya dengan keadaan sebelumnya, jika perubahannya maka perubahan akan menggelembung.
Nate
5

Ada dua masalah berbeda di sini:

  1. Bagaimana Anda membaca input pengguna dari OS / perangkat keras?

  2. Bagaimana Anda memproses input pengguna di mesin Anda?

Untuk membaca, itu jelas tergantung pada platform Anda, dan input apa yang ingin Anda baca. Perhatikan bahwa mudah untuk mengonversi satu hal ke hal lain di lapisan input Anda. (Yaitu jajak pendapat dan memancarkan acara ke mesin, atau mendengarkan acara dan memancarkan keadaan ke mesin.)

Untuk pemrosesan, ada beberapa opsi berbeda:

  • Untuk kontrol pergerakan pemain (dan skema serupa), pemungutan suara mungkin lebih sederhana karena Anda perlu menghitung ulang kecepatan setiap frame. Sangat mungkin bahwa loop batin Anda akan berbasis polling:

    yaitu sesuatu seperti speed += 1 if button.down else -1; clamp(speed, 0, 42);

  • Untuk acara terpisah (misil api, jeda permainan, teleport ke sisi lain planet), pemrosesan acara lebih disukai, jika tidak, kode Anda akan dikotori dengan maybeLaunchMissile(key_state);panggilan, dan itu hanya ... buruk, m'kay. ;)

Semoga ini bisa membantu.

Macke
sumber