-
24/06/12
tugas softskill translate chapter 5 "the keyboard"
Bab 5. User input
"Jika terus, manusia akan berevolusi dan kehilangan semua jarinya, kecuali jari untuk menekan tombol."
-Frank Lloyd Wright
KUNCI TOPIK
- Keyboard
- mouse
- Joystick
- Hardware Abstraction
- Angkatan Saran atau masukan
- Penutupan
Sebuah model interaksi pengguna yang dasar adalah kunci untuk setiap permainan yang baik. Tanpa mekanisme input pengguna yang memadai,gameplay menjadi terhambat dan frustrasi terjadi. Dalam bab ini, kita akan membahas dasar-dasar kontrol user input. Sayangnya, akan ada beberapa aturan umum. Interaksi pengguna terjadi pada pada tingkat abstraksi yang relatif rendah, dan implementasi cenderung mengarah pada hardware. Bila memungkinkan,teknik umumlah yang kemungkinan dipakai. Tapi sebagian besar bab ini dikhususkan untuk metode input khusus yang tersedia untuk platform populer pada PC, seperti Win32 API dan Microsoft DirectInput.
Keyboard
Keyboard adalah perangkat input utama untuk PC berbasis permainan, tetapi juga tersedia untuk ponsel, beberapa
consol, dan palm device. itu semua perangkat input yang sering dipakai dan yang paling banyak tersedia. sarangnya User Input(perangkat input) yang populer tersebut tidak terlalu cocok untuk Game.
Pemetaan Keyboard mengambil waktu untuk belajar, dan ide umum dari keyboard adalah sama sekali tidak praktis untuk anak-anak.Menjadi perangkat multifungsi yang dapat digunakan untuk mengetik dokumen dan untuk bermain game, tidak mengherankan bahwa keyboard dapat dibaca menggunakan berbagai metode, tergantung pada persyaratan tertentu dari aplikasi. Beberapa metode mengambil string penuh, yang lain bekerja atas dasar kunci-demi-kunci, dan sebagainya. Tapi untuk tujuan game, dua jenis rutinitas relevan. Pertama, ada rutinitas sinkron, yang menunggu sampai tombol ditekan dan kemudian melaporkannya ke aplikasi. Kedua, ada rutinitas asynchronous, yang kembali segera setelah dipanggil, dan memberikan informasi tentang aplikasi yang tombol ditekan, jika ada.
Motode membaca sinkron digunakan untuk mengetik informasi, seperti nama karakter dalam permainan role-playing(RPG). Mereka bekerja dengan pemungutan suara controller sampai pesan baru masukan kunci tiba. Tapi mereka tidak sangat baik cocok untuk gameplay nyata. Kode permainan harus terus-menerus memeriksa untuk melihat apakah tombol ditekan, dan apapun respon, terus menggambar, melaksanakan AI, dan sebagainya. Jadi, pengendali asynchronous adalah cara untuk pergi. Mereka menyediakan tes cepat untuk memeriksa keadaan keyboard yang efisien.Rutinitas Asynchronous juga bisa milik dua keluarga yang berbeda. Beberapa dari mereka yang dirancang untuk menguji keadaan kunci individu, sehingga pemrogram melewati kode kunci sebagai parameter dan mendapat negara sebagai terjadi. Lainnya, seperti yang terpapar oleh DirectInput, mengambil negara seluruh keyboard dalam satu panggilan, sehingga programmer dapat mengakses struktur data dan memeriksa keadaan setiap tombol tanpa lebih lanjut hardware cek. Tipe kedua rutin umumnya lebih efisien karena ada overhead kurang terlibat.
Sebagai contoh, kita akan fokus pada panggilan asynchronous satu tombol untuk platform PC. Panggilan adalah Windows spesifik dan merupakan bagian dari Win32 API. Sintaksnya adalah
short GetAsyncKeyState(int keycode);
pada saat sintaks ini dipanggil menerima kode kunci dan mengembalikan nilai pendek, yang mengkode informasi negara yang berbeda. Kuncinya kode kita lulus sebagai parameter dapat menjadi karakter dikapitalisasi, seperti "K", atau kode kunci diperpanjang,yang digunakan untuk membaca karakter khusus. Dengan menggunakan kode kunci yang diperluas, kita dapat membaca kunci tertentu, seperti Hapus, tombol fungsi, Tabs, dan sebagainya. Tabel 5.1 menyediakan daftar kode kunci utama khusus untuk dipanggil.
Nilai encode dikembalikan sebagian kunci dilewatkan sebagai parameter. Bit yang paling signifikan diaktifkan jika kuncinya ditekan, sedangkan least significant bit diaktifkan jika kunci ini diaktifkan yang terakhir GetAsyncKeyState waktu dipanggil. Berikut adalah contoh bagaimana untuk memeriksa apakah tombol Shift kiri adalah ditekan:
If (GetAsyncKeyState(VK_LSHIFT))
{
// whatever
}
Perhatikan bahwa, karena sifat dari panggilan, kita dapat memeriksa beberapa tombol. Contoh berikut menunjukkan bagaimana untuk menguji
untuk Shift kiri DAN kombinasi Kembali:
If ((GetAsyncKeyState(VK_LSHIFT)) && (GetAsyncKeyState(VK_RETURN)))
{
// whatever
}
Seperti yang Anda lihat, setiap tes kunci memerlukan system call, yang dapat menyusahkan bagi sistem-sistem memeriksa
banyak kunci yang berbeda. Sekarang, mari kita membandingkan panggilan ini dengan cek seluruh keyboard, yang dapat dilakukan
dengan menggunakan panggilan:
bool GetKeyboardState(PBYTE *lpKeyState);
Berikut hasilnya hanya mengkodekan apakah fungsi berhasil, dan daging yang sebenarnya dikembalikan sebagai array dikirimkan sebagai
referensi. Kemudian, cek berurutan seperti berikut ini melakukan tes individu, yang tidak lain adalah
lookup sederhana array:
if (keystate[VK_RSHIFT])
{
// right shift was pressed
}
Sekali lagi, untuk game yang memeriksa banyak kunci (seperti simulator penerbangan), opsi ini bisa lebih baik daripada diulang panggilan ke GetAsyncKeyState. Programmer hanya perlu menyadari bahwa panggilan awal untuk GetKeyboardState diperlukan untuk memuat array. Perangkap lain yang mungkin diperhatikan adalah bahwa modus kedua ini tidak segera memeriksa kunci ketika Anda melakukan tes. Tombol diperiksa saat GetKeyboardState dipanggil. Jika ada yang signifikan menunda antara tes ini dan lookup array, efek samping yang tidak diinginkan mungkin terjadi karena array akan
berisi nilai-nilai kunci "old" atau ganjil.
Keyboard dengan DirectInput
DirectInput menyediakan akses cepat untuk asynchronous negara kunci. Panggilan tunggal dapat mengambil keadaan seluruh keyboard, tes berikutnya sehingga hanya pencarian tabel. Operasi ini demikian sangat mirip dengan pemanggilan GetKeyboardState Win32. Tapi sebelum kita menggali kita perlu membaca kode dalam keyboard, kita perlu membahas bagaimana DirectInput bekerja.
DirectInput merangkum keyboard, joystick, mouse, dan input perifer lainnya yang bernaung pada antarmuka yang disebut perangkat. Operasi ini benar-benar mudah.
Pertama-tama kita perlu boot DirectInput. Ini berarti menciptakan objek DirectInput, dari mana semua benda lain yang berhubungan dengan pengolahan input berasal. Objek DirectInput demikian dapat digunakan untuk membuat perangkat, yang merupakan interface logis untuk peripheral. Setelah perangkat dibuat, kita perlu menentukan beberapa parameter, seperti format data yang kita inginkan untuk pertukaran dengan perangkat, dan tingkat koperasi, yang memberitahu DirectInput jika
perangkat yang akan dibagi di antara aplikasi yang berbeda atau jika kita membutuhkannya secara eksklusif.
Perangkat DirectInput dapat disurvei asynchronous. Kami query keadaan perangkat, bukan menunggu khusus acara seperti kunci atau tekan tombol. Ini berarti DirectInput akan mengambil snapshot dari kondisi perangkat pada saat ini dan mengembalikannya ke aplikasi sehingga dapat diproses. Sebagai ringkasan, berikut adalah daftar langkah-langkah dalam mendirikan keyboard DirectInput:
1. Membuat objek DirectInput.
2. Buat perangkat keyboard.
3. Mengatur format data untuk membacanya.
4. Mengatur tingkat cooperative yang akan Anda gunakan pada sistem operasi.
5. Baca data yang diperlukan.
Sekarang mari kita beralih ke contoh spesifik, dimulai dengan kode DirectInput diperlukan untuk boot API. kode itu pada bagian ini telah diuji di kedua DirectX8 dan DirectX9. DirectInput hampir identik di kedua versi.
LPDIRECTINPUT8 g_pDI = NULL;
HRESULT hr = DirectInput8Create (GetModuleHandle (NULL), DIRCTINPUT_VERSION,
IID_IDirectInput8, (VOID **) & g_pDI, NULL)))
Dalam kode sebelumnya, parameter pertama digunakan untuk mengirim pegangan contoh untuk aplikasi yang menciptakan objek DirectInput. Kemudian, kita ,membutuhkan versi DirectInput yang diminta. Macro DIRCTINPUT_VERSION adalah cara praktis untuk melewatkan nomor versi saat ini. Selanjutnya, kita membutuhkan identifier unik antarmuka untuk objek yg diminta. Kami menggunakan IID_IDirectInput8 untuk meminta
DirectInput objek, tetapi kita bisa menggunakan parameter lain untuk menentukan versi ANSI atau Unicode antarmuka. Kami kemudian membutuhkan pointer sehingga kami dapat menerima objek yang sudah diinisialisasi, dan parameter terakhir digunakan untuk melakukan agregasi Komponen Objek Model (COM). Anda mungkin tidak ingin agregat Objek DirectInput untuk hal lain, sehingga meninggalkannya sebagai NULL.
Sekarang kita memiliki objek DirectInput siap digunakan. Sekarang saatnya untuk kode keyboard nyata. Kami pertama akan meminta perangkat dan mengatur beberapa parameter yang menentukan bagaimana kita akan berkomunikasi dengannya. Kemudian, kita akan
memeriksa kode sumber yang digunakan untuk membaca data dari keyboard.
Langkah pertama adalah untuk benar-benar meminta perangkat dari objek DirectInput. Hal ini dicapai dengan baris:
HRESULT hr = g_pDI-> createDevice (GUID_SYSKeyboard, & g_pKeyboard, NULL);
Panggilan harus menerima Global Unique Identifier (GUID) untuk perangkat yang diinginkan. DirectInput dibangun di atas COM, sebuah model pemrograman berorientasi objek. Dalam COM, GUIDs digunakan untuk mengidentifikasi objek tertentu atau
interface. Secara internal, GUIDs hanya 128-bit struktur, tetapi mereka digunakan untuk mewakili fungsi, objek,dan umumnya setiap DirectX membangun. Dalam hal ini, GUIDs klasik untuk perangkat yang berbeda
- GUID_SYSKeyboard: Keyboard sistem default.
- GUID_SysMouse: Mouse sistem default.
GUIDs tambahan dapat ditugaskan untuk joystick. Namun, GUIDs tidak harus ditulis secara langsung, tetapi sebagai hasil dari panggilan untuk DirectInput8 :: EnumDevices.
Kami akan mencakup joystick pada bagian berikutnya. Untuk keyboard kita, GUID_SYSKeyboard akan melakukan pekerjaan. Parameter kedua adalah hanya pointer ke baru menciptakan perangkat, dan parameter terakhir ini lagi disediakan untuk agregasi dan dengan demikian harus diatur ke NULL.
Sekarang, kita harus memberitahu keyboard bagaimana kita ingin bertukar data. Hal ini dicapai dengan panggilan untuk SetDataFormat, seperti yang ditunjukkan di sini:
HRESULT hr = g_pKeyboard-> SetDataFormat (& c_dfDIKeyboard);
Panggilan ini harus menerima sebuah parameter dari tipe LPCDIDATAFORMAT, yang merupakan struktur didefinisikan sebagai:
typedef struct {DIDATAFORMAT
DWORD dwSize;
DWORD dwObjSize;
DWORD dwFlags;
DWORD dwDataSize;
DWORD dwNumObjs;
LPDIOBJECTDATAFORMAT rgodf;
DIDATAFORMAT}, * LPDIDATAFORMAT;
typedef const DIDATAFORMAT * LPCDIDATAFORMAT;
Struktur ini mengontrol jumlah objek kita akan meminta, format masing-masing, dan sebagainya. Karena untuk mengisi struktur kompleks, DirectInput sudah dilengkapi dengan beberapa format data yang telah ditetapkan yang dapat kita gunakan secara langsung. Untuk keyboard, yang c_dfDiKeyboard format yang memberitahu DirectInput kita akan meminta keyboard lengkap, disimpan dalam array 256 byte.
Selain itu, kita perlu memberitahu DirectInput tentang tingkat cooperative yang akan kita gunakan dengan perangkat ini. Ini ditelusuri dengan menggunakan baris:
HRESULT hr = g_pKeyboard-> SetCooperativeLevel (hWnd, DISCL_FOREGROUND | DISCL_EXCLUSIVE);
Di sini kita melewati jendela menangani sebagai parameter pertama, dan parameter kedua adalah ATAU dari serangkaian flag yang mengontrol tingkat koperasi. Dalam hal ini, kita mengatakan bahwa kita ingin DirectInput eksklusif mengakses dan bahwa akses ini hanya berlaku jika aplikasi di latar depan. Sebagai aplikasi kita
bergerak ke latar belakang, perangkat secara otomatis unacquired.
Selain itu, kami perlu mendapatkan keyboard, sehingga kami dapat mulai melakukan query negaranya. Baris berikut akan melakukan
yang bagi kita:
g_pKeyboard-> Acquire ();
Dan sekarang kami siap untuk mulai menggunakan keyboard. Berikut adalah potongan kode yang menyatakan kedua DirectInput dan keyboard, dan memastikan perangkat siap. Pengecekan error telah dihilangkan untuk kejelasan:
HRESULT jam;
hr = DirectInput8Create (GetModuleHandle (NULL), DIRCTINPUT_VERSION,
IID_IDirectInput8, (VOID **) & g_pDI, NULL);
hr = g_pDI-> createDevice (GUID_SYSKeyboard, & g_pKeyboard, NULL);
hr = g_pKeyboard-> SetDataFormat (& c_dfDIKeyboard);
hr = g_pKeyboard-> SetCooperativeLevel (hDlg, dwCoopFlags);
hr = g_pKeyboard-> Acquire ();
Membaca keyboard bahkan lebih mudah daripada menyiapkan itu. Yang harus kita lakukan adalah mempersiapkan array 256-byte dan menyebarkannya ke DirectInput dengan keyboard yang diperoleh untuk query statenya:
Diks BYTE [256]; / / DirectInput Keyboard state penyangga
ZeroMemory (diks, sizeof (diks));
hr = g_pKeyboard-> GetDeviceState (sizeof (diks), diks);
Perhatikan bagaimana kita membersihkan buffer dan kemudian menyebarkannya ke DirectInput. Seperti GetAsyncKeyState, kunci Kode tertentu harus digunakan setelah membaca query untuk setiap tombol. Dalam hal ini, semua kunci diwakili oleh simbol konstanta, seperti:
DIK_RETURN Kunci kembali
DIK_SPACE Tombol spasi
DIK_A ... DIK_Z Kunci abjad
DIK_F1 ... DIK_F10 Tombol fungsi
Sekarang, untuk query kunci tertentu, kita harus menguji bit yang paling signifikan dari posisi array yang sesuai. Jika posisi yang diatur satu, kuncinya saat ini sedang ditekan. Jadi, untuk memeriksa apakah tombol diaktifkan kembali, kode berikut dapat digunakan:
bool return_pressed = (buffer [DIK_RETURN] & 0x80) = 0);!
Seperti biasa, kita bisa membaca kombinasi, sehingga kami dapat memeriksa apakah beberapa kunci yang ditekan secara bersamaan.
Karena hanya ada satu DirectInput membaca di awal, ini hanya pencarian array.
Membaca keyboard yang benar-benar mudah. Tapi kita harus berhati-hati dengan acquiring and unacquiring perangkat, yang dapat membuat kerusakan input controller kita. Kadang-kadang, terutama di beberapa tingkat mode cooperative, kita dapat kehilangan kontak dengan keyboard sesaat. Ini disebut unacquiring perangkat. alasanyang paling populer untuk ini adalah bahwa aplikasi kita pindah ke background, sehingga kehilangan akses keyboard pada aplikasi pendukung yang lain, yang ada pada background sekarang. Beberapa acara lain mungkin akan membuat kita kehilangan jejak perangkat kita. Jika ini terjadi, kita akan menemukannya dalam panggilan GetDeviceState berikutnya, yang akan gagal. Kita kemudian harus reacquire keyboard sehingga kami dapat terus query negaranya. Hal ini dicapai sebagai berikut:
Diks BYTE [256]; / / DirectInput Keyboard negara penyangga
ZeroMemory (diks, sizeof (diks));
hr = g_pKeyboard-> GetDeviceState (sizeof (diks), diks);
if (FAILED (hr))
{
hr = g_pKeyboard-> Acquire ();
sementara (hr == DIERR_INPUTLOST | | hr == DIERR_OTHERAPPHASPRIO)
hr = g_pKeyboard-> Acquire ();
}
Perhatikan bagaimana kita mendeteksi kesalahan dan terus memanggil sampai kita memperoleh kembali hak akses ke perangkat.
Setelah kita selesai dengan aplikasi kita, sekarang saatnya untuk melepaskan semua objek DirectInput. Melepaskan keyboard dengan 2 langkah proses. Pertama, kita unacquire perangkat, kemudian lepaskan struktur datanya.
Kedua, kita harus menghapus objek DirectInput utama. Secara keseluruhan, urutannya dapat dicapai dengan menggunakan kode berikut:
if (g_pKeyboard) g_pKeyboard-> Unacquire ();
SAFE_RELEASE (g_pKeyboard);
SAFE_RELEASE (g_pDI);
Perhatikan bahwa kita menggunakan macro SAFE_RELEASE yang disediakan dengan DirectX untuk memastikan bahwa semua struktur data dan memori yang dialokasikan akan dihapus.
Langganan:
Posting Komentar (Atom)
Terima Kasih Atas Infonya yah mas :)
BalasHapusmaaf baru baca