Zajmuję się tworzeniem gry metodą odpytywania dla metody wprowadzania. Jednak teraz, gdy zagłębiam się w menu gry i inne elementy interfejsu użytkownika, stwierdzam, że prawdopodobnie chciałbym mieć dane sterowane zdarzeniami. Być może nawet posiadanie obu, używanie zdarzeń sterowanych dla interfejsu użytkownika i odpytywanie dla wejścia „świata”. Jestem ciekawy, jaka jest najlepsza droga.
Definiuję sondowanie jako: każdą pętlę aktualizacji sprawdzam, które klawisze są wciśnięte, gdzie znajduje się mysz, naciśnięte przyciski, a następnie je przeglądam i wykonuję działania na podstawie zebranych informacji.
Zdarzenie definiuję jako zdarzenie oparte na: przerwaniu, gdy zdarzenie ma miejsce, a przerwanie jest wyzwalane i blok kodu jest uruchamiany na podstawie zdarzenia.
Czy uważasz, że najlepiej jest kierować się wszystkimi zdarzeniami, wszystkimi ankietami, czy też połączenie obu jest dopuszczalne? Jeśli masz plusy i minusy, proszę wymienić je. Dzięki.
EDYTOWAĆ
Gra jest oparta na Javie / OpenGL, więc zostanie wydana na Windows / Mac / Linux. Możliwość rozszerzenia tego na urządzenia mobilne jest niska. Gra jest w stylu RTS, trzecia osoba w 3D.
EDYCJA 2
Nadal nie jestem do końca zadowolony ze sposobu, w jaki to zaimplementowałem, ale zmierzam do przechwytywania zdarzeń w moim interfejsie użytkownika, a jeśli nie są one obsługiwane przez żaden z moich składników interfejsu, przekazuję zdarzenie do „Świat” do wybierania / selekcji. Coś jak:
@Override
private boolean handleEvent(Event event) {
if(hud.handleEvent(event)) {
return true;
}
return WORLD.handleEvent(event);
}
W ten sposób nie dostaję kliknięć przez interfejs użytkownika, aby wybrać obiekty za przyciskami, a co nie.
Obecnie moje sterowanie kamerą wciąż opiera się na odpytywaniu, i wydaje się, że na razie działa, ale mogę to później zaktualizować.
Doceniam wszystkie odpowiedzi, przepraszam, że mogłem wybrać tylko jedną!
Odpowiedzi:
To zależy od wymagań twojej gry i sprzętu. Większość gier jest zwykle zainteresowana zmianami stanu wejściowego, tj. Użytkownik naciska klawisz ognia, a broń zaczyna strzelać, użytkownik zwalnia klawisz ognia, a broń przestaje strzelać, użytkownik naciska klawisz ruchu i zaczyna się poruszać, zwalnia klawisz ruchu i przestaje się poruszać itd., więc system wprowadzania sterowany zdarzeniami ma w tych przypadkach największy sens, ponieważ informacje są już w odpowiednim formacie. Ponadto na platformie Windows już odbierasz zdarzenia dotyczące zmian stanu klawiatury i myszy, więc często jest to konwersja 1: 1 ze zdarzeń wejściowych niskiego poziomu na zdarzenia gier wysokiego poziomu. Dzięki sondowaniu często trzeba ręcznie generować takie zdarzenia, porównując stan między bieżącą a ostatnią klatką. Zasadniczo „które przyciski są teraz wciśnięte?”
To powiedziawszy, na niektórych platformach utknąłeś na wejściach z ankietami na niskim poziomie i nie ma możliwości obejrzenia się od krawędzi. Jednak zawsze osiągałem najlepsze wyniki, wykorzystując zdarzenia dla całej logiki wysokiego poziomu, ponieważ w naturalny sposób działają te systemy.
źródło
GetAsyncKeyState
jest to prosty sposób na użycie odpytywania w Win32.Nie widzę powodu, dla którego nie możesz zrobić obu i uzyskać to, co najlepsze z obu światów.
Zdarzenia wejściowe są generowane przez odpytywanie (na pewnym poziomie sterownik odpytuje sprzęt, aby zobaczyć, w jakim jest stanie), a ponieważ główna pętla odpytuje wszystkie urządzenia wejściowe, możesz łatwo wdrożyć własne. Coś prostego, takiego jak poniżej, używałem w przeszłości.
Wiem, że zdefiniowałeś zdarzenia jako zakłócenia, a to, co tu umieściłem, nie jest „oparte na prawdziwych zdarzeniach”, ale nie rozumiem, co nie daje ci powyższe, że zakłócenia dają - większość użytkowników nie zauważy utrata pojedynczej klatki, chyba że gra działa z bardzo małą liczbą klatek.
źródło
Istnieją tutaj dwa różne problemy:
Jak odczytujesz dane wejściowe użytkownika z systemu operacyjnego / sprzętu?
Jak przetwarzasz dane wejściowe użytkownika w silniku?
Jeśli chodzi o czytanie, zależy to wyraźnie od platformy i rodzaju danych, które chcesz przeczytać. Zauważ, że łatwo jest przekonwertować jedną rzecz na drugą w warstwie wejściowej. (Tj. Odpytuje i emituje zdarzenia do silnika lub nasłuchuje zdarzeń i emituje stan do silnika).
Do przetwarzania istnieje kilka różnych opcji:
W przypadku kontroli ruchu gracza (i podobnych schematów) odpytywanie może być prostsze, ponieważ trzeba ponownie obliczyć prędkość każdej klatki. Jest bardzo prawdopodobne, że Twoja wewnętrzna pętla będzie oparta na sondowaniu:
tj. coś podobnego
speed += 1 if button.down else -1; clamp(speed, 0, 42);
W przypadku zdarzeń dyskretnych (pocisk ognia, gra pauzy, teleportacja na drugą stronę planety) przetwarzanie zdarzeń jest preferowane, w przeciwnym razie twój kod będzie pełen
maybeLaunchMissile(key_state);
połączeń, a to po prostu ... źle, dobrze. ;)Mam nadzieję, że to pomoże.
źródło