Bỏ phiếu so với đầu vào hướng sự kiện


19

Tôi đang phát triển một trò chơi bằng cách sử dụng bỏ phiếu cho phương thức nhập liệu. Tuy nhiên, bây giờ khi tôi đi sâu hơn vào các menu trò chơi và các thành phần UI khác, tôi thấy rằng có lẽ tôi muốn có đầu vào hướng sự kiện. Có lẽ thậm chí có cả hai, sử dụng sự kiện hướng đến UI và bỏ phiếu cho đầu vào "thế giới". Tôi tò mò về cách tốt nhất để đi là gì.

Tôi đang xác định bỏ phiếu là: mỗi vòng cập nhật Tôi kiểm tra các phím nào được nhấn, chuột ở đâu, các nút được nhấn, sau đó chạy qua chúng và thực hiện các hành động dựa trên thông tin được thu thập.

Tôi đang xác định sự kiện được định hướng là: các sự kiện dựa trên ngắt, khi một sự kiện xảy ra và ngắt được kích hoạt và một khối mã được chạy dựa trên sự kiện đó.

Bạn có nghĩ rằng tốt nhất là đi tất cả các sự kiện, tất cả các cuộc bỏ phiếu, hoặc là sự kết hợp của cả hai đều được chấp nhận? Nếu bạn có ưu và nhược điểm cho một trong hai xin vui lòng liệt kê chúng. Cảm ơn.

CHỈNH SỬA

Trò chơi dựa trên Java / OpenGL, do đó sẽ được phát hành cho Windows / Mac / Linux. Khả năng mở rộng điều đó cho các thiết bị di động là thấp. Trò chơi mang phong cách RTS, 3D người thứ 3.

CHỈNH SỬA 2

Tôi vẫn không hoàn toàn hài lòng với cách tôi đã thực hiện điều này, nhưng những gì tôi đang hướng tới là nắm bắt các sự kiện trong UI của mình và nếu chúng không được xử lý bởi bất kỳ thành phần UI nào của tôi, tôi chuyển sự kiện này sang "Thế giới" để chọn / lựa chọn. Cái gì đó như:

@Override  
private boolean handleEvent(Event event) {  
    if(hud.handleEvent(event)) {  
        return true;  
    }  
    return WORLD.handleEvent(event);  
}

Bằng cách này, tôi không nhận được các nhấp chuột bị rò rỉ thông qua giao diện người dùng để chọn các đối tượng phía sau các nút và những gì không.

Hiện tại các điều khiển máy ảnh của tôi vẫn dựa trên việc bỏ phiếu, và điều đó dường như đang hoạt động, nhưng tôi có thể cập nhật điều đó sau.

Tôi đánh giá cao tất cả các câu trả lời, xin lỗi tôi chỉ có thể chọn một!


6
Tôi không chắc chắn trong Java, nhưng nói chung bạn luôn phải bỏ phiếu đầu vào. Sau đó, bạn có thể đăng các sự kiện khi mọi thứ thay đổi, nhưng điều này vẫn dựa trên hệ thống bỏ phiếu.
James

Theo tôi, điểm tập trung thích hợp nhất là thiết kế một vòng lặp sự kiện không có bất kỳ tải trọng nào khác ngoài bộ sưu tập đầu vào. Hãy để tôi giải thích: hệ điều hành sẽ thực hiện gián đoạn điều khiển đầu vào và xử lý nó trong "luồng đầu vào" toàn cầu, sau đó luồng hệ điều hành này sẽ chuyển hướng các tin nhắn vào ứng dụng hiện đang tập trung và ghi thông tin vào hàng đợi tin nhắn của nó. Hàng đợi tin nhắn phải được thăm dò bởi PeekMessage hoặc GetMessage. Cách nhanh nhất để có được điều này là sử dụng GetMessage và để bộ lập lịch đánh thức bạn, sau đó bạn có thể đánh dấu thời gian tin nhắn rất chính xác.
v.oddou

Câu trả lời:


17

Nó phụ thuộc vào yêu cầu của trò chơi và phần cứng của bạn. Hầu hết các trò chơi thường quan tâm đến việc thay đổi trạng thái đầu vào, tức là người dùng nhấn phím lửa và vũ khí của họ bắt đầu bắn, người dùng nhả phím lửa và vũ khí của họ ngừng bắn, người dùng nhấn phím di chuyển và bắt đầu di chuyển, nhả phím di chuyển và dừng di chuyển , v.v., vì vậy một hệ thống đầu vào hướng sự kiện có ý nghĩa nhất trong những trường hợp đó vì thông tin đã có định dạng phù hợp. Ngoài ra, trên nền tảng Windows, bạn đã nhận được các sự kiện thay đổi trạng thái bàn phím và chuột, do đó, đây thường là chuyển đổi 1: 1 từ các sự kiện đầu vào cấp thấp sang các sự kiện trò chơi cấp cao. Với việc bỏ phiếu, bạn sẽ thường thấy mình phải tạo các sự kiện như vậy bằng tay bằng cách so sánh trạng thái giữa khung hiện tại và khung cuối cùng. Về cơ bản, "nút nào được nhấn bây giờ?"

Điều đó đang được nói, trên một số nền tảng nhất định, bạn bị mắc kẹt với đầu vào bỏ phiếu ở mức độ thấp và không có cách nào để tự kiểm tra cạnh. Tuy nhiên, tôi luôn đạt được kết quả tốt nhất khi sử dụng các sự kiện cho tất cả logic cấp cao vì đó là cách tự nhiên mà các hệ thống đó có xu hướng hoạt động.


Cảm ơn, tôi đã bao gồm thông tin bổ sung về nền tảng và mục đích của trò chơi.
MichaelHouse

1
Lưu ý rằng đó GetAsyncKeyStatelà một cách đơn giản để sử dụng bỏ phiếu trên Win32.
Macke

Derp, tôi đã hỏi một câu hỏi trong các bình luận của Nate Bross mà bạn giải quyết ở đây, vì vậy tôi đoán tôi sẽ tinh chỉnh nó. Có phải tất cả các PC đều cung cấp rằng phần cứng 1: 1 làm gián đoạn mối quan hệ sự kiện bàn phím hệ điều hành, và loại nền tảng nào bị giới hạn trong việc bỏ phiếu ở cấp độ thấp?
michael.bartnett

@Macke: đôi khi phần mềm chống vi-rút báo cáo các chương trình sử dụng API này vì chúng có thể nhận được phím bấm từ toàn bộ hệ thống toàn cầu, do đó cho phép đăng nhập khóa độc hại. Bài viết tuyệt vời nhất về nó trên toàn bộ internet (tôi biết) là bài này: securelist.com/analysis/publications/36353/
v.oddou

7

Tôi thấy không có lý do gì mà bạn không thể làm cả hai, và có được những điều tốt nhất của cả hai thế giới.

Sự kiện đầu vào được tạo bằng cách bỏ phiếu (ở một mức độ nào đó, trình điều khiển sẽ thăm dò phần cứng để xem trạng thái của nó) và vì vòng lặp chính của bạn thăm dò tất cả các thiết bị đầu vào, bạn có thể dễ dàng thực hiện việc của riêng mình. Một cái gì đó đơn giản như dưới đây là những gì tôi đã sử dụng trong quá khứ.

mouseInput = GetMouse();
kbInput = GetKeyboard();


// refactor this out to its own method if it makes sense
if menuState == Showing
    if mouseInput.LeftButton == State.Pressed
        LeftButton(mouseInput.X, mouseInput.Y)

// rest of game input code processing

void LeftButton(int x, int y)
{
    // left button event handler
}

Tôi biết rằng bạn đã xác định các sự kiện bị gián đoạn và những gì tôi đã đặt ở đây không phải là "sự kiện dựa trên sự thật", nhưng tôi không thấy những gì ở trên không cung cấp cho bạn những gián đoạn đó mang lại cho bạn - hầu hết người dùng sẽ không nhận thấy mất khung hình duy nhất, trừ khi trò chơi của bạn chạy ở tốc độ khung hình rất thấp.


1
Tôi tò mò về bản chất của việc nhận đầu vào từ các thiết bị. Các sự kiện bàn phím được HĐH gửi đi có phải là kết quả của việc bỏ phiếu ở cấp trình điều khiển thiết bị không? Hay một sự kiện bàn phím tương ứng với một ngắt? Hoặc có các ngắt, nhưng HĐH đệm chúng và gửi chúng khi thấy phù hợp?
michael.bartnett

Tôi không tích cực về cách thức hoạt động của nó ở cấp độ đó, nhưng cơ bản nhất, một số phần mềm chạy trong một vòng lặp và kiểm tra trạng thái bàn phím và so sánh nó với trạng thái trước đó, nếu thay đổi của nó bị thay đổi.
Nate

5

Có hai vấn đề khác nhau ở đây:

  1. Làm thế nào để bạn đọc đầu vào của người dùng từ hệ điều hành / phần cứng?

  2. Làm thế nào để bạn xử lý đầu vào của người dùng trong công cụ của bạn?

Để đọc, nó rõ ràng phụ thuộc vào nền tảng của bạn và loại đầu vào bạn muốn đọc. Lưu ý rằng thật dễ dàng để chuyển đổi thứ này sang thứ khác trong lớp đầu vào của bạn. (Tức là thăm dò và phát ra các sự kiện cho động cơ, hoặc lắng nghe các sự kiện và phát ra trạng thái cho động cơ.)

Để xử lý, có một vài tùy chọn khác nhau:

  • Đối với điều khiển chuyển động của người chơi (và các sơ đồ tương tự), việc bỏ phiếu có thể đơn giản hơn khi bạn cần tính toán lại tốc độ từng khung hình. Rất có khả năng vòng lặp bên trong của bạn sẽ được bỏ phiếu dựa trên:

    tức là một cái gì đó như speed += 1 if button.down else -1; clamp(speed, 0, 42);

  • Đối với các sự kiện riêng biệt (tên lửa, trò chơi tạm dừng, dịch chuyển tức thời đến hành tinh khác), việc xử lý sự kiện là thích hợp hơn, nếu không, mã của bạn sẽ bị vấy bẩn bởi maybeLaunchMissile(key_state);các cuộc gọi và điều đó thật ... tệ, thưa ngài. ;)

Hy vọng nó giúp.

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.