Usuwanie opóźnienia na początku naciśnięcia klawisza

11

Tworzę prostą grę, a jednym z problemów, z którymi się spotkałem, jest irytujące opóźnienie przy ciągłym naciskaniu klawisza.

Tak więc w zasadzie, kiedy naciskam (przez bardzo długi czas), na przykład Up, mój obiekt przesuwa się o 1 jednostkę w górę, nie porusza się (przez około 1 sekundę), a następnie porusza się ciągle o 1 jednostkę w górę (bez żadnych opóźnień).

Obecnie używam tego do przenoszenia obiektu (SDL2):

while (SDL_PollEvent(&event))
{
    switch (event.type)
    {
    case SDL_KEYDOWN:
        switch (event.key.keysym.sym)
        {
        case SDLK_UP:
            //Move object 1 unit up
            break;
        //Other unrelated things omitted
        }
        break;
    //Omitted other cases
    }
}

Chciałbym usunąć opóźnienie, aby obiekt mógł natychmiast Upbardzo szybko się poruszać . Czy jest na to sposób?

Rakete1111
źródło

Odpowiedzi:

19

Oczekiwanie na uruchomienie zdarzeń obniżających klucz jest prawdopodobne, że zależy od częstotliwości powtarzania kluczowych zdarzeń kontrolowanej przez system operacyjny (i którą użytkownicy mogą sami określić).

Zamiast tego możesz zadzwonić SDL_GetKeyboardStatew górnej części pętli aktualizacji gry (część aktualizacji, która ma miejsce w każdej ramce, niezależnie od tego, czy zdarzenie się pojawiło), aby uzyskać stan klawiatury i sprawdzić, czy w górę Klawisz jest wyłączony lub nie w trakcie pojedynczej klatki.


źródło
Czy nie lepiej byłoby słuchać wiadomości w oknie? Przy użyciu odpytywania czasami brakuje mi bardzo krótkich naciśnięć klawiszy, a problem ten nasila się, gdy liczba klatek na sekundę jest niska.
Roy T.,
@RoyT. To zależy od twojej gry i rodzaju akcji, którą chcesz uruchomić klawiszem. Jeśli naciśnięcie klawisza jest jednorazowe, jak klawisz „akcji”, który zamyka okno dialogowe, kolejka komunikatów jest właściwym podejściem - chcesz nasłuchiwać zdarzenia atomowego. - Z drugiej strony, jeśli status klucza reprezentuje stan ciągły, taki jak klawisz „ruch”, logika jest zwykle while key UP is down move 30 units per second- i na sekundę ma sens tylko wtedy, gdy masz mierzalny czas między kluczem w dół i w górę - zwykle więcej niż jedną klatkę.
Falco
@RoyT. Możesz także słuchać wiadomości (i używać ich do aktualizacji własnej tablicy stanów klawiatury); Zdecydowałem się zasugerować to podejście ze względu na jego prostotę. Z pewnością możesz napisać inną odpowiedź. Ważną częścią jest po prostu unikanie polegania na komunikatach systemu operacyjnego w celu sprawdzania, czy klucz jest ciągle w dół, ponieważ to właśnie łączy cię z częstotliwością powtarzania klucza systemu operacyjnego.
I przez klatkę rozumiesz tykanie gry, a nie klatkę wideo, prawda? Ponieważ nie jesteśmy plebs i nie kodujemy logiki gry w pętli renderowania. :-)
corsiKa
@JoshPetrie Całkowicie się zgadzam, chciałem tylko zwrócić uwagę na to małe zastrzeżenie, jeśli chcesz zaznaczyć „kliknięcie” zamiast „naciśnij”. :)
Roy T.
10

Alternatywnym sposobem (podejście Josha również jest świetne!) Byłoby ustawienie wartości logicznej SDL_KEYDOWNi ewentualnie ignorowanie wszystkich powtarzających się kluczowych zdarzeń. Można to zrobić, sprawdzając repeatczłonka zdarzenia kluczowego.

Następnie możesz wdrożyć swój własny zegar, który nie musi być niczym wymyślnym, i wprowadzić w życie powtarzanie klawiszy. Możesz albo uruchomić akcję bezpośrednio z timera, a nawet wygenerować SDL_KEYDOWNzdarzenie i ujednolicić rozwiązania.

Tyyppi_77
źródło