Sabtu, 25 Mei 2013

User Input


Keyboard
            Keyboard adalah perangkat input utama untuk game berbasis PC, tetapi juga tersedia untuk ponsel, beberapa konsol, dan perangkat sawit. Yang membuat mereka, kemungkinan besar, perangkat input yang paling banyak tersedia. Sayangnya, seperti perangkat input populer sangat tidak cocok untuk game. Pemetaan keyboard mengambil waktu untuk belajar, dan gambaran umum tentang keyboard ini sama sekali tidak praktis untuk anak-anak kecil. Menjadi multifungsi perangkat yang dapat digunakan untuk mengetik dokumen dan untuk bermain game, tidak mengherankan bahwa keyboard dapat dibaca dengan menggunakan berbagai metode, tergantung pada kebutuhan spesifik 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 segera kembali setelah dipanggil, dan memberikan informasi tentang aplikasi yang tombol ditekan, jika ada.
            Mode membaca sinkron digunakan untuk mengetik informasi, seperti nama karakter dalam role-playing game (RPG). Mereka bekerja dengan polling kontroler sampai pesan input kunci baru 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 keyboard seluruh negara dalam satu panggilan, sehingga programmer kemudian dapat mengakses struktur data dan memeriksa keadaan setiap tombol tanpa lebih lanjut cek hardware. 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. Perintahnya adalah
pendek GetAsyncKeyState (int keycode); Panggilan ini 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 diperpanjang, kita bisa membaca kunci tertentu, seperti Hapus, tombol fungsi, Tabs, dan sebagainya. Tabel 5.1 menyediakan daftar kode kunci khusus utama untuk ini menelepon.

Tabel 5.1. Keycodes untuk panggilan GetAsyncKeyState
Keycode Deskripsi
VK_RSHIFT VK_SHIFT, VK, LSHIFT Salah satu dari dua Shift
VK_MENU Salah satu dari tombol Alt
VK_CTRL VK_RCTRL, VK_LCTRL Setiap tombol Ctrl
VK_UP, VK_DOWN, VK_LEFT, VK_RIGHT The tombol kursor
VK_F1 ... VK_F12 Tombol Fungsi
VK_ESCAPE The tombol Esc
VK_SPACE The Spasi
VK_RETURN Enter / Return
VK_HOME, VK_END, VK_PRIOR, VK_NEXT Tombol keypad numerik
VK_BACK The tombol Backspace
VK_TAB Kunci Tab
VK_INSERT, VK_DELETE Insert dan Delete

            Nilai kembali mengkodekan keadaan kunci dilewatkan sebagai parameter. Bit yang paling signifikan diaktifkan jika tombol saat ditekan, sedangkan least significant bit diaktifkan jika kunci ini diaktifkan yang terakhir Waktu GetAsyncKeyState dipanggil. Berikut adalah contoh bagaimana untuk memeriksa apakah tombol Shift kiri adalah ditekan:

Jika (GetAsyncKeyState (VK_LSHIFT))
 {
 / / Apapun
 }
Perhatikan bahwa, karena sifat panggilan, kita dapat memeriksa beberapa tombol. Contoh berikutnya menunjukkan bagaimana untuk menguji untuk Shift kiri DAN Kembali kombinasi:
Jika ((GetAsyncKeyState (VK_LSHIFT)) && (GetAsyncKeyState (VK_RETURN)))
 {
 / / Apapun
 }

Seperti yang Anda lihat, setiap tes kunci memerlukan system call, yang dapat menyusahkan bagi sistem-sistem memeriksabanyak kunci yang berbeda. Sekarang, mari kita bandingkan panggilan ini dengan cek keyboard yang utuh, yang dapat dilakukan dengan menggunakan panggilan:
bool GetKeyboardState (PBYTE * lpKeyState);
Berikut hasilnya hanya mengkodekan apakah fungsi berhasil, dan daging yang sebenarnya dikembalikan sebagai array lulus sebagai referensi. Kemudian, pemeriksaan berturut-turut seperti berikut ini melakukan tes individu, yang tidak lain array lookup sederhana:
if (keystate [VK_RSHIFT])
 {
 Pergeseran / / kanan ditekan
 }



            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. Lain yang mungkin perangkap untuk diperhatikan adalah bahwa modus kedua ini tidak segera memeriksa kunci ketika Anda melakukan tes. Tombol diperiksa pada panggilan untuk GetKeyboardState. Jika ada yang signifikan menunda antara tes ini dan lookup array, efek samping yang tidak diinginkan mungkin terjadi karena array akan mengandung "lama" nilai-nilai kunci. Keyboard dengan DirectInput DirectInput menyediakan akses asynchronous cepat untuk negara-negara kunci. Sebuah panggilan tunggal dapat mengambil keadaan Seluruh Keyboard, tes berikutnya sehingga hanya tabel lookup. Operasi ini demikian sangat mirip dengan GetKeyboardState Win32 menelepon. Namun sebelum kita menggali ke dalam kode pembacaan Keyboard, kita perlu membahas bagaimana DirectInput bekerja.
            DirectInput merangkum keyboard, joystick, tikus, dan setiap masukan eksotis lainnya perifer bawah umum interface yang disebut perangkat. Operasi ini benar-benar mudah. Pertama-tama kita perlu boot DirectInput. Ini menyiratkan menciptakan objek DirectInput, dari mana semua benda lain yang berhubungan dengan proses input dapat berasal. Obyek DirectInput demikian dapat digunakan untuk membuat perangkat, yang merupakan antarmuka logis untuk peripheral. Setelah perangkat telah dibuat, kita perlu menentukan beberapa parameter, seperti format data yang kita inginkan untuk pertukaran dengan perangkat, dan tingkat koperasi, yang memberitahu DirectInput jika perangkat untuk dibagi di antara aplikasi yang berbeda atau jika kita perlu secara eksklusif. Perangkat DirectInput kemudian dapat disurvei asynchronous. Kami query keadaan perangkat, tidak menunggu peristiwa tertentu seperti kunci atau tekan tombol. Ini berarti DirectInput akan mengambil snapshot dari kondisi saat ini perangkat dan mengembalikannya ke aplikasi sehingga dapat diproses. Sebagai ringkasan, berikut adalah daftar langkah-langkah terlibat dalam mendirikan keyboard DirectInput:

1.      Membuat objek DirectInput.
2.      Buat perangkat keyboard yang.
3.      Mengatur format data untuk membacanya.
4.      Mengatur tingkat koperasi akan Anda gunakan dengan sistem operasi.
5.       Baca data yang diperlukan.

Mari kita sekarang beralih ke contoh spesifik, dimulai dengan kode DirectInput diperlukan untuk boot API. Itu kode dalam bagian ini telah diuji di kedua DirectX8 dan DirectX9. DirectInput hampir identik dalam 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 harus lulus versi DirectInput kita meminta. Itu makro DIRCTINPUT_VERSION adalah cara yang berguna untuk lulus nomor versi saat ini. Selanjutnya, kita harus lulus pengenal antarmuka yang unik untuk obyek yang kita minta. Kami menggunakan IID_IDirectInput8 untuk meminta DirectInput objek, tetapi kita bisa menggunakan parameter lain untuk menentukan versi ANSI atau Unicode antarmuka. Kami kemudian melewati pointer sehingga kami dapat menerima objek sudah diinisialisasi, dan parameter terakhir digunakan untuk melakukan Component Object Model (COM) agregasi. Anda mungkin tidak akan ingin agregat Anda Objek DirectInput untuk hal lain, sehingga meninggalkan ini sebagai NULL.
           


            Sekarang kita memiliki objek DirectInput siap untuk digunakan. Sekarang saatnya untuk kode keyboard nyata. Kami akan pertama 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 kalimat:
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 dari COM, model pemrograman berorientasi obyek. Dalam COM, GUIDs digunakan untuk mengidentifikasi objek tertentu atau interface. Secara internal, GUID hanya struktur 128-bit, tetapi mereka digunakan untuk mewakili fungsi, benda, dan umumnya setiap DirectX membangun. Dalam kasus ini, GUIDs klasik untuk perangkat yang berbeda

● GUID_SYSKeyboard: Keyboard sistem default.
● GUID_SysMouse: Sistem tikus default.

            GUID tambahan dapat diberikan ke joystick. Namun, GUID ini 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 pointer ke baru menciptakan perangkat, dan parameter terakhir ini lagi disediakan untuk agregasi dan sehingga 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 harus menerima parameter 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 struktur yang kompleks untuk mengisi, DirectInput sudah dilengkapi dengan beberapa format data yang telah ditetapkan yang dapat kita gunakan secara langsung. Untuk keyboard, c_dfDIKeyboard Format memberitahu DirectInput kita akan meminta keyboard lengkap, disimpan dalam array dari 256 byte. Selain itu, kita perlu memberitahu DirectInput tentang tingkat koperasi akan kita gunakan dengan perangkat ini. Ini dicapai dengan menggunakan garis:
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 bendera yang mengontrol tingkat koperasi. Dalam kasus ini, kita mengatakan DirectInput yang kita inginkan eksklusif mengakses dan bahwa akses ini seharusnya hanya berlaku jika aplikasi tersebut di latar depan. Sebagai aplikasi kita bergerak ke latar belakang, perangkat secara otomatis unacquired. Selain itu, kami perlu mendapatkan keyboard, sehingga kami dapat mulai query negaranya. Baris berikut akan melakukan bahwa 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. Kesalahan pemeriksaan 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 mempersiapkan itu. Yang harus kita lakukan adalah mempersiapkan array 256-byte dan menyebarkannya ke DirectInput dengan keyboard yang diperoleh untuk query negaranya:
Diks BYTE [256]; / / keyboard DirectInput penyangga negara
ZeroMemory (diks, sizeof (diks));
hr = g_pKeyboard-> GetDeviceState (sizeof (diks), diks);

Perhatikan bagaimana kita menghapus buffer dan kemudian menyebarkannya ke DirectInput. Seperti GetAsyncKeyState, kunci tertentu Kode harus digunakan setelah membaca query untuk setiap tombol. Dalam kasus ini, semua kunci yang diwakili oleh simbolik konstanta, seperti:
DIK_RETURN Kunci kembali
DIK_SPACE Tombol spasi
DIK_A ... DIK_Z Tombol 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 ke satu, kuncinya saat ini sedang ditekan. Dengan demikian, untuk memeriksa apakah tombol Kembali adalah diaktifkan, kode berikut dapat digunakan:
bool return_pressed = (buffer [DIK_RETURN] & 0x80) = 0)!;

            Seperti biasa, kita bisa membaca kombinasi, sehingga kami dapat memeriksa apakah beberapa tombol yang ditekan secara bersamaan. Karena hanya ada satu DirectInput membaca di awal, ini hanya berbagai pencarian. Membaca keyboard benar-benar mudah. Tapi kita harus berhati-hati dengan mendapatkan dan unacquiring yang perangkat, yang dapat membuat kontroler masukan kami kerusakan. Kadang-kadang, terutama pada beberapa tingkat kooperatif mode, kita bisa kehilangan kontak dengan keyboard sesaat. Ini disebut unacquiring perangkat. Yang paling alasan populer untuk ini adalah bahwa aplikasi kita pindah ke latar belakang, sehingga kehilangan akses keyboard mendukung aplikasi lain, yang sekarang di latar depan. Beberapa acara lain mungkin membuat kita kehilangan jejak perangkat kami juga. Jika ini terjadi, kita akan menemukan dalam panggilan GetDeviceState berikutnya, yang akan gagal. Kami kemudian harus reacquire keyboard sehingga kami dapat terus query negaranya. Hal ini dicapai sebagai berikut:
Diks BYTE [256]; / / keyboard DirectInput penyangga negara
ZeroMemory (diks, sizeof (diks));
hr = g_pKeyboard-> GetDeviceState (sizeof (diks), diks);
if (FAILED (jam))
 {
 hr = g_pKeyboard-> Acquire ();

 sementara (hr == DIERR_INPUTLOST | | hr == DIERR_OTHERAPPHASPRIO)
 hr = g_pKeyboard-> Acquire ();
 }

Perhatikan bagaimana kita mendeteksi kesalahan dan terus menelepon Memperoleh sampai kita memperoleh kembali akses ke perangkat. Setelah kami selesai dengan aplikasi kita, saatnya untuk melepaskan semua objek DirectInput damai. Melepaskan keyboard adalah proses dua langkah. Pertama, kita unacquire perangkat, kemudian lepaskan struktur datanya. Kedua, kita harus menghapus obyek DirectInput utama. Secara keseluruhan, urutan kehancuran 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 disediakan dengan DirectX untuk memastikan bahwa semua struktur data dan memori yang dialokasikan akan dihapus.


Mouse
            Sejak awal mereka pada akhir 1960-an sebagai perangkat input CAD, tikus telah disesuaikan untuk banyak kegunaan termasuk game komputer. Mereka sangat populer di game PC, tapi game konsol biasanya tidak mendukung mereka. Tidak seperti keyboard atau joystick, mouse tidak hanya menghasilkan tombol atau tombol yang ditekan, tapi 2D posisi juga. Ini menyediakan pilihan yang lebih banyak masukan pada biaya kurva belajar yang lebih tinggi untuk pemain.
            Tikus dapat digunakan dalam berbagai skenario, dari unit memetik dalam judul strategi real-time untuk populer mouselook ditemukan di sebagian besar penembak orang pertama. Dalam semua kasus, pengoperasian mouse dapat dibagi menjadi transmisi informasi posisional (berkat sensor tikus internal) dan mengirim tekan tombol dan pesan rilis. Mari kita periksa bagaimana mouse beroperasi di bawah DirectInput. Kode sumber ini sangat mirip dengan keyboard meminta karena DirectInput memperlakukan semua perangkat yang sama. Hal ini menguntungkan bagi programmer karena rincian paling dalam yang tersembunyi. Mari kita asumsikan kita memiliki objek DirectInput utama dan berjalan, dan mulai dengan penciptaan perangkat lulus:
LPDIRECTINPUTDEVICE g_pMouse;
HRESULT jam;
hr = g_pDI-> CreateDevice (GUID_SysMouse, & g_pMouse, NULL);

Seperti yang Anda lihat, sangat mirip dengan meminta keyboard, satu-satunya perbedaan menjadi GUID kami lulus untuk meminta perangkat yang diinginkan. Kemudian, format data diatur sebagai berikut:
hr = g_pMouse-> SetDataFormat (& c_dfDIMouse);

Dalam hal ini, parameter c_dfDIMouse memberitahu DirectInput kita akan melewati struktur DIMOUSESTATE ke IDirectInputDevice :: GetDeviceState. Struktur ini memiliki tanda tangan berikut:
typedef struct {DIMOUSESTATE
 LONG lX;
 LY PANJANG;
 LONG lZ;
 RgbButtons BYTE [4];
} DIMOUSESTATE, * LPDIMOUSESTATE;

Struktur ini mengembalikan X dan posisi Y, dan Z sumbu opsional, yang biasanya ditugaskan untuk roda. Kemudian, tombol array bekerja seperti array Keyboard. Tombol ditekan jika bit high-order diatur. A varian dari struktur ini adalah DIMOUSESTATE2, ditetapkan oleh c_dfDIMouse2 parameter. Satu-satunya perbedaan adalah bahwa yang terakhir mendukung delapan tombol bukannya empat didukung oleh DIMOUSESTATE. Ini terutama berguna dalam tikus tertentu yang digunakan untuk sistem CAD, misalnya. Setelah format data telah ditetapkan, kita perlu mengatur level kooperatif. Tidak ada kejutan di sini, karena kode tersebut persis sama dengan versi Keyboard:
hr = g_pMouse-> SetCooperativeLevel (hWnd,
 DISCL_EXCLUSIVE | DISCL_FOREGROUND);

Selain itu, kita perlu untuk mendapatkan siap menggunakan perangkat dengan baris:
g_pMouse-> Acquire ();

Berikut adalah kode sumber penuh di review:
LPDIRECTINPUTDEVICE g_pMouse;
HRESULT hr = g_pDI-> CreateDevice (GUID_SysMouse, & g_pMouse, NULL);
hr = g_pMouse-> SetDataFormat (& c_dfDIMouse);
hr = g_pMouse-> SetCooperativeLevel (hWnd,
 DISCL_EXCLUSIVE | DISCL_FOREGROUND);
g_pMouse-> Acquire ();

Membaca dari mouse ini dicapai dengan panggilan GetDeviceState, yang akan mengembalikan LPDIMOUSESTATE struktur. Kode sumber akan:
DIMOUSESTATE dims; / / DirectInput ketatanegaraan tikus
ZeroMemory (& meredup, sizeof (meredup));

hr = g_pMouse-> GetDeviceState (sizeof (DIMOUSESTATE), & meredup);
if (FAILED (jam))
{
 hr = g_pMouse-> Acquire ();
sementara
(hr == DIERR_INPUTLOST | | hr == DIERR_OTHERAPPHASPRIO | |
hr == DIERR_NOTACQUIRED)
hr = g_pMouse-> Acquire ();
 }

Perhatikan bagaimana saya telah menambahkan kode pencegahan unacquiring untuk menghindari kehilangan jejak mouse kita karena kejadian tak terduga. Selain itu, kode ini sangat mirip dengan membaca keyboard. Untuk mengakses mouse atribut, yang harus kita lakukan adalah:
int MouseX = dims.lX;
int mousey = dims.lY;
bool lbutton = (dims.rgbButtons [0] & 0x80) = 0)!;


Biasanya, tombol 0 ditugaskan untuk tombol kiri mouse, tombol 1 ditugaskan untuk orang yang tepat, dan tombol 2 adalah ditugaskan untuk tombol tengah (jika tersedia). Mengenai posisi, ingat bahwa mouse adalah relatif perangkat penunjuk. Ketika pertama kali diperoleh, posisi mouse adalah ulang ke (0,0). Kemudian, masing-masing membaca baru akan kembali perpindahan dari yang terakhir. Jadi, jika kita menggerakkan mouse vertikal, kita akan melihat perpindahan dalam Y arah. Tetapi ketika kita menghentikan gerakan, nilai tikus membaca akan kembali ke (0,0). Ingat, mouse tidak bekerja dengan posisi melainkan bekerja dengan perpindahan. Terakhir, but not least, mouse biasanya dikonfigurasi poin X begitu negatif ke kiri, dan titik Y positif menjauh dari tubuh kita seperti kita duduk di meja.
Selain itu, ingatlah untuk melepaskan mouse segera setelah Anda selesai menggunakannya. Kode ini lagi sangat mirip dengan kode rilis Keyboard:
if (g_pMouse) g_pMouse-> Unacquire ();
SAFE_RELEASE (g_pMouse);
SAFE_RELEASE (g_pDI);
Mouselook

Sebuah penggunaan populer dari mouse adalah untuk menerapkan mouselook klasik yang digunakan dalam banyak penembak orang pertama. Itu mouselook mudah untuk kode setelah Anda memahami bagaimana mouse beroperasi. Yang harus kita lakukan adalah menggunakan kunci mengubah posisi kami, dan menggunakan mouse untuk reorientasi sudut pandang kita. Saya akan menjelaskan efek sepenuhnya, sehingga kita bisa menggabungkan apa yang telah kita pelajari tentang keyboard dan mouse. Permainan harus memiliki setidaknya empat derajat kebebasan. Kita harus memiliki posisi yang terdiri dari X dan Z nilai, dan kemudian yaw dan sudut lapangan. Nilai Y sering ditambahkan ke dalam campuran sehingga kita dapat mendaki berbeda ketinggian, tapi gulungan umumnya tidak diperlukan. Kami akan menggunakan pemetaan berikut:

● Tikus: Mouselook
● Panah kiri: memberondong kiri
● Panah kanan: memberondong tepat
● Panah: Maju
● Panah bawah: Mundur

Mari kita fokus pertama pada keyboard dan melupakan orientasi kedua. Dengan asumsi standar DirectInput Keyboard, kita akan membutuhkan kode berikut untuk menerapkan perilaku yang diinginkan:
int memberondong = (buffer [DIK_RIGHT] & 0x80) = 0) - (buffer [DIK_LEFT] & 0x80) = 0)!;
! int fwd = (buffer [DIK_UP] & 0x80) = 0) - (buffer [DIK_DOWN] & 0x80) = 0)!;

Perhatikan bagaimana kita telah elegan dikemas kontrol kursor. Dengan mengurangi arah yang berlawanan, kita mendapatkan dua nomor, memberondong dan fwd, dalam kisaran -1 .. 1. Jumlah ini kemudian digunakan untuk menggerakkan posisi kami memperbarui rutin:
pos.x + = fwd * FWDSPEED * berlalu * cos (yaw) +
memberondong * STRAFESPEED * berlalu * cos (yaw 3,1416 / 2);
pos.z + = fwd * FWDSPEED * berlalu * sin (yaw) +
memberondong * STRAFESPEED * berlalu * sin (yaw 3,1416 / 2);

The fwd dan memberondong variabel mengontrol bagaimana masing-masing anggota dikalikan dengan -1-, 0, atau 1-untuk melakukan yang diinginkan efek. Sekarang, mari kita merawat lapangan dan yaw melalui mouse:

yaw + = YAWSPEED * berlalu * dims.lX;
lapangan + = PITCHSPEED * berlalu * dims.lY;

Jadi sekarang kita memiliki pos.x baru kami, pos.z, yaw, dan struktur pemain lapangan diperbarui. Jelas, kita perlu menjaga dua perangkat hidup, dan kita perlu mendefinisikan semua konstanta dalam topi untuk mengatur kecepatan yang diinginkan. Perhatikan bagaimana setiap konstan dikalikan dengan faktor waktu berlalu, yang menyimpan waktu yang dibutuhkan untuk membuat frame terakhir. Dengan cara ini kita memastikan perangkat-independen kinerja. Untuk kelengkapan, di sini adalah source code yang diperlukan untuk menghitung semua parameter kamera spesifik siap untuk dipasang ke OpenGL atau DirectX pipa:
Titik campos (pos.x, pos.y, pos.z);
Titik camlookat (pos.x + cos (yaw) * cos (pitch), pos.y + sin (pitch),
pos.z + sin (yaw) * cos (pitch));

The lookat perhitungan koordinat hanya pemetaan bola menggunakan pitch dan yaw. Tergantung pada bagaimana kapak Anda ditata, tanda mungkin berubah atau Anda mungkin perlu menambahkan sudut konstan seperti Pi ke lapangan nilai-nilai.

0 komentar:

Posting Komentar

Adsense Menu

 
Template by : Boedy Template | copyright@2011 | Design by : Boedy Acoy