폴링 vs 이벤트 중심 입력


19

입력 방법으로 폴링을 사용하여 게임을 개발 중입니다. 그러나 이제 게임 메뉴 및 기타 UI 구성 요소에 대해 자세히 살펴보면 이벤트 기반 입력을 원할 것입니다. 아마도 UI를 위해 구동되는 이벤트를 사용하고 "세계"입력을 위해 폴링하는 것도 가능합니다. 가장 좋은 방법은 무엇인지 궁금합니다.

폴링을 다음과 같이 정의하고 있습니다. 각 업데이트 루프는 어떤 키를 눌렀는지, 마우스가 어디에서 눌 렸는지, 버튼을 눌렀는지 확인한 다음, 해당 정보를 기반으로 조치를 취합니다.

이벤트 기반 이벤트, 이벤트가 발생하고 인터럽트가 트리거되고 이벤트를 기반으로 코드 블록이 실행될 때 이벤트 기반을 정의하고 있습니다.

모든 이벤트 중심, 모든 폴링 또는 두 가지의 조합을 모두 수행하는 것이 가장 좋다고 생각하십니까? 찬반 양론이 있으면 목록으로 작성하십시오. 감사.

편집하다

이 게임은 Java / OpenGL 기반이므로 Windows / Mac / Linux로 출시됩니다. 이를 모바일 장치로 확장 할 가능성은 낮습니다. 게임은 RTS 스타일, 3 인칭 3D입니다.

편집 2

나는 여전히 이것을 구현 한 방식에 완전히 만족하지 않지만 UI로 이벤트를 잡는 중이며 UI 구성 요소 중 하나가 처리하지 않으면 이벤트를 이벤트에 전달합니다. 선택 / 선택을위한 "세계". 다음과 같은 것 :

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

이렇게하면 UI를 통해 클릭 수가 누출되어 버튼 뒤에있는 객체와 그렇지 않은 객체를 선택할 수 없습니다.

현재 내 카메라 컨트롤은 여전히 ​​폴링을 기반으로하며 현재 작동하는 것 같지만 나중에 업데이트 할 수 있습니다.

모든 답변을 주셔서 감사합니다. 하나만 선택할 수 있습니다.


6
Java에서는 확실하지 않지만 일반적으로 항상 입력을 폴링해야합니다. 그런 다음 상황이 변경 될 때 이벤트를 게시 할 수 있지만 여전히 폴링 시스템을 기반으로합니다.
James

제 생각에는 가장 관련성 높은 초점은 입력 수집 이외의 다른 레이로드가없는 이벤트 루프를 디자인하는 것입니다. 운영 체제가 입력 기반 중단을 수행하고 전역 "입력 스레드"에서 처리하면이 OS 스레드는 현재 포커스가있는 응용 프로그램으로 메시지를 리디렉션하고 인텔을 메시지 대기열에 씁니다. 메시지 큐는 PeekMessage 또는 GetMessage에 의해 폴링되어야합니다. 이것을 얻는 가장 빠른 방법은 GetMessage를 사용하고 스케줄러가 당신을 깨우 게하는 것입니다. 그러면 메시지를 매우 정확하게 타임 스탬프 할 수 있습니다.
v.oddou

답변:


17

게임 및 하드웨어 요구 사항에 따라 다릅니다. 대부분의 게임은 일반적으로 입력 상태 변경에 관심이 있습니다. 즉, 사용자가 발사 키를 누르면 무기 발사가 시작되고, 사용자는 발사 키를 해제하고 무기는 발사를 중지합니다. 정보 등이 이미 적절한 형식이므로 이벤트 중심 입력 시스템이 가장 적합합니다. 또한 Windows 플랫폼에서 이미 키보드 및 마우스 상태 변경에 대한 이벤트를 수신하므로 하위 레벨 입력 이벤트에서 상위 레벨 게임 이벤트로의 1 : 1 변환입니다. 폴링을 사용하면 현재 프레임과 마지막 프레임 간의 상태를 비교하여 이러한 이벤트를 수동으로 생성해야하는 경우가 종종 있습니다. 기본적으로 "현재 어떤 버튼을 눌렀습니까?"

즉, 특정 플랫폼에서는 낮은 수준에서 폴링 입력이 고착되어 있으며 가장자리를 직접 확인하는 방법은 없습니다. 그러나 나는 항상 모든 고급 로직에 대한 이벤트를 사용하여 최상의 결과를 얻었습니다. 그 시스템은 자연스럽게 작동하는 방식이기 때문입니다.


감사합니다. 게임 플랫폼과 목적에 대한 추가 정보를 포함 시켰습니다.
MichaelHouse

1
참고 GetAsyncKeyStateWin32에서 폴링을 사용하는 간단한 방법입니다.
Macke

Derp, Nate Bross의 의견에서 당신이 여기에서 다루는 질문을 했으므로 그것을 다듬을 것입니다. 모든 PC가 OS 키보드 이벤트 관계에 대한 1 : 1 하드웨어 인터럽트를 제공합니까? 저수준 폴링으로 제한되는 플랫폼은 무엇입니까?
michael.bartnett

@Macke : 안티 바이러스는 때때로이 API를 사용하는 프로그램이 전체 시스템에서 키 누르기를 수신하여 악의적 인 키 로깅을 가능하게하므로 프로그램을보고합니다. 전체 인터넷 (내가 아는 것)에서 그것에 관한 가장 멋진 기사는 이것이다 : securelist.com/analysis/publications/36358/…
v.oddou

7

나는 당신이 두 가지를 모두 할 수 없으며 두 세계를 모두 활용할 수있는 이유가 없습니다.

입력 이벤트는 폴링 (일부 레벨에서 드라이버가 하드웨어를 폴링하여 상태를 확인)에 의해 생성되며, 메인 루프는 모든 입력 장치를 폴링하기 때문에 쉽게 자체 구현할 수 있습니다. 아래처럼 간단한 것이 과거에 사용한 것입니다.

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
}

이벤트를 인터럽트로 정의했으며 여기에 넣은 내용이 "실제 이벤트 기반"이 아니라는 점을 알고 있지만 인터럽트로 인한 내용이 위의 내용에 해당되지 않습니다. 대부분의 사용자는 알지 못합니다 게임이 매우 낮은 프레임 속도로 실행되지 않는 한 단일 프레임이 손실됩니다.


1
장치에서 입력을받는 특성이 궁금합니다. OS에서 키보드 이벤트를 전달하면 장치 드라이버 수준에서 폴링 한 결과입니까? 아니면 키보드 이벤트가 인터럽트와 일치합니까? 아니면 인터럽트가 있지만 OS가 버퍼링하고 적합하다고 판단되면 전달합니다.
michael.bartnett

그 수준에서 어떻게 작동하는지에 대해서는 긍정적이지 않지만 가장 기본적입니다. 일부 소프트웨어는 루프에서 실행되고 키보드 상태를 확인하고 변경 사항이 변경되면 버블 링 된 경우 이전 상태와 비교합니다.
Nate

5

여기에는 두 가지 다른 문제가 있습니다.

  1. OS / 하드웨어에서 사용자 입력을 어떻게 읽습니까?

  2. 엔진에서 사용자 입력을 어떻게 처리합니까?

읽기의 경우 플랫폼과 읽기 원하는 입력에 따라 다릅니다. 입력 레이어에서 한 항목을 다른 항목으로 쉽게 변환 할 수 있습니다. (즉, 엔진에 이벤트를 폴링하고 방출하거나, 이벤트를 듣고 엔진에 상태를 방출합니다.)

처리를 위해 몇 가지 다른 옵션이 있습니다.

  • 플레이어 이동 제어 (및 유사한 구성표)의 경우 각 프레임의 속도를 다시 계산해야하므로 폴링이 더 간단 할 수 있습니다. 내부 루프가 폴링을 기반으로 할 가능성이 큽니다.

    즉, 같은 speed += 1 if button.down else -1; clamp(speed, 0, 42);

  • 불연속 이벤트 (화재 미사일, 일시 정지 게임, 지구 반대편으로 순간 이동)의 경우 이벤트 처리가 바람직합니다. 그렇지 않으면 코드가 maybeLaunchMissile(key_state);전화로 흩어질 수 있습니다. ;)

도움이 되길 바랍니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.