2010-01-29 33 views
13

Tôi đang làm việc trên trò chơi C++ DirectX 2D và tôi cần đầu vào bàn phím và chuột.
Wikipedia nói:Tôi có nên sử dụng vòng lặp tin nhắn DirectInput hoặc Windows không?

Microsoft khuyến cáo rằng các ứng dụng mới tận dụng các vòng lặp thông điệp Windows cho bàn phím và chuột đầu vào thay vì DirectInput

Vậy làm thế nào tôi nên sử dụng nó?
Tôi có một lớp Gameplay GameScreen chăm sóc bản vẽ và cập nhật (logic trò chơi), tôi gọi phương thức Vẽ và Cập nhật bên trong vòng lặp thông báo của cửa sổ.

Cảm ơn

Trả lời

14

Vì bạn khá nhiều phải chạy một máy bơm tin nhắn để có một cửa sổ, bạn cũng có thể sử dụng máy bơm đó để xử lý đầu vào bàn phím và chuột là tốt. Đó là hoàn toàn tùy thuộc vào máy bơm của bạn cho dù bạn bàn tay sự kiện bàn phím trên một cửa sổ con, bạn có thể xử lý chúng trong máy bơm nếu bạn thích.

máy bơm thông điệp điển hình của bạn trông như thế này:

while (GetMessage(&msg, NULL, 0, 0)) 
{ 
    if (WM_QUIT == msg.message) 
     break; 
    TranslateMessage(&msg); // post a WM_CHAR message if this is a WM_KEYDOWN 
    DispatchMessage(&msg); // this sends messages to the msg.hwnd 
} 

Đối với một trò chơi, máy bơm của bạn có thể trông như thế này

while (true) 
{ 
    if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE | PM_NOYIELD)) 
    { 
     bool fHandled = false; 
     if (msg.message >= WM_MOUSEFIRST && msg.message <= WM_MOUSELAST) 
     fHandled = MyHandleMouseEvent(&msg); 
     else if (msg.message >= WM_KEYFIRST && msg.message <= WM_KEYLAST) 
     fHandled = MyHandleKeyEvent(&msg); 
     else if (WM_QUIT == msg.message) 
     break; 

     if (! fHandled) 
     { 
     TranslateMessage(&msg); 
     DispatchMessage(&msg); 
     } 
    } 
    else 
    { 
     // if there are no more messages to handle right now, do some 
     // game slice processing. 
     // 
    } 
} 

Tất nhiên, bơm thực tế của bạn có khả năng sẽ còn phức tạp hơn rằng, có thể với MsgWaitForMultipleObjects để bạn có thể đánh thức định kỳ ngay cả khi không có thông báo nào để xử lý, nhưng ngay lập tức khi có tin nhắn.

+4

Tôi muốn biết tại sao tôi không nên sử dụng DirectInput. Cảm ơn – Adir

+1

Được trả lời bởi Alex trong http://stackoverflow.com/questions/2165230/should-i-use-directinput-or-windows-message-loop/2168067#2168067 – bobobobo

1

Nếu trò chơi có cửa sổ đơn, so với tôi có thể phân biệt rõ ràng chỉ là vấn đề về hương vị. Tuy nhiên, nếu bạn có (hoặc đang có kế hoạch để có, hoặc không thể loại trừ tích cực các tùy chọn có trong tương lai) nhiều cửa sổ, sau đó cửa sổ nhắn tin có thể bị mệt mỏi.

Vấn đề là do thông báo bàn phím/chuột mặc định chỉ được chuyển đến cửa sổ hiện đang được lấy nét và thường trong các trò chơi bạn muốn có khả năng chuyển tiêu điểm (sang chế độ xem điểm số, kẻ thù trên màn hình radar hoặc bất kỳ thứ gì) và vẫn duy trì tính tương tác. Giải pháp dễ dàng sẽ dành cho mọi mô-đun yêu cầu đầu vào bàn phím/chuột để truy vấn trực tiếp và không dựa vào chuyển tiếp tin nhắn - do đó, DirectInput.

Tôi không thể nói nhiều về kịch bản cụ thể của bạn, tất nhiên - chỉ là 2c của tôi.

+1

Không đúng sự kiện bàn phím và chuột chuyển đến cửa sổ lấy nét. Các sự kiện bàn phím được gửi đến cửa sổ lấy nét _bằng thông điệp bơm_ của bạn (đó là những gì DispatchMessage làm). Sự kiện chuột chuyển đến cửa sổ bên dưới con trỏ. –

+0

Phải. Cảm ơn! Tôi ban đầu chỉ nhận xét bằng bàn phím và chỉ sau đó 'sửa' nó thành bàn phím/chuột. –

-1

XInput chắc chắn là con đường để đi. Đầu vào Độ trễ thấp là rất quan trọng đối với việc chơi game và XInput (thay thế DirectInput trong các DirectXSDK mới) được thiết kế cho chính xác các trường hợp sử dụng này.

Hơn nữa, bạn có hỗ trợ cho các bộ điều khiển trò chơi, cần điều khiển, v.v. ngoài hộp.

+1

DirectInput không phải là độ trễ thấp hơn cho các sự kiện bàn phím và chuột. Nhưng nó cung cấp cho bạn một mô hình đầu vào nhất quán hơn nếu sau này bạn muốn hỗ trợ cần điều khiển, v.v. –

+0

Bạn hoàn toàn đúng, nhưng ý tôi là DirectInput (và XInput, là bộ kế thừa DInputs) có độ trễ thấp hơn các thông điệp Windows. – DarthCoder

+1

Nhưng không phải cho đầu vào bàn phím và chuột.DirectInput chỉ là một trình bao bọc xung quanh API Win32 cho bàn phím và chuột. –

1

Có, bài đăng MSDN là chính xác. Sử dụng các thông điệp windows bạn có thể sử dụng hỗ trợ đa ngôn ngữ (đối với bất kỳ loại bàn phím nào mà người dùng có thể đang sử dụng)/cài đặt cá nhân của người dùng (nút chuột phải thay vì trái), vv .. bạn phải loại bỏ để sử dụng DirectInput/XInput . Chỉ sử dụng 2 thiết bị này để hỗ trợ gamepad/phím điều khiển. Đối với phần còn lại chỉ cần sử dụng các cửa sổ tin nhắn.

Để biết chi tiết, tôi đồng ý với câu trả lời của John Knoeller.

4

DirectInput không được chấp nhận vì lý do chính đáng.Như tôi biết, nó tạo ra một chuỗi phụ và chỉ truy vấn giao diện Raw Input của Windows. Để có hiệu suất tốt nhất, tôi muốn sử dụng Nhập liệu trực tiếp.

Nếu hiệu suất không phải là vấn đề với bạn (và tôi đoán đó là trường hợp đối với trò chơi 2D trên phần cứng hiện tại), hãy làm theo lời khuyên của Microsoft và sử dụng thông báo cửa sổ như mô tả của John Knoeller.

+0

Bạn có thể vui lòng chứng minh "chỉ truy vấn Nguyên nhân của Windows ' giao diện "bit hơn nữa (một tham chiếu có lẽ)? – bobobobo

3

FYI: Re câu trả lời John Knoeller của ... một máy bơm thông điệp đơn giản trông như thế này:

while (GetMessage(&msg, NULL, 0, 0)) 
{ 
    TranslateMessage(&msg); 
    DispatchMessage(&msg); 
} 

Các thử nghiệm WM_QUIT rằng ông bao gồm KHÔNG BAO GIỜ có thể đúng bởi vì GetMessage trả về zero khi một WM_QUIT nhận được. Tuy nhiên, thử nghiệm cho WM_QUIT trong vòng lặp PeekMessage bắt buộc vì PeekMessage trả về true/false cho dù thư có được trả lại hay không. Kể từ khi GetMessage chặn cho đến khi một tin nhắn được trả về, vì vậy nó có thể có một giá trị trả về khác nhau.

0

Sử dụng chỉ sử dụng DirectInput trong những trường hợp đặc biệt

Những điều tốt đẹp về vòng lặp thông điệp của Windows sử dụng với GetMessage là nó sử dụng 0% sử dụng CPU. Nếu bạn đang thực hiện những điều không cần xử lý như chờ một khóa từ người dùng, thu thập dữ liệu từ người dùng như trong cơ sở dữ liệu hoặc chương trình thuế, hoặc thậm chí là một trình xử lý văn bản, chỉ cần sử dụng thông điệp Windows với getmessage. Tôi tất cả các ngày chương trình trên là quá trình khi người dùng nhấn một phím.

Tất cả vòng lặp tin nhắn Windows cần xử lý khóa là để chương trình đó được chuyển sang. Chuột thậm chí không cần phải ở trong cửa sổ.

đặc biệt hoàn cảnh sử dụng DirectInput

Nếu bạn cần phải: 1) Biết khi một phím được nhấn và thả. Bạn cũng có thể không muốn lặp lại các phím được phát hiện dưới dạng nhấn phím.
2) Xử lý các phím trong nền khi một chương trình khác được chuyển sang.

Nếu một trong hai điều trên là đúng, thì hãy sử dụng directinput.

Nếu bạn chỉ đang thu thập dữ liệu từ người dùng, thì bạn sẽ cần phải sử dụng lệnh ngủ để tạm ngừng thực hiện chương trình. Bạn muốn chương trình có 0% sử dụng CPU trong trình quản lý tác vụ nếu chương trình chỉ đang ngồi đó chờ đợi các phím từ người dùng.

Sử dụng chức năng ngủ để chương trình ngủ cho đến khi bạn muốn thăm dò ý kiến ​​đầu vào trực tiếp cho các phím.

Do đó, đầu vào trực tiếp chỉ lãng phí thời gian lập trình nếu bạn đang thực hiện một nhiệm vụ bình thường đơn giản là lấy khóa từ người dùng như bạn có thể thấy.

Các vấn đề liên quan