Bẫy chuột trong SDL


12

Làm thế nào tôi có thể bẫy chuột của người dùng trong trò chơi của tôi? Đây không phải là một trò chơi toàn màn hình, nhưng tôi muốn nó để người dùng không thể kéo chuột ra ngoài màn hình.

Tôi có phải kiểm tra tọa độ của chuột và SDL_WarpCthon để làm cho nó nói bên trong cửa sổ (theo cách thủ công) không, hoặc có cách nào tự động không?

Cảm ơn bạn.


Bạn đã xem xét việc ẩn con trỏ và cong nó trở lại trung tâm chưa? Sau đó, chỉ cần vẽ dấu thập của bạn ở giữa màn hình thay cho con trỏ HĐH.
Vaughan Hilts

Câu trả lời:


24

Trong khi bạn có thể thực hiện điều này bằng SDL_WarpCthon (), tôi đã gặp vấn đề với phương thức đó trên một số nền tảng. Tôi đã gặp vấn đề thực sự với một số nền tảng không thực hiện đáng tin cậy hành động WarpCthon (), đặc biệt khi tôi gọi nó là mọi khung hình.

Ngoài ra, hãy nhớ rằng trên nhiều nền tảng, con trỏ được xử lý với tần suất cao hơn ứng dụng của bạn. Điều này đặc biệt đúng nếu bạn đang chạy dưới 60fps! Vì vậy, ngay cả khi nền tảng đang vênh chuột thành công trên mọi khung hình trong trò chơi của bạn, con trỏ vẫn có thể rời khỏi cửa sổ của bạn nếu nó nhận được cập nhật ở giữa các khung được hiển thị của bạn.

Phương pháp chính xác để bẫy chuột theo SDL là:

SDL_WM_GrabInput( SDL_GRAB_ON );

Điều này cho SDL biết rằng ý định của bạn là thực sự giành toàn quyền kiểm soát chuột + bàn phím (xem tài liệu hướng dẫn ) và do đó giữ chuột bên trong cửa sổ bất kể điều gì. Từ thời điểm này, chuột sẽ không di chuyển ra ngoài cửa sổ, bất kể tốc độ khung hình của bạn là bao nhiêu và bạn không nên gọi SDL_WarpCoder, trừ khi bạn thực sự có ý định dịch chuyển con trỏ đi đâu đó, thay vì spam liên tục.

Trong khi ở chế độ "lấy" này, bạn sẽ tiếp tục nhận các sự kiện chuyển động của chuột như thể chuột không bị gò bó trong cửa sổ. (Vì vậy, nếu con trỏ ở cạnh phải của màn hình và người dùng di chuyển chuột sang phải hơn, bạn sẽ nhận được một sự kiện chuyển động chuột hiển thị chuyển động sang phải, mặc dù vị trí con trỏ sẽ không thay đổi). Điều này thực sự hữu ích cho (ví dụ) điều khiển xoay cho các trò chơi FPS, trong đó bạn chỉ quan tâm đến chuyển động tương đối của con trỏ, chứ không phải vị trí tuyệt đối của nó.

Cập nhật cho SDL2 - ngày 9 tháng 12 năm 2013

Giao diện này đã thay đổi cho SDL2. Nếu bạn đang sử dụng SDL1.2, câu trả lời ở trên vẫn đúng. Tuy nhiên, dưới SDL2, SDL_WM_GrabInput(SDL_GrabMode)chức năng không còn khả dụng. Cách mới để bắt chuột của SDL2 là:

SDL_SetRelativeMouseMode(SDL_TRUE);

Mặt khác, chức năng này giống hệt với chức năng trước đó - trong chế độ này, bạn sẽ tiếp tục nhận SDL_MOUSEMOTIONcác sự kiện như thể con chuột không bị hạn chế bên trong cửa sổ.


1
Hãy cẩn thận: Tôi đã nhận thấy rằng trên một số nền tảng, tôi ngay lập tức nhận được một sự kiện MouseMotion giả với một chuyển động rất lớn, ngay sau khi bật lấy chuột. Để đối phó với điều đó, tôi có mã của mình bỏ qua sự kiện chuyển động chuột đầu tiên nhận được sau khi bật chế độ này.
Trevor Powell

Điều đó đã làm việc hoàn hảo, và nó dễ dàng hơn nhiều so với cách thủ công. Cảm ơn bạn!
David Gomes

3

Mặc dù câu trả lời được cập nhật của Trevor phản ánh trạng thái hiện tại của SDL2, bạn cũng có thể bẫy chuột bằng cách tạo của bạn SDL_Windowvới SDL_WINDOW_INPUT_GRABBEDbộ. Xin lưu ý rằng tôi đã gặp phải một số vấn đề lạ trên Linux (có lẽ là do một số vấn đề về cửa sổ X) khi bạn không thể thoát khỏi cửa sổ trừ khi được gọi là SDL_QUIT (ngay cả khi một sự kiện HĐH khác đánh cắp tiêu điểm).


Cảm ơn bạn, SDL_WINDOW_INPUT_GRABBED hoạt động hoàn hảo trên mã SDL2 của tôi.
Adrian Maire


2

Bạn có thể sử dụng Sự kiện chuyển động SDL để phát hiện khi chuột di chuyển. Sau đó, bạn có thể gọi WarpCthon bên trong đó ngay cả sau khi bắn một sự kiện để dẫn các giá trị relX và relY. Bạn cũng có thể ẩn con trỏ hệ điều hành của mình và vẽ một dấu thập hoặc một cái gì đó tương tự ở giữa màn hình. Điều này đảm bảo rằng chuột dường như luôn ở giữa cho người dùng và bạn vẫn có thể nhận các giá trị cho chuyển động và tương tự.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.