Így készíts saját érintőképernyős játékot az Arduinóval

|

Érintéssel vezérelt kézi konzolt is meghajthat az Arduino. Cikkünkben bemutatjuk, hogyan érdemes belevágnod, ha ebbe az irányba vinnéd fejlesztésedet.

Igazán minimális hardveres erőforrások mellett is alkothatsz izgalmas játékokat az Arduino közreműködésével; LED-ek és gombok segítségével villámgyorsan összeeszkábálhatsz egy reakció- vagy memóriajátékot, egy néhány soros LCD-kijelzőn pedig elkészítheted a Chrome-ban nethiánykor megjelenő dinós endless runnert.

Mindez azonban össze sem hasonlítható azzal a minőségi ugrással, amit egy érintőképernyő megfelelő alkalmazása jelent, ugyanakkor mindenképp számolnod kell azzal, hogy itt már sokkal komolyabb kihívás vár rád. Ha ez nem tántorít el a feladattól, akkor nincs más teendőd, mint beszerezni a nélkülözhetetlen kijelzőt, cikkünkben pedig segítünk végighaladni a folyamaton, amely első, Arduino-alapú érintőképernyős játékod elkészítéséhez vezet.

Hardverek és csomagok

Az összeállítás során minden kiegészítő komponenst mellőzünk, pusztán a megjelenítőt használjuk, amit a mikrovezérlődhöz kell kapcsolnod. Mi egy 2,4" TFT LCD Shieldet használtunk a demó elkészítéséhez. Már a képernyő használatához is jó néhány extra szoftveres csomagra lesz szükséged, ezért az Arduino IDE elindítása után a Ctrl+Shift+I billentyűkombinációt leütve navigálj a beépített könyvtárkezelőbe.

Itt egy gyors kereséssel installáld a legfrissebb elérhető verziókat az Adafruit GFX Libraryből, az MCUFRIEND_kbv nevű csomagból, valamint az Adafruit TouchScreen modulból. Ezzel a három csomaggal már a legtöbb olcsó kijelzőbe életet lehelhetsz, előtte azonban ellenőrizd a vásárláskor kapott tájékoztatón azt, hogy a gyártó milyen komponensek installálását javasolja.

A telepítések végeztével még mindig nem a kódolás következik, előbb a csatlakoztatott megjelenítődön az érintések megfelelő érzékelése egy kis kalibrációt igényel. Ehhez válaszd a Fájl menüben a Példák opciót, és itt egészen a legalsó szegmensbe került saját csomagokig tekerj le, amíg nem találkozol az MCUFRIEND_kbv könyvtárral. Benne találsz egy TouchScreen_Calibr_native.ino állományt, amelynek megnyitásával és feltöltésével elindíthatod a kijelződ érintősávjainak tesztjét.

Az angolul megjelenő utasításokat követve haladj végig a sarokpontok rögzítésén, és az utolsó lépést követően a képernyődön megjelenő kalibrációs információkat jegyezd le, ezekre az értékek elengedhetetlenek ahhoz, hogy projektedben is hibátlanul működjön az érintések kezelése.

Apró segítség

Saját alkotásod elkészítését nem kell teljesen a nulláról kezdened, az új projektben számos hasznos kódelemet felhasználhatsz a kalibrációs állománnyal megegyező könyvtárban található button_simple.ino programból. Kezdésként nyiss egy új alkalmazást, és az említett állomány setup előtti részét teljes egészében másold át programod felületére.

Ezzel könnyen átugorhatod az inicializációs részeket, valamint az érintésvizsgálat egyes elemeit is, és elkezdhetsz dolgozni játékod megvalósításán. A másolt részeknek mindössze három pontján kell módosítást végrehajtanod: az első a legfelül található #if 1 sor törlése, a másik a const int XP = 6, XM = A2, YP = A1, YM = 7; const int TS_LEFT = 907, TS_RT = 136, TS_TOP = 942, TS_BOT = 139; sorokban található értékek átírása, ide kell beemelned azokat az adatokat, amelyeket a kalibráció során kinyertél.

Végül az Adafruit_GFX_Button után található változók neveit kell cserélned (illetve kibővítened) left_btn, right_btn és fire_btn-re. Ha ezzel megvagy, bezárhatod a button_simple példakódot, innen már egyéni irányelvek szerint haladhatsz tovább. Kezdetnek a setup() függvény belsejében nevesítsd a megjelenítő azonosítóját (uint16_t ID = tft.readID();), aktiváld a képernyőt (tft.begin(ID);), állítsd a kijelzőt portrémódba (tft.setRotation(0); ), majd töltsd ki az egész felületet egy háttérszínnel (tft.fillScreen(BLACK);).

Ha ezekkel a lépésekkel megvagy, akár tesztelheted is a programot, amely jelen formájában az általad választott színre állítja teljes megjelenítő felületét.

Tartalmat a kijelzőre

Következő lépésként - továbbra is a setupban - elkezdheted elemekkel feltölteni megjelenítőd felületét. Elsőként a három gombot varázsold a képernyőre; a két szélsővel egy platformot mozgathatsz majd jobba-balra, a középsővel pedig lövéseket adhatsz le. A tesztünkhöz használt megjelenítő 240×320 pixeles felbontással rendelkezik, amennyiben a saját modelled eltérő képpontszámmal dolgozik, érdemes lehet rugalmasan kezelned/arányosítanod az alábbi értékeket.

A balra mutató gombot a left_btn.initButton(&tft,  60, 280, 60, 40, WHITE, YELLOW, RED, "<--", 2); sor segítségével hozhatod létre, ahol a zárójelben elsőként a kijelzőre hivatkozol, majd megadod a kezdő koordináták pixeleit, illetve a gomb kiterjedését számokban kifejezve, ezek után a színek és a felirat következik. Ha elkészültél, a left_btn.drawButton(false); sor segítségével megjeleníted a gombot, a zárójelben található false információval pedig hamisra állítod a kezdeti érintés értékét.

Hasonlóan készítheted el - a kiindulási pixelek és a feliratok módosítása mellett - a fire_btn, valamint a right_btn gombokat is. Ezek után a tft.drawFastHLine(0,17,240,CYAN); és a tft.drawFastHLine(0,250,240,CYAN); kódokkal húzz két egyenes vonalat a képernyőre, amivel tulajdonképpen lekeríted a játékmezőt.

Már csak a karaktered megjelenítése maradt, ehhez hozz létre egy start változót a definíciós részben, és a kezdő értékét állítsd be 60-ra (int start = 60; ), majd rajzold ki a platformodat és a középső lövész egységét (tft.fillRect(start+29, 216, 2, 4, RED); tft.fillRect(start, 220, 60, 20, RED);). Most már futtathatod a programodat, és játékmeződ készen várja, hogy érintéseiddel életre keltsd figurádat.

Már mozog

Az alapfelállás elkészítését követően a loopban már csak az érintésekkel kell trükköznöd és ez alapján újrarajzolnod a megfelelő objektumokat. Először az érintéseket kell eltárolnod egy igaz/hamis értékkel dolgozó változóban (bool down = Touch_getXY(); ), majd minden gombhoz meghívni a left_btn.press(down && left_btn.contains(pixel_x, pixel_y)); az if (left_btn.justReleased()) { left_btn.drawButton(); }, valamint az if (left_btn.justPressed()) {left_btn.drawButton(true);} ellenőrzéseket.

Az utolsó feltételvizsgálatnál kell még néhány további, gombspecifikus bővítés, de az alapértelmezett felépítés a fire_btn és a right_btn esetében is ugyanez. A balra mutató billentyűnél első lépésként töröld a platformodat úgy, hogy feketére színezed (tft.fillRect(start+29, 216, 2, 4, BLACK);tft.fillRect(start, 220, 60, 20, BLACK); , majd csökkentsd a kiinduló koordináta értékét (start=start-5;), végül rajzold vissza az új állapotot (tft.fillRect(start+29, 216, 2, 4, RED); tft.fillRect(start, 220, 60, 20, RED);).

A másik irányban szintén ezt a kódot használd, az egyetlen, ami változik, hogy itt a start értékét növelned kell majd. A lövés leadásához a justPressed vizsgálatot tartalmazó if-ben hozz létre egy int num=214; változót, majd a tft.fillRect(start+29, num, 2, 2, BLACK); num=num-3;tft.fillRect(start+29, num, 2, 2, GREEN); delay(5); segítségével rajzold ki a képernyőre a lövedéket, igény esetén egy while-ciklusba építve (ezzel a képernyőd felső csíkját óvhatod meg a módosítástól).

Ha elkészültél, jöhet is a tesztelés, kódod segítségével a platform az érintéseidre reagálva mozog a megfelelő irányba, és lövések leadására is képes. Ezek után a PC World Pluson is megtalálható mintakódban még annyival bővítettük a játékot, hogy a képernyő tetején randomizálva, bizonyos lépésenként felrajzoltunk egy kört, találat esetén pedig számoljuk a pontokat, de természetesen a példaprogram alapján saját mechanikákat is kidolgozhatsz frissen beüzemelt kézi konzolod első játékához.

((kód)) void loop() { bool down = Touch_getXY(); left_btn.press(down && left_btn.contains(pixel_x, pixel_y)); right_btn.press(down && right_btn.contains(pixel_x, pixel_y)); fire_btn.press(down && fire_btn.contains(pixel_x, pixel_y));

if (left_btn.justReleased()) {left_btn.drawButton();}

if (fire_btn.justReleased()){ fire_btn.drawButton(); }

if (right_btn.justReleased()) {right_btn.drawButton(); }

if (left_btn.justPressed()) {left_btn.drawButton(true); tft.fillRect(start+29, 216, 2, 4, BLACK); tft.fillRect(start, 220, 60, 20, BLACK); start=start-5; tft.fillRect(start+29, 216, 2, 4, RED); tft.fillRect(start, 220, 60, 20, RED); }

if (fire_btn.justPressed()) { int num=214; fire_btn.drawButton(true);

while(num>25){ tft.fillRect(start+29, num, 2, 2, BLACK); num=num-3; tft.fillRect(start+29, num, 2, 2, GREEN); delay(5); }

tft.fillRect(start+29, num, 2, 2, BLACK); }

if (right_btn.justPressed()) { right_btn.drawButton(true); tft.fillRect(start+29, 216, 2, 4, BLACK); tft.fillRect(start, 220, 60, 20, BLACK); start=start+5; tft.fillRect(start+29, 216, 2, 4, RED); tft.fillRect(start, 220, 60, 20, RED); } }

Úgy tűnik, AdBlockert használsz, amivel megakadályozod a reklámok megjelenítését. Amennyiben szeretnéd támogatni a munkánkat, kérjük add hozzá az oldalt a kivételek listájához, vagy támogass minket közvetlenül! További információért kattints!

Engedélyezi, hogy a https://www.helloworldonline.hu értesítéseket küldjön Önnek a kiemelt hírekről? Az értesítések bármikor kikapcsolhatók a böngésző beállításaiban.