Saya menggunakan C # dan mencoba untuk mendapatkan posisi mouse perangkat keras. Hal pertama yang saya coba adalah fungsionalitas XNA sederhana yang mudah digunakan
Vector2 position = new Vector2(Mouse.GetState().X, Mouse.GetState().Y);
Setelah itu saya melakukan menggambar mouse juga, dan membandingkannya dengan mouse hardware windows, mouse baru ini dengan koordinat yang disediakan xna adalah "slacking off". Maksud saya, bahwa itu di belakang oleh beberapa frame. Misalnya jika game berjalan pada 600 fps, tentu saja itu akan responsif, tetapi pada 60 fps perangkat lunak penundaan mouse tidak lagi dapat diterima. Karena itu saya mencoba menggunakan apa yang saya pikir adalah mouse perangkat keras,
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool GetCursorPos(out POINT lpPoint);
tetapi hasilnya persis sama. Saya juga mencoba mendapatkan kursor bentuk Windows, dan itu jalan buntu juga - bekerja, tetapi dengan penundaan yang sama. Berputar-putar dengan fungsionalitas xna:
GraphicsDeviceManager.SynchronizeWithVerticalRetrace = true/false
Game.IsFixedTimeStep = true/fale
memang mengubah waktu tunda untuk alasan yang agak jelas, tetapi intinya adalah bahwa terlepas itu masih di belakang mouse Windows default. Saya pernah melihat di beberapa permainan, bahwa mereka menyediakan opsi untuk mouse yang dipercepat perangkat keras, dan yang lain (saya pikir) sudah secara default. Adakah yang bisa memberikan petunjuk tentang cara mencapai itu.
sumber
Mouse.GetState()
rusak. Apakah Anda yakin bahwa Anda mendapatkan posisi mouse di bingkai yang sama seperti saat Anda menggambarnya? Ingat juga bahwa kursor Windows memiliki akselerasi / deselerasi yang diaktifkan, sehingga terasa lebih responsif. Jika Anda ingin lebih dekat dengan perangkat keras, Anda harus menekan DirectInput, yang akan memberi Anda gerakan delta alih-alih posisi mouse absolut. Tapi saya percayaMouse.GetState()
masih cara yang benar untuk melakukannya di XNA.Mouse.GetState()
tidak rusak, dan selamaIsFixedTimeStep == true
orang seharusnya tidak dapat melihat penundaan kecuali dibandingkan langsung dengan windows mouse yang terlihat. Namun pengaturan IsFixedTimeStep ke false di framerate yang lebih rendah menjadi terlihat oleh semua orang. Tentang input langsung saya menganggap itu suatu kemungkinan (pilihan terakhir).Jawaban:
Apa yang Anda lihat bukan input lag.
Untuk mendapatkan posisi kursor di Windows Anda bisa menggunakan
WM_MOUSEMOVE
atauGetCursorPos
. Keduanya menyediakan posisi kursor setelah Windows memprosesnya, menerapkan hal-hal seperti akselerasi. Ini adalah posisi kursor yang digunakan Windows, termasuk untuk menggambar. Dan hampir selalu apa yang ingin Anda gunakan juga.Inilah yang digunakan XNA . Khususnya
GetCursorPos
( MSDN ). Ini berarti bahwa, ketika Anda meneleponMouse.GetState
, Anda mendapatkan posisi kursor yang sebenarnya seperti yang dilihat Windows - dengan praktis tidak ada penundaan.Sekarang, Anda dapat menggunakan
WM_INPUT
(atau DirectInput, meskipun sudah usang). Ini memberi Anda data pointer mentah. Ini sebelum Windows dapat menerapkan hal-hal seperti akselerasi, dan biasanya bukan yang Anda inginkan.Apa yang Anda lihat adalah output lag.
Ini karena " kursor perangkat keras ". Ini adalah sprite kecil yang akan ditarik lebih layar dengan GPU di sangat akhir pipa nya. Dan maksud saya akhirnya . Muncul setelah buffer bingkai - itu akan dimasukkan ke dalam aliran data saat gambar dikirim ke monitor. Alasannya bereaksi sangat cepat adalah karena posisinya diatur dengan langsung mengatur register GPU. Tidak ada menunggu di dalam pipa sama sekali.
Game Anda, di sisi lain, harus melalui jalur GPU. Ini menambahkan banyak penundaan sendiri. Yang paling bermasalah dari ini untuk Anda adalah buffering ganda - yang (saya cukup yakin) Anda tidak bisa mematikannya di XNA 4. Anda tidak langsung menggambar ke buffer frame - Anda menggambar ke backbuffer. Yang disajikan setiap ~ 16ms (at 60FPS). Itu berarti Anda melihat minimal 16ms antara menerima hasil
Mouse.GetState
mendapatkan sesuatu berdasarkan hasil di layar. Mungkin lebih lama Tentunya jauh lebih lambat daripada kursor perangkat keras.Jadi apa solusinya?
Salah satunya adalah menggunakan
SetCursor
( MSDN ) untuk mengubah gambar yang akan ditampilkan oleh kursor perangkat keras, untuk menjadi gambar yang lebih sesuai dengan permainan Anda (atau hanya tinggal dengan kursor Windows).Dan yang lainnya (jauh lebih mudah) adalah dengan hanya menerima lag, dan mengatur
Game.IsMouseVisible = false
untuk menyembunyikan lag relatif. Tampilkan kursor Anda sendiri dalam game. Ini akan menjadi 16 ms lebih lambat dari kursor Windows yang tersembunyi - tetapi siapa yang peduli? Gamer sudah terbiasa dengan itu. Dan 16ms hampir tidak terlihat secara visual (itu sebabnya kami membuat hal-hal di 60FPS).sumber