Autor Wątek: C++ obsługa klawiatury  (Przeczytany 2132 razy)

Offline MatlertheGreat

  • Użytkownik

# Styczeń 24, 2014, 23:11:22
Witam,
Coś czuję, że zamiast zrobić coś najprościej, jak zwykle, przekombinowuję, no ale ta sprawa nie daje mi spać :D.

Mam problem z poruszaniem kamery. Najpierw zrobiłem zwykłe sprawdzanie tablicy ze stanem przycisków i odpowiednim przesunięciem kamery:
//Mniej więcej tak:
if( keyArray['W'] )
{
    vPos += Vector( 0.0f, 0.0f, 1.0f );
}

No ale prawdziwemu programiście :D to nie wystarcza więc zacząłem kombinować. Chcąc osiągnąć konfigurowalne sterowanie wieloma czynnikami chcę sobie stworzyć klasę Commander, do której przekazuję komunikat o wciskanych przyciskach. Założenie było takie: sprawdź czy wciśnięty przycisk jest równy temu w configu, jeśli tak, to wyślij komendę do odpowiedniego "słuchacza" np.:
if( keyPressed == keyInConfig )
{
    player.ReceiveCommand( PLAYER_MOVE_FORWARD );
}

Niestety taki kod wywołałby krótki ruch tylko w momencie wciśnięcia przycisku i przytrzymanie go nie skutkowałoby dalszym ruchem. I nie wiem jak rozróżnić gdzie wysyłać jakie komendy.

Tak więc, jak rozwiązujecie sprawę konfigurowalnego sterowania? Czy kamera powinna sama wczytywać config i sprawdzać stan przycisków?
Jak rozróżnić czy przycisk jest trzymany( np. kamera porusza się tak długo jak wciśnięty jest przycisk, ale już przy wciśniętym F2 chcę zmienić kolor tła tylko raz ).
I jeszcze jedno: obsługa klawiatury przez PeekMessage to dobry pomysł, czy jednak mam tego unikać?

Trochę się rozpisałem, mam nadzieję, że Was nie zanudziłem i że nie oczekuję za dużo. Będę wdzięczny za każdą pomoc i wskazówki ;).

Offline Mr. Spam

  • Miłośnik przetworów mięsnych

Offline ArekBal

  • Użytkownik

# Styczeń 24, 2014, 23:25:41
Cytuj
Czy kamera powinna sama wczytywać config i sprawdzać stan przycisków?
FANTASTYCZNY pomysł, MUSISZ go zrealizować

;)

Problem pierwszy się rozwiązuje "mapowaniem" klawisza do polecenia.

Problem drugi poprzez zarządzanie stanami klawisza lub zarządzanie zdarzeniami zmian tego stanu.

EDIT:
Problem 3:
Kod: (Nacisniety) [Zaznacz]
oldKeyState[key].isDown == false && newKeyState[key].isDown
Kod: (Puszczony) [Zaznacz]
oldKeyState[key].isDown && newKeyState[key].isDown == false
Kod: (Przytrzymany) [Zaznacz]
oldKeyState[key].isDown && newKeyState[key].isDown


« Ostatnia zmiana: Styczeń 24, 2014, 23:37:01 wysłana przez ArekBal »

Offline MatlertheGreat

  • Użytkownik

# Styczeń 25, 2014, 00:33:02
FANTASTYCZNY pomysł, MUSISZ go zrealizować
To sarkazm? :D
Czyli sugerujesz, że w metodzie Update() klasy Camera, powinienem przekazać tablcę ze stanem klawiszy? Tam mam sprawdzać odpowiednie przyciski?

A co do mapowania klawiszy. Co jeżeli chcę mieć ustawienia in-game. Musiałbym zmienić plik konfiguracyjny i przekazac nowy do kamery aby się uaktualniła?
Jakoś nie widzi mi się takie wyjście. Dla tego chciałem mieć jedną klasę "tłumaczącą" input na komendy, zrozumiałe dla podzespołów gry. Nie wiem tylko czy powinienem wysyłać komendy w chwili otrzymania komunikatu od Windows, czy odczas faktycznej metody Updae()?

Takie wyjście ma sens( jeśli tak, to mam jeszcze kilka pytań :) ), czy może bezsensownie brnę w błoto?


//Edit
Chyba źle zrozumiałem mapowanie klawiszy.
Chodziło o to, żeby ta przekazywana tablica klawiszy zawierała moje predefiniowane przyciski. Jeśli tak to faktycznie ciekawy pomysł i plus dla Ciebie;). Chyba że coś poknociłem...
« Ostatnia zmiana: Styczeń 25, 2014, 00:44:32 wysłana przez MatlertheGreat »

Offline ArekBal

  • Użytkownik

# Styczeń 25, 2014, 01:15:25
Tak to sarkazm... :)
kamera to kamera, klawisze to klawisze.

Kamerą będziesz chciał sterować na różne sposoby, np. będziesz chciał ją automatyzować.
Póki co, wystaw metody z kamery i steruj z update klasy gry. Jak zaczniesz dodawać stany gry, konteksty inputu, kontrolery do kamery to spojrzysz na to lepszym okiem.

Fakt faktem konfiguracja to jeden z tych modułów aplikacji które się rozchodzą po kodzie niemiłosiernie, tego nie unikniesz, możesz najwyżej ograniczać do konstruktorów.

Cytuj
Co jeżeli chcę mieć ustawienia in-game. Musiałbym zmienić plik konfiguracyjny i przekazac nowy do kamery aby się uaktualniła?
Po to między innymi masz oddzielony input z klawiatury warstwą abstrakcji jaką są komendy by nawet jeżeli się zmieni klawisz to dalej poleci ta sama komenda.
Niech kamera nic nie wie nawet o komendach czy inpucie.

Cytuj
Dla tego chciałem mieć jedną klasę "tłumaczącą" input na komendy, zrozumiałe dla podzespołów gry. Nie wiem tylko czy powinienem wysyłać komendy w chwili otrzymania komunikatu od Windows, czy odczas faktycznej metody Updae()?
To już zależy jak leży. Między innymi będzie to zależeć od rodzaju komendy. Ale zawsze to jest stan i ew. zmiana na stanie. ;)
Może jeżeli "wysyłasz" komendy to się tego trzymaj.
« Ostatnia zmiana: Styczeń 25, 2014, 01:22:13 wysłana przez ArekBal »

Offline Xirdus

  • Redaktor

# Styczeń 25, 2014, 01:32:42
W pętli głównej gry masz na pewno część odpowiedzialną za zbieranie i przetwarzanie inputu. Ta część i tylko ta część powinna bezpośrednio odwoływać się do klawiszy - reszta obiektów gry powinna wiedzieć o inpucie właśnie w postaci komunikatów co zrobić. Z tym że wcale nie potrzeba ci komunikatów jako takich - kod inputu po prostu powinien wywoływać metody odpowiednich obiektów. Rzecz jasna, może też wywoływać jakąś funkcję pośrednią z odpowiednimi argumentami, i dopiero w tej funkcji będzie się odbywać przetwarzanie klawisza (tylko już nie w formie "klawisz W", tylko "klawisz do przodu").

Wczytanie configu i ewentualnie zmiana podczas gry to zadanie dla obiektu opcji gry, którego zadaniem jest tylko i wyłącznie trzymanie opcji gry. Klawisze możesz trzymać jako boost::bimap (mapa, której kluczem mogą być obie wartości z pary) enum klawisza <-> enum akcji.

Offline MatlertheGreat

  • Użytkownik

# Styczeń 25, 2014, 17:46:57
Ok, dzięki wielkie za odpowiedzi. Rozjaśniliście mi parę spraw i chyba już sobie poradzę;)