petak, 19 aprila, 2024
Kako da...?

LibGDX „Java game development framework” (3. dio)

Autor: Gavrilo Prodanović

Svako bi od framework-a za razvoj igrica na više platformi očekivao dobru apstrakciju po pitanju ulaznih uređaja da bi ubrzao svoj proces razvijanja, a LibGDX se sa time može pohvaliti. Naš framework posjeduje dva osnovna načina za obradu ulaza: prvi je pooling gdje pozivanjem metode utvrđujemo stanje ulaznog uređaja (npr. da li je tipka na tastaturi spuštena ili čitanje pozicija miša), a drugi je hvatanje događaja (eng. event handling).

Preko pooling-a možemo pristupiti uređajima uz pomoć nekoliko osnovnih metoda. Da li je touch screen dodirnut, možemo provjeriti pomoću isTouched() koja vraća true ako postoji dodir i false u suprotnom. Za multitouch možemo pozvati isTouched(int index), gdje index označava koji prst želimo provjeriti. Da bismo dobili koordinate dodira, postoje getX() i getY() metode, a za multitouch u argument proslijedimo indeks našeg prsta/pokazivača. Na desktop-u za manipulaciju mišem možemo koristiti gore prethodno navedene metode, a u tom slučaju ulaz sa miša će se tretirati kao single-touch screen. Za miš takođe postoje dodatne metode kao što su isButtonPressed(int button), setCursorPosition(int x, int y) i setCursorCatched(boolean) koja hvata kursor na sredinu ekrana i čini ga nevidljivim; i na kraju setCursorImage kojom možemo promijeniti dosadnu bijelu strelicu u nešto ljepše. Sve ove metode, osim isButtonPressed, dostupne su samo na desktop-u, dok ova na mobilnim platformama dodir ekrana registruje kao klik lijevog tastera miša. Tipke sa tastature i posebnu dugmad na mobilnim platformama možemo pooling-om da hvatamo uz pomoć isKeyPressed(int key) metode, a key kodovi se nalaze u statičkoj klasi Keys.

Pooling može biti zgodan u nekim situacijama, ali mnogo praktičnije je koristiti hvatanje događaja. U LibGDX-u ćemo događaje hvatati tako što implementiramo interfejs InputProcessor, a onda instancu implementiranog interfejsa postavimo tako što ga proslijedimo Gdx.input.setInputProcessor(InputProcessor) metodi. InputProcessor deklariše sledeće metode za implementaciju: – touchDown, touchUp i touchDragged – pomoću njih možemo registrovati kada je prst spušten ili dignut, ili da li ga pomjeramo po ekranu. – keyDown, keyUp i keyTyped – prve dvije metode proslijeđuju keycode, a keyTyped će se pozvati samo kada se generiše unicode printabilni karakter. – mouseMoved i scrolled se pozivaju samo na desktop platformi. Prva proslijeđuje x i y koordinate, dok druga proslijeđuje -1 ili 1 u zavisnosti od smjera točkića na mišu kada se okrene.

Koristeći touch kao glavni ulazni uređaj za kontrolu igre, prirodan način pristupa je korišćenje nekih osnovnih gestova (eng. gesture) jednim prstom ili pomoću više njih. Kao primjer uzećemo uvećavanje pomoću dva prsta. Unutar LibGDX-a postoji klasa GestureDetector koja implementira InputProcessor interfejs i može da prepozna osam osnovnih gestova koji su definisani u GestureListener interfejsu. Za gestove koji se mogu izvesti jednim prstom/pokazivačem na desktop platformi, GestureDetector će za ulaz da wrap-uje miš.

Na mobilnim uređajima uglavnom su prisutni akcelerometar i kompas, a čitanje njihovih vrijednosti je moguće preko pooling-a u našem framework-u. Jedini problem je što se senzorima može pristupiti samo preko pooling-a i ne postoje helper klase koje bi nam pomogle u implementaciji kontrole na ovaj način. Uz akcelerometar i kompas možemo na mobilnim uređajima koristiti i vibracije da bismo prenijeli što bolji utisak igraču. Da bismo aktivirali vibraciju, možemo metodi Gdx.input.vibrate proslijediti trajanje vibracije u milisekundama, ako želimo izvesti složenu vibraciju, možemo proslijediti cjelobrojni niz u kojem svaki neparni element označava dužinu trajanja vibracije u milisekundama, a svaki parni mirovanje u milisekundama. Drugi argument označava element od koga počinje ponavljanje u petlji ili -1 ako želimo da se vibracija zaustavi na kraju niza. U slučaju da trenutnu vibraciju želimo prekinuti prije završetka, u tome će nam pomoći cancelVibrate().

Ukoliko od igrača trebate zatražiti neki unos kao što su nadimak ili lozinka za server, u tome vam može pomoći TextInputListener i metoda Gdx.input.getTextInput koja će izbaciti dijalog i pitati korisnika za unos. Izgled dijaloga zavisi od platforme, pa će na Android-u da bude uobičajen Android dijalog, a za desktopSwing dijalog. Ukoliko odlučite pisati svoje kontrole za unos sa tastature, na desktop-u, iOS-u i na Android uređajima sa fizičkom tastaturom će to biti lako izvodljivo. Za Android-e koji nemaju fizičku tastaturu, može se koristiti onScreen tastatura, ali postoje bagovi koji neće htjeti prikazati tastaturu uopšte, ili određeni virtualni tasteri neće funkcionisati. Od tastatura poznato je da stock android ili Google-ova tastatura odlično radi. Od bagovitih tastatura mogu se spomenuti HTC i Samsung-ove i mnoge još druge. Ovaj problem je prisutan i zna da zada glavobolju, ali da ne bude kao potpuno obeshrabljenje, reći ćemo da nije fatalan i postoje načini da se zaobiđe, kao što je na primjer dodatan Activity u Android projektu koji služi za skupljanje uobičajenih podataka.

Možda biste željeli na desktop-u koristiti mogućnosti koje postoje na mobilnoj platformi kao što su multitouch, akcelerometar i kompas, da li zbog bržeg testiranja ili da biste stvorili neku vrstu hibridne platforme. U tome će vam pomoći klase RemoteSender i RemoteInput. RemoteInput implementira interfejs Input tako da sve gore što smo do sad naveli, jeste podržano. RemoteInput je taj koji otvara ulaznu konekciju i čeka da se poveže neki RemoteSender koji implementira interfejs InputProcessor i u konstruktoru uzima IP adresu i port na koji treba da se poveže. Na Play Store-u postoji Gdx Remote aplikacija koja vam može uštedjeti vrijeme.

Gejmeri imaju još jedan vid ulaza za računar, a to su džojstici ili gamepad-ovi. U LibGDX-u oni su podržani preko ekstenzije gdx-controllers. Može se koristiti pool-ovanje, ili se mogu registrovati event listener-i. Pošto ne postoji standard po pitanju mapiranja dugmadi na ovim uređajima, biće potrebno da korisnika provedete kroz konfiguraciju džojstika. Trenutno jedini mapirani kontroler je Ouya za koji ne morati provesti igrača kroz konfiguraciju. Ova ekstenzija može da se koristi i na Android uređajima koji pokreću najmanje 3.1 verziju ovog sistema.

Na kraju da rezimiramo ukratko: LibGDX posjeduje dobru apstrakciju i bogatu podršku za različite ulazne uređaje. Osim baga sa nekim onScreen tastaturama, možemo reći da smo u potpunosti zadovoljni kako je ulaz odrađen u ovom framework-u.