петак, 26 априла, 2024
Како да...?

LibGDX „Java game development framework” (3. дио)

Аутор: Гаврило Продановић

Свако би од framework-а за развој игрица на више платформи очекивао добру апстракцију по питању улазних уређаја да би убрзао свој процес развијања, а LibGDX се са тиме може похвалити. Наш framework посједује два основна начина за обраду улаза: први је pooling гдје позивањем методе утврђујемо стање улазног уређаја (нпр. да ли је типка на тастатури спуштена или читање позиција миша), а други је хватање догађаја (енг. event handling).

Преко pooling-а можемо приступити уређајима уз помоћ неколико основних метода. Да ли је touch screen додирнут, можемо провјерити помоћу isTouched() која враћа true ако постоји додир и false у супротном. За multitouch можемо позвати isTouched(int index), гдје index означава који прст желимо провјерити. Да бисмо добили координате додира, постоје getX() и getY() методе, а за multitouch у аргумент прослиједимо индекс нашег прста/показивача. На desktop-у за манипулацију мишем можемо користити горе претходно наведене методе, а у том случају улаз са миша ће се третирати као single-touch screen. За миш такође постоје додатне методе као што су isButtonPressed(int button), setCursorPosition(int x, int y) и setCursorCatched(boolean) која хвата курсор на средину екрана и чини га невидљивим; и на крају setCursorImage којом можемо промијенити досадну бијелу стрелицу у нешто љепше. Све ове методе, осим isButtonPressed, доступне су само на desktop-у, док ова на мобилним платформама додир екрана региструје као клик лијевог тастера миша. Типке са тастатуре и посебну дугмад на мобилним платформама можемо pooling-ом да хватамо уз помоћ isKeyPressed(int key) методе, а key кодови се налазе у статичкој класи Keys.

Pooling може бити згодан у неким ситуацијама, али много практичније је користити хватање догађаја. У LibGDX-у ћемо догађаје хватати тако што имплементирамо интерфејс InputProcessor, а онда инстанцу имплементираног интерфејса поставимо тако што га прослиједимо Gdx.input.setInputProcessor(InputProcessor) методи. InputProcessor декларише следеће методе за имплементацију: – touchDown, touchUp и touchDragged – помоћу њих можемо регистровати када је прст спуштен или дигнут, или да ли га помјерамо по екрану. – keyDown, keyUp и keyTyped – прве двије методе прослијеђују keycode, а keyTyped ће се позвати само када се генерише unicode принтабилни карактер. – mouseMoved и scrolled се позивају само на desktop платформи. Прва прослијеђује x и y координате, док друга прослијеђује -1 или 1 у зависности од смјера точкића на мишу када се окрене.

Користећи touch као главни улазни уређај за контролу игре, природан начин приступа је коришћење неких основних гестова (енг. gesture) једним прстом или помоћу више њих. Као примјер узећемо увећавање помоћу два прста. Унутар LibGDX-а постоји класа GestureDetector која имплементира InputProcessor интерфејс и може да препозна осам основних гестова који су дефинисани у GestureListener интерфејсу. За гестове који се могу извести једним прстом/показивачем на desktop платформи, GestureDetector ће за улаз да wrap-ује миш.

На мобилним уређајима углавном су присутни акцелерометар и компас, а читање њихових вриједности је могуће преко pooling-а у нашем framework-у. Једини проблем је што се сензорима може приступити само преко pooling-a и не постоје helper класе које би нам помогле у имплементацији контроле на овај начин. Уз акцелерометар и компас можемо на мобилним уређајима користити и вибрације да бисмо пренијели што бољи утисак играчу. Да бисмо активирали вибрацију, можемо методи Gdx.input.vibrate прослиједити трајање вибрације у милисекундама, ако желимо извести сложену вибрацију, можемо прослиједити цјелобројни низ у којем сваки непарни елемент означава дужину трајања вибрације у милисекундама, а сваки парни мировање у милисекундама. Други аргумент означава елемент од кога почиње понављање у петљи или -1 ако желимо да се вибрација заустави на крају низа. У случају да тренутну вибрацију желимо прекинути прије завршетка, у томе ће нам помоћи cancelVibrate().

Уколико од играча требате затражити неки унос као што су надимак или лозинка за сервер, у томе вам може помоћи TextInputListener и метода Gdx.input.getTextInput која ће избацити дијалог и питати корисника за унос. Изглед дијалога зависи од платформе, па ће на Android-у да буде уобичајен Android дијалог, а за desktopSwing дијалог. Уколико одлучите писати своје контроле за унос са тастатуре, на desktop-у, iOS-у и на Android уређајима са физичком тастатуром ће то бити лако изводљиво. За Android-е који немају физичку тастатуру, може се користити onScreen тастатура, али постоје багови који неће хтјети приказати тастатуру уопште, или одређени виртуални тастери неће функционисати. Од тастатура познато је да stock android или Google-ова тастатура одлично ради. Од баговитих тастатура могу се споменути HTC и Samsung-ове и многе још друге. Овај проблем је присутан и зна да зада главобољу, али да не буде као потпуно обесхрабљење, рећи ћемо да није фаталан и постоје начини да се заобиђе, као што је на примјер додатан Activity у Android пројекту који служи за скупљање уобичајених података.

Можда бисте жељели на desktop-у користити могућности које постоје на мобилној платформи као што су multitouch, акцелерометар и компас, да ли због бржег тестирања или да бисте створили неку врсту хибридне платформе. У томе ће вам помоћи класе RemoteSender и RemoteInput. RemoteInput имплементира интерфејс Input тако да све горе што смо до сад навели, јесте подржано. RemoteInput је тај који отвара улазну конекцију и чека да се повеже неки RemoteSender који имплементира интерфејс InputProcessor и у конструктору узима IP адресу и порт на који треба да се повеже. На Play Store-у постоји Gdx Remote апликација која вам може уштедјети вријеме.

Гејмери имају још један вид улаза за рачунар, а то су џојстици или gamepad-ови. У LibGDX-у они су подржани преко екстензије gdx-controllers. Може се користити pool-oвање, или се могу регистровати event listener-и. Пошто не постоји стандард по питању мапирања дугмади на овим уређајима, биће потребно да корисника проведете кроз конфигурацију џојстика. Тренутно једини мапирани контролер је Ouya за који не морати провести играча кроз конфигурацију. Ова екстензија може да се користи и на Android уређајима који покрећу најмање 3.1 верзију овог система.

На крају да резимирамо укратко: LibGDX посједује добру апстракцију и богату подршку за различите улазне уређаје. Осим бага са неким onScreen тастатурама, можемо рећи да смо у потпуности задовољни како је улаз одрађен у овом framework-у.