Pomoc oko dogadjaja

Pomoc oko dogadjaja

offline
  • Pridružio: 19 Maj 2011
  • Poruke: 297

Treba mi mala pomoc oko stukture podataka vezano za input sa tastature.

Da bi objekti koji se krecu u igri imali konstantu brzinu kretanja nezavisno od brzine uredjaja odlucio sam da implementiram "fixed time step" petlju uz pomoc par tutorijala.
To izgleda otprilike ovako:
while( gameRunning ) // glavna petlja igre {     input->update(); // status ulaza sa tasture, misa...         // fixed time step petlja     globalTimer.update();     auto currTime = globalTimer.get();     while((currTime - updatedTime) > fixedStep)     {         scene->update( fixedStep ); // move stuff         updatedTime += fixedStep;      }     scene->drawAll(); // samo crtanje }

E sad kad treba da se pomeri neki objekat koji se kontrolise pomocu tastature recimo, treba da smislim to da izvedem kako treba jer ako je recimo neki taster u "released" stanju (nesto sto treba da se izvrsi samo jedanput) a proveravam ga u fixed time step petlji moze da se desi da ne "pokupim" taj dogadjaj jer nije u datom vremenu usao proces u tu petlju. Ako me razumete?
Nacin koji mislim da treba da se radi je da se proverava taj taster pre petlje i da se taj dogadjaj zabelezi u neku listu (ili sta god) i da se ne mdifikuje dok se ne "obradi" u fixed time step petlji (u kojoj ce se i obrisati taj dogadjaj iz te liste kad se zavrsi sa njim).
E sad pitanje da li zna neko neku standardnu semu (pattern) kako se ovo radi i/ili neki savet/primer kako vi to vidite?



Registruj se da bi učestvovao u diskusiji. Registrovanim korisnicima se NE prikazuju reklame unutar poruka.
offline
  • Srđan Tot
  • Am I evil? I am man, yes I am.
  • Pridružio: 12 Jul 2005
  • Poruke: 2483
  • Gde živiš: Ljubljana

Ne znam da li treba uopšte to da te brine. Predpostavljam da timš podešen takav fixed time step da imaš 30 frejmova po sekundi ili možda čak i više. Čak i ako se desi da update i crtanje scene traje toliko dugo da u sledećoj iteraciji više puta pozoveš update, to ne bi smelo mnogo da utiče na igrivost.



offline
  • Pridružio: 19 Maj 2011
  • Poruke: 297

Nisam lepo objasnio, evo recimo ovako ako pogledamo jednu iteraciju petlje samo:
input->update(); // pokupim stanja tastera // i imam recimo space key up/released // u sledecoj iteraciji vise nece biti! ... // ovde je sad fixed time step petlja // u nekom vremenu moze da se desi da je preskoci pa ne pokupim taj dogadjaj while(...)      scene->update( fixedStep ); scene->drawAll();

Morao bih da sacuvam stanje sa ulaza u neku message queue/listu koja se obradjuje i prazni u FTS sekciji.

offline
  • Srđan Tot
  • Am I evil? I am man, yes I am.
  • Pridružio: 12 Jul 2005
  • Poruke: 2483
  • Gde živiš: Ljubljana

Nažalost, i dalje ne razumem u čemu je problem, ali mislim malo bolju sliku nego posle prvog posta.

Čini mi se kao da ne koristiš buffered input, tj. da uvek samo gledaš trenutno stanje tastature. Što znači da ako se nešto desi dok radiš update i crtanje scene, nikad nećeš biti obavešten o tome. Ako je to problem, najlakše rešenje je da se prebaciš na buffered input ako biblioteka koju koristiš to podržava.

Drugo rešenje koje mi pada na pamet je da češće proveravaš stanje tastature. Ubaci input->update() u while petlju u kojoj vrtiš FTS.

offline
  • Pridružio: 19 Maj 2011
  • Poruke: 297

Citat:
...najlakše rešenje je da se prebaciš na buffered input ako biblioteka koju koristiš to podržava.

Ne koristim biblioteke vec cist win32 raw input.

Citat:
Ubaci input->update() u while petlju u kojoj vrtiš FTS.

Ako ubacim u FTS moze da se desi da ne pokupi input, jer je input->update() u stvari win32 message pump:

MSG msg = {0};    while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))    {       TranslateMessage(&msg);       DispatchMessage(&msg);    }

posto sam se "registrovao" na WM_INPUT poruku u kojoj obradjujem stanje tastera:

case WM_INPUT:       {          if(nullptr != pInput)          {             HRAWINPUT hRawInput = reinterpret_cast<HRAWINPUT>(lParam);             return pInput->handleRawInput(hRawInput);          }       }break;

LRESULT GameInput::handleRawInput(HRAWINPUT hRawInput) {    static const UINT cRawHeaderSize = sizeof(RAWINPUTHEADER);    const UINT dwSize = 40;// 40 is mouse size, 32 for keyboard, on x64 its 48!    UINT sz = dwSize;    LPBYTE lpb[dwSize];    if(-1 == GetRawInputData(hRawInput, RID_INPUT, lpb, &sz, cRawHeaderSize))    {       OutputDebugString("GetRawInputData() failed!");       mouseDelta = D3DXVECTOR2(0, 0);       return 0;    }    RAWINPUT* raw = reinterpret_cast<RAWINPUT*>(lpb);    if(RIM_TYPEMOUSE == raw->header.dwType)    {       handleMouse(raw->data.mouse);    }    if(RIM_TYPEKEYBOARD == raw->header.dwType)    {       handleKeyboard(raw->data.keyboard);    }    return 0; }

offline
  • Srđan Tot
  • Am I evil? I am man, yes I am.
  • Pridružio: 12 Jul 2005
  • Poruke: 2483
  • Gde živiš: Ljubljana

Super, to je već samo po sebi buffered način čitanja (ne može da se desi da izgubiš poruku). Sad samo napraviš jednu strukturu ili klasu koja će na osnovu tih poruka da ima trenutni state ili svih tastera (recimo neki niz boolean tipova u kojem svaki član niza predstavlja jedan taster) ili samo onih koji te zanimaju.

Kasnije u FTS samo gledaš trenutni state. Kada se FTS petlja završi, osvežiće se state preko novih poruka i pičiš dalje.

Ko je trenutno na forumu
 

Ukupno su 717 korisnika na forumu :: 23 registrovanih, 7 sakrivenih i 687 gosta   ::   [ Administrator ] [ Supermoderator ] [ Moderator ] :: Detaljnije

Najviše korisnika na forumu ikad bilo je 3466 - dana 01 Jun 2021 17:07

Korisnici koji su trenutno na forumu:
Korisnici trenutno na forumu: _Sale, A.R.Chafee.Jr., Cirkon, dragon986, Faki-Valjevo, Georgius, GreenMan, hyla, Insan, krkalon, L A Z A R, LeGrandCharles, Lieutenant, Marko Marković, milekNS, Mr. Majevica, MRUD, Pakito93, rovac, Sirius, Tas011, zdrebac, zile54