Catatan: Saya harus melakukan polling, daripada melakukan panggilan balik karena keterbatasan API (SFML). Saya juga minta maaf karena kurangnya judul yang 'layak'.
Saya pikir saya punya dua pertanyaan di sini; cara mendaftar input yang saya terima, dan apa yang harus dilakukan dengannya.
Menangani Input
Saya sedang berbicara tentang fakta bahwa Anda telah mendaftarkan bahwa tombol 'A' telah ditekan, misalnya, dan bagaimana melakukannya dari sana.
Saya telah melihat array seluruh keyboard, seperti:
bool keyboard[256]; //And each input loop check the state of every key on the keyboard
Tetapi ini tampaknya tidak efisien. Anda tidak hanya menyambungkan kunci 'A' ke 'pemain bergerak ke kiri', misalnya, tetapi memeriksa setiap kunci, 30-60 kali per detik.
Saya kemudian mencoba sistem lain yang hanya mencari kunci yang diinginkan.
std::map< unsigned char, Key> keyMap; //Key stores the keycode, and whether it's been pressed. Then, I declare a load of const unsigned char called 'Quit' or 'PlayerLeft'.
input->BindKey(Keys::PlayerLeft, KeyCode::A); //so now you can check if PlayerLeft, rather than if A.
Namun, masalah dengan ini adalah saya sekarang tidak bisa mengetik nama, misalnya, tanpa harus mengikat setiap kunci.
Lalu, saya memiliki masalah kedua, yang saya tidak bisa memikirkan solusi yang baik untuk:
Mengirim Input
Saya sekarang tahu bahwa tombol A telah ditekan atau bahwa playerLeft benar. Tetapi bagaimana saya pergi dari sini?
Saya berpikir untuk mengecek
if(input->IsKeyDown(Key::PlayerLeft) { player.MoveLeft(); }
input pasangan ini sangat ke entitas, dan saya merasa agak berantakan. Saya lebih suka pemain untuk menangani gerakannya sendiri ketika diperbarui. Saya pikir beberapa jenis sistem acara bisa berfungsi, tetapi saya tidak tahu bagaimana caranya. (Saya mendengar sinyal dan slot bagus untuk pekerjaan semacam ini, tetapi tampaknya sangat lambat dan saya tidak bisa melihat bagaimana itu cocok).
Terima kasih.
sumber
Saya pikir diskusi OP menyatukan banyak hal, dan masalahnya dapat disederhanakan secara substansial dengan memecahnya sedikit.
Saran saya:
Pertahankan susunan status kunci Anda. Apakah tidak ada panggilan API untuk mendapatkan seluruh kondisi keyboard sekaligus? (Sebagian besar pekerjaan saya adalah pada konsol, dan bahkan pada Windows untuk pengontrol yang terhubung Anda mendapatkan seluruh status pengontrol sekaligus.) Keadaan kunci Anda adalah peta "keras" pada tombol-tombol keyboard. Tidak diterjemahkan adalah yang terbaik, tetapi bagaimanapun Anda membuatnya termudah keluar dari API.
Kemudian simpan beberapa array paralel yang menunjukkan apakah kunci naik bingkai ini, yang lain menunjukkan bahwa itu turun, dan yang ketiga menunjukkan hanya bahwa kunci itu "turun". Mungkin melempar timer sehingga Anda dapat melacak berapa lama kunci telah dalam kondisi saat ini.
Selanjutnya buat metode untuk membuat pemetaan kunci untuk tindakan. Anda akan ingin melakukan ini beberapa kali. Satu kali untuk hal-hal UI (dan berhati-hatilah untuk menanyakan pemetaan Windows karena Anda tidak dapat menganggap scancode ketika Anda menekan 'A' akan memberikan nilai A pada komputer pengguna). Lain untuk setiap "mode" dalam game. Ini adalah pemetaan kode kunci untuk tindakan. Anda dapat melakukan ini dengan beberapa cara, satu untuk menjaga enum yang digunakan oleh sistem penerima, yang lain akan menjadi penunjuk fungsi yang menunjukkan fungsi yang akan dipanggil pada perubahan keadaan. Mungkin bahkan hibrida dari keduanya, tergantung pada tujuan dan kebutuhan Anda. Dengan "mode" ini, Anda dapat mendorong dan memasukkannya ke tumpukan mode pengontrol, dengan tanda yang memungkinkan input yang diabaikan untuk terus turun ke tumpukan atau apa pun.
Akhirnya, tangani tindakan-tindakan kunci itu entah bagaimana. Untuk gerakan, Anda mungkin ingin melakukan sesuatu yang rumit, menerjemahkan 'W' ke bawah berarti "bergerak maju," tetapi itu tidak perlu menjadi solusi biner; Anda dapat memiliki "W is down" berarti "meningkatkan kecepatan dengan X sampai maksimum Y," dan "W is up" menjadi "menurunkan kecepatan oleh Z sampai menyentuh nol." Secara umum - Anda ingin "antarmuka penanganan pengontrol dalam sistem permainan" Anda menjadi sangat sempit; lakukan semua terjemahan kunci di satu tempat dan kemudian gunakan hasil itu di tempat lain. Ini berbeda dengan memeriksa secara langsung untuk melihat apakah bilah spasi ditekan di sembarang tempat dalam kode, karena jika itu di beberapa tempat acak mungkin akan terkena pada waktu acak ketika Anda tidak menginginkannya, dan Anda tidak Aku tidak mau berurusan dengan itu ...
Saya benar-benar benci merancang pola dan saya pikir komponen membawa lebih banyak biaya pengembangan daripada yang baik, jadi itu sebabnya saya tidak menyebutkan keduanya. Pola akan muncul jika ditakdirkan untuk, seperti halnya komponen, tetapi berangkat untuk melakukan keduanya sejak awal hanya akan mempersulit hidup Anda.
sumber
Di SFML, Anda memiliki tombol secara berurutan sesuai dengan jenis peristiwa KeyPressed. Anda memproses setiap kunci dalam beberapa saat (getNextEvent ()).
Jadi jika tombol yang ditekan ada di peta Key-> Action Anda, jalankan tindakan yang sesuai, dan jika tidak, teruskan ke widget / hal-hal yang mungkin membutuhkannya.
Mengenai pertanyaan kedua Anda, saya sarankan Anda untuk tetap seperti ini karena membuatnya lebih mudah untuk mengubah gameplay Anda. Jika Anda menggunakan sinyal atau semacamnya, Anda harus membuat slot untuk "RunKeyDown" dan yang lainnya untuk "JumpKeySlot". Tetapi apa yang terjadi jika dalam gim Anda, tindakan khusus dilakukan ketika keduanya ditekan?
Jika Anda ingin menghubungkan input dan entitas, Anda dapat menjadikan input Anda sebagai Status (RunKey = true, FireKey = false, ...) dan mengirimkannya ke pemain seperti Anda mengirim acara lain ke AI Anda.
sumber
Solusi yang tepat seringkali merupakan kombinasi dari dua metode yang Anda diskusikan:
Untuk fungsionalitas gameplay dengan seperangkat tombol yang telah ditentukan, polling setiap frame benar-benar tepat dan Anda hanya harus polling untuk kunci yang benar-benar terikat pada sesuatu. Ini sebenarnya analog dengan bagaimana Anda akan meminta input controller dalam game konsol, itu akan sepenuhnya polling terutama ketika datang ke perangkat input analog. Selama bermain game umum, Anda mungkin ingin mengabaikan acara penekanan tombol dan cukup gunakan polling.
Saat mengetik input untuk hal-hal seperti nama, Anda harus mengalihkan game ke mode penanganan input yang berbeda. Misalnya, segera setelah prompt "masukkan nama Anda" muncul, Anda dapat mengubah apa yang Anda lakukan dengan kode input. Itu bisa mendengarkan acara pers kunci melalui beberapa antarmuka panggilan balik, atau Anda dapat mulai polling untuk setiap tombol jika diperlukan. Ternyata biasanya selama acara mengetik Anda tidak terlalu peduli dengan kinerja, jadi pemungutan suara tidak akan seburuk itu.
Jadi, Anda ingin menggunakan polling selektif untuk input gameplay, dan penanganan event untuk input mengetik nama (atau semua polling keyboard jika penanganan event tidak tersedia).
sumber
Saya sangat menyukai jawaban dash-tom-bang, itu benar-benar menyoroti beberapa aspek yang harus Anda ingat ketika merancang sistem input.
Saya ingin menambahkan sedikit tutorial yang saya temukan yang mengarah ke arah yang sama (termasuk konteks input, 3 layer, ...):
http://www.gamedev.net/blog/355/entry-2250186-designing-a-robust-input-handling-system-for-games/
sumber