SDL'de fare kapanı


12

Kullanıcının faresini oyunumun içine nasıl bindirebilirim? Tam ekran bir oyun değil, ama kullanıcının fareyi ekranın dışına sürükleyememesi için istiyorum.

Pencerenin içinde (manuel olarak) söylemek için fare ve SDL_WarpCursor koordinatlarını kontrol etmek zorunda mıyım, yoksa otomatik bir yol var mı?

Teşekkür ederim.


İmleci gizlemeyi ve merkeze geri döndürmeyi düşündünüz mü? Ardından, artı imlecinizi OS imleci yerine ekranın ortasına çizin.
Vaughan Hilts

Yanıtlar:


24

SDL_WarpCursor () kullanarak bunu uygulayabilirsiniz, ancak bazı platformlarda bu yöntemle ilgili sorunlar yaşadım. Bazı platformlarda, özellikle her kareyi çağırdığımda, WarpCursor () eylemini güvenilir bir şekilde gerçekleştiremediğimde gerçek sorunlar yaşadım.

Ayrıca, birçok platformda imlecin uygulamanızdan daha yüksek bir frekansta işlendiğini unutmayın. Bu özellikle 60 fps'nin altında koşuyorsanız geçerlidir! Bu nedenle platform, oyununuzun her karesinde fareyi başarıyla çarpıştırsa bile, oluşturulan çerçeveleriniz arasında güncellemeler alıyorsa imleç pencerenizden uzaklaşabilir.

Fareyi SDL altında yakalamak için doğru yöntem:

SDL_WM_GrabInput( SDL_GRAB_ON );

Bu, SDL'ye niyetinizin aslında fare + klavyenin tam kontrolünü ele geçirmek olduğunu ( belgelere bakın ) ve bu nedenle fareyi ne olursa olsun pencerenin içinde tutmak olduğunu söyler . Bu noktadan itibaren, kare hızınızdan bağımsız olarak fare pencerenin dışına taşınmaz ve imleci sürekli olarak spam yapmak yerine bir yere ışınlamak istemiyorsanız, SDL_WarpCursor öğesini çağırmamalısınız.

Bu "kapma" modundayken, fare hareket olaylarını, fare pencerenin içinde kısıtlanmamış gibi almaya devam edeceksiniz. (Dolayısıyla, imleç ekranın sağ kenarındaysa ve kullanıcı faresini daha sağa hareket ettirirse, imleç konumu değişmeyecek olsa da, sağda hareket gösteren bir fare hareketi olayı alırsınız). Bu, mutlak konumunu değil imlecin yalnızca göreceli hareketini önemsediğiniz FPS oyunları için kontrolleri çevirmek (örneğin) için gerçekten yararlıdır.

SDL2 Güncelleştirmesi - 9 Aralık 2013

Bu arayüz SDL2 için değişti. SDL1.2 kullanıyorsanız, yukarıdaki cevap hala doğrudur. Ancak, SDL2 altında SDL_WM_GrabInput(SDL_GrabMode)işlev artık kullanılamaz. SDL2'nin fareyi yakalamanın yeni yolu:

SDL_SetRelativeMouseMode(SDL_TRUE);

Aksi takdirde, bu önceki işlevle aynıdır - bu modda SDL_MOUSEMOTIONfare pencerenin içinde kısıtlanmamış gibi olaylar almaya devam edersiniz .


1
Dikkat: Bazı platformlarda, fare yakalamayı açtıktan hemen sonra çok büyük bir hareketle sahte bir MouseMotion olayı aldığımı fark ettim. Bununla başa çıkmak için, kodum bu modu açtıktan sonra alınan ilk fare hareket olayı yoksay var.
Trevor Powell

Mükemmel çalıştı ve manuel yoldan çok daha kolay. Teşekkür ederim!
David Gomes

3

Trevor'un güncellenen cevabı SDL2 mevcut durumunu yansıtacak etmezken, tuzak oluşturarak fareyi da yapabilirsiniz SDL_Windowile SDL_WINDOW_INPUT_GRABBEDsette. SDL_QUIT çağrılmadıkça (başka bir işletim sistemi olayı odağı çalsa bile), pencereden çıkamayacağınız Linux'ta bazı garip sorunlarla karşılaştığımı (muhtemelen bazı X pencere tuhaflığı nedeniyle) unutmayın.


Teşekkürler, SDL_WINDOW_INPUT_GRABBED SDL2 kodumda mükemmel çalışıyor.
Adrian Maire

3

SDL2 için, etkinleştirmek ve devre dışı bırakmak istiyorsanız SDL_SetWindowGrab işlevi de var gibi görünüyor .

SDL_SetWindowGrab(SDL_Window* window, SDL_bool grabbed)

2

Farenin ne zaman hareket ettiğini algılamak için SDL Hareket Olayı'nı kullanabilirsiniz. Ardından, relX ve relY değerlerini iletmek için bir olayı başlattıktan sonra bile WarpCursor'ı çağırabilirsiniz. Ayrıca OS imlecinizi gizleyebilir ve ekranın ortasına artı işareti veya benzeri bir şey çizebilirsiniz. Bu, farenin kullanıcı için her zaman ortada kalmasını sağlar ve yine de hareket ve benzeri için değerler alabilirsiniz.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.