Mobil programozás

Nehogy már megint a mobilod nyomkodjon Téged!

Bátfai, Norbert

Egyetemi tanársegéd
Debreceni Egyetem, Informatikai Kar
Információtechnológiai Tanszék


                    
                

Bátfai, Mária Erika

Szakmai lektor  
Debreceni Egyetem, Egyetemi és Nemzeti Könyvtár
Társadalomtudomyányi Könyvtár


                    
                

Novák, Ildikó

Nyelvi lektor  
A http://www.angolora.hu online magántanára
http://www.angolora.hu


                    
                

Új Széchenyi Terv logó.

A tananyag a TÁMOP-4.1.2-08/1/A-2009-0046 számú Kelet-magyarországi Informatika Tananyag Tárház projekt keretében készült. A tananyagfejlesztés az Európai Unió támogatásával és az Európai Szociális Alap társfinanszírozásával valósult meg.

A Kelet-magyarországi Informatika Tananyag Tárház logója.

Magyarország megújul logó.

Nemzeti Fejlesztési Ügynökség http://ujszechenyiterv.gov.hu/ 06 40 638-638

Az EU logója.

2011

Verziótörténet
Verzió 0.0.12009. december 29.Bátfai
Elkezdem a jegyzet készítését DocBook 5.0 XML-ben, a pályázati anyagomnak megfelelően GNU FDL engedéllyel. Mivel a Kempelen Farkas Felsőoktatási Digitális Tankönyvtár szokásos licence ennél szigorúbb, az anyagot még nem teszem ki és a legalnotice elemen belül, mindkét licencet említve, részletesen leírom a szituációt.
Verzió 0.0.22010. január 11.Bátfai
Átírom DocBook 4.4-be és ebben folytatom, mert a teljesítéshez a Tankönyvtár lapján, a 2005-ös pályázathoz hasonlóan, a 4.4 verziót kérik.
Verzió 0.0.32010. január 21.Bátfai
Tartalomjegyzék fixálása, bevezető rész befejezése.
Verzió 0.0.42010. február 5.Bátfai
A 110% Nyári Kapitális OSE bemutatása, a Focijáték Neked NYFK foci szimulátorának leírása.
Verzió 0.0.52010. március 6.Bátfai
Maven projektek beillesztése, SourceForge és saját hp-s projektek belinkelése. UML ábrák beillesztése.
Verzió 0.0.62010. március 10.Bátfai
Játékgráfok képeinek legenerálása, beillesztése. A dblatex nem tudta tördelni a táblázatokat, ezért kettessével csoportosítottam a képeket.
Verzió 0.0.112010. március 15.Bátfai
Maven és NetBeans projektként való felélesztés, saját horgászhelyes példa, két gépi játékosos módosítás, helyesírás-ellenőrzés.
Verzió 0.0.122010. szeptember 24.Bátfai
Az USZT és az EU támogatási szövegének, logójának beillesztése.
Verzió 0.0.142010. szeptember 26.Bátfai
LEGO leJOS programozás részek beillesztésének megkezdése.
Verzió 0.0.202010. október 1.Bátfai
A 0.0.1 verziótörténeti bejegyzésnek megfelelő részek kikerültek (bekommentezve). A focis játék továbbfejlesztéseivel kapcsolatos részek frissítve.
Verzió 0.0.212010. október 3.Bátfai
Átolvasás, nyelvi és szakmai lektoroknak kiadás. Képek méretének beállítása (a dblatex számára, az xsltproc-nak a parancssorban kapcsoljuk ki a skálázás figyelését). Az irodalomjegyzék átnézése.
Verzió 0.0.222010. október 6.Bátfai
Feladatok külön kigyűjtése a fejezetek végére.
Verzió 0.1.22010. október 9.Bátfai
Szakmai lektor javításainak átvezetése. További példák beillesztése a fejezetek végére.
Verzió 0.1.32010. október 10.Bátfai
Képek méretének további fimonítása a saját dblatex konverzióhoz (illetve néhány kép vágása). Apróbb hibák javítása. Kiadva a nyelvi lektornak.
Verzió 0.1.42010. október 20.Bátfai
Ellenőrzés, nyomtatás, majd kiadás a lektoroknak. Meta adatok (Dublin Core, Marc) elkészítése.
Verzió 0.2.02010. december 1.Bátfai
Lektori javítások bedolgozása.
Verzió 1.0.02010. december 1.Bátfai
A beküldendő kész könyv.
Verzió 1.0.12011. január 6.Bátfai
A kolofon módosítása (betéve colophon és legalnotice tagokba is).

Ajánlás

Gyerekeimnek: Bátfai Mátyás Bendegúznak, Bátfai Margaréta Niobénak, Bátfai Nándor Benjáminnak és az érdeklődő hallgatóimnak. Viszont, ha szeretnél csatlakozni a Debreceni Fejlesztői Hálózathoz, akkor Neked, mivel a közösségépítés igényével is írtuk, kötelező olvasmány!

Tartalom

Bevezetés
Nehogy már...
Nehogy már megint...
A megnyitott játékok
A könyv szervezése: horgászat, foci, ezoterika
A játékok gondozása, felhasználása az oktatásban
Játékgráfok
A szerzőről
Miért is írom ezt a könyvet?
A lektorokról
I. Tartalom menedzsment
1. A játékok felélesztése
A Java ME™ platform
Konfiguráció és profil
A játékok felélesztése
A játékok új nyelvre fordítása
A fejezet feladatainak összefoglalása
2. A játékok erőforrásainak lecserélése
Képek lecserélése
Új horgászhelyes portolás elkészítése
Új focis portolás elkészítése
A fejezet feladatainak összefoglalása
II. Szoftverfejlesztés
3. A játékok továbbfejlesztése
A játékok szervezése, megírása
A 110% Nyári Kapitális OSE
A Focijáték Neked OSE bemutatása
Az EM foci szimulátora
A Hetedik Szem NYFK bitmintáinak elemzése
Továbbfejlesztések
Két gépi játékos a foci játékban
A fejezet feladatainak összefoglalása
4. A játékok portolása
Portolás
Android platformos horgász
Teljes képernyős asztali alkalmazás
Megvalósítás Java Appletként
A fejezet feladatainak összefoglalása
III. MELLÉKLET
5. Funkcionális képernyőképek
Játék gráfok
Funkcionális pillanatképek a 110% Nyári Kapitális NYFK játékból
Funkcionális pillanatképek a Focijáték Neked NYFK játékból
Funkcionális pillanatképek a Hetedik Szem NYFK játékból
6. LEGO robotok Java programozása
LEGO© NXT
Első leJOS osztályaim
Kormányzott autó viselkedésekkel
Bluetooth alapú távirányító
A fejezet feladatainak összefoglalása
Irodalomjegyzék

A táblázatok listája

2.1. Pillanatkép a most elkészített Saját horgász játékból
2.2. Pillanatkép egy kisebb kijelzőjű szimulátorban a Saját horgász játékból
2.3. A „saját ” labdarúgó futásának keretei
2.4. A „ellen ” labdarúgó futásának keretei
5.1. A 110% Nyári Kapitális NYFK induló splash képernyője
5.2. A 110% Nyári Kapitális NYFK Névjegy parancsának részlete
5.3. Csalizás a 110% Nyári Kapitális NYFK játékban
5.4. A 110% Nyári Kapitális NYFK játék horgászhelye
5.5. Halradar és kapás a 110% Nyári Kapitális NYFK játékban
5.6. A 110% Nyári Kapitális NYFK játék horgász vásznán elérhető parancsok
5.7. A madárdal ki-/bekapcsolásának lehetősége a 110% Nyári Kapitális NYFK játékban
5.8. A splash képernyő a Focijáték Neked NYFK játékban
5.9. A 110% Nyári Kapitális NYFK játék induló képernyőre helyezett parancsai
5.10. Saját játékos labda technika, játékérzék és gyorsaság értékei Focijáték Neked NYFK játék foci szimulátorában
5.11. A Focijáték Neked NYFK játékban a telefon kamerája is fontos szerepet kap
5.12. Indul egy mérkőzés Focijáték Neked NYFK játékbeli VB-n
5.13. Ki-kivel játszik az aktuális sorsolás szerint a Focijáték Neked NYFK játékban
5.14. Olasz-brazil mezőnyjáték a Focijáték Neked NYFK játékban
5.15. Az aktuális olasz-brazil mérkőzés statisztikái Focijáték Neked NYFK játékban
5.16. Új mérkőzés: indul a svéd-angol a Focijáték Neked NYFK játék VB-jének valóságában
5.17. Egy angol szöglet Focijáték Neked NYFK játékban
5.18. Egy védés a német-amerikai meccsen Focijáték Neked NYFK játékban
5.19. Tizenegyes párbaj Focijáték Neked NYFK játékban
5.20. A Hetedik Szem NYFK játék indulása
5.21. A Hetedik Szem NYFK grafikus vászonra rajzolt menüje
5.22. A Hetedik Szem NYFK vásznának parancsai
5.23. A tudat-lenyomatok vizsgálata a Hetedik Szem NYFK játékban
5.24. A tudat-lenyomatok vizsgálatának megjelenítése a Hetedik Szem NYFK játékban

A példák listája

1.1. A megjegyzések
1.2. A MIDlet osztály
1.3. Az API doksi használata
1.4. A Szoveg.java állományok szervezése
1.5. A Parancs.java állományok szervezése
3.1. A játékot vezérlő szál elkészítése és elindítása a KapitalisMIDlet.java állományban
3.2. A játékot vezérlő szál elkészítése és elindítása a FociMIDlet.java állományban

Végszó

A tananyag a TÁMOP-4.1.2-08/1/A-2009-0046 számú Kelet-magyarországi Informatika Tananyag Tárház projekt keretében készült. A tananyagfejlesztés az Európai Unió támogatásával és az Európai Szociális Alap társfinanszírozásával valósult meg.

Magyarország megújul logó.

Az EU logója.

Bevezetés

Ebben a bevezető részben

s ezek mellett azt is megtudjuk majd, hogy egyáltalán miért is írta meg a szerző ezt a könyvet.

„Minden számítógép-pedagógus tudja a világon, hogy játékokkal kell kezdeni.”

Marx György [MARX]

Nehogy már...

 

„Több erőfeszítést fektetünk a tervezésbe és kódolásba (ami szórakozás), hogy csökkentsük a jóval költségesebb tesztelést és hibajavítást (ami nem az).”

 
 --Kernighan-Plauger [KERNIGHANP] A programozás magasiskolája

A Nehogy már a mobilod nyomkodjon Téged! [NEHOGY] című könyv megírásakor arra törekedtem, hogy népszerű stílusban adjak át legalább annyira mély információkat, melyekkel felvértezve az olvasó különösebb erőfeszítés nélkül tudja elkészíteni első, saját mobiltelefonos programjait. Ezt persze azzal is segítem, hogy a könyvben tárgyalt forráskódok nem csak a tárgyalt részleteikben, hanem külön projektekként (azaz a teljes kódokat és a program más erőforrásait is tartalmazóan) elérhetőek. Hét Java ME™ és három Google Android® projektet tekint át a könyv. Az előbbieknél tisztán tudtam alkalmazni a Kernighan-Ritchie klasszikus [KERNIGHANC] C könyvében megismert módszert, hogy minden program egy korábbi továbbfejlesztése. Az Androidos példáknál még elég bug-os volt az akkor még csak szimulált platform, ezért futotta csak három (a Java ME™-s résszel szimmetrikus) projektre[1].

A Nehogy már a mobilod nyomkodjon Téged! könyv borítólapja.

A Nehogy már a mobilod nyomkodjon Téged! könyv példáinak letöltése.

A könyv megírása óta számos kurzusban használtam már fel a könyv példáit, tipikusan a Hetediket, az e közben felhalmozódó tapasztalataim azt mutatják, hogy a könyvvel kitűzött célt sikerült megvalósítanom: a hallgatók (sokszor még olyanok is, akik nem vagy alig rendelkeztek Java programozási ismeretekkel) sikeresen készítették el saját mobil játékukat és sikerélményük volt!

[Tipp]Olvasnál még róla? Olvass!

A könyv megvásárolható vagy megrendelhető a

Sziget Egyetemi Könyvesboltban: Debrecen Egyetem tér 1,
                52 512 900/22185

. Továbbá kölcsönözhető a Debreceni Egyetem Egyetemi és Nemzeti és az Informatikai Kar könyvtárában.

Nehogy már megint...

A jelen Nehogy már megint a mobilod nyomkodjon Téged! című könyv az imént említett folytatásaként készül, így megtehetjük, hogy a Java ME™ platform alapjait csak röviden említjük és a feldolgozást a megnyitott Java játékok feldolgozására fókuszáljuk.

Az írás során arra törekszünk, hogy az olvasó valamilyen szinten könnyen „magáévá tudja tenni” a feldolgozott projekteket. Ezeket a szinteket a következőképpen, a [REVOLUTION] cikkünkben is ismertetett, nehézségük szerint növekvő rendbe szedve, az alábbi módon szervezzük meg:

A megnyitott játékok

A 2008-as Év Informatikai Oktatója VISZ díj átvételekor tett bejelentésnek [2] megfelelően, a szerző doktori (phd) értekezése kapcsán, 2010 elején az Eurosmobil megnyitotta néhány piaci ciklusát már bejárt játékának: egy horgász, egy foci és egy ezoterikus játékának forrását.

A könyv szervezése: horgászat, foci, ezoterika

A jelen könyvet három konkrét megnyitott játék ismertetése nyomán szervezzük meg. Ezek a 110% Nyári Kapitális NYFK ( 110% Summer Capital OSE - egy horgász játék) a Focijáték Neked NYFK ( Soccer Game 4u OSE - egy foci játék) és a Hetedik Szem NYFK ( Seventh Eye OSE - egy ezoterikus közösségi játék).

Nyílt forráskód

A Java forrásokat és a különböző erőforrásokat (képek, MIDI fájlok) a GNU GPL v3[3] licenc engedélye alatt tettük közzé, illetve párhuzamosan e jegyzet írásával, éppen ehhez a könyvhöz készítettük:

  • A Kapitális sorozat a horgászat élményét adja a mobilodon. Adott kiadástól függően úszós, fenekező vagy úszós és fenekező készséggel horgászhatod meg privát tavadat. MIDI-ben (Musical Instrument Digital Interface) készített, élethű, akár csengőhangnak is használható (de azért kikapcsolható) madárdal szórakoztatja játék közben a horgászt. A 110% értelmezése a realisztikusabb horgászat, hogy például a könnyebb szerelékkel felkínált csalit is felveszi a hal, de aztán a fárasztásnál közben ez a vékonyabb zsinór elszakadhat, a vékonyabb horog eltörhet stb. A játékbeli horgászhely bármikor újratelepíthető, 5 különféle méretű zsinórt, 6-féle előkét, 17-féle csalit kombinálhatsz a szereléskor.

    Képernyőkép a Kapitális sorozat egyik tagjáról.

    nyari-kapitalis-1_0_0-project.zip

  • A focis sorozatunk tagjai a foci élményét, a csapat játék irányításának élményét adják a mobilodon. Ezek a programok foci szimulátorok, amelyekkel a labdarúgást a telefon billentyűivel űzhetjük. Ennek megfelelően egy csapatot 10 játékos, a telefon 0-9 gombjáig reprezentálta játékos alkot. A program megjelenése 2.5D. A játékban fotókat készíthetsz a telefon kamerájával a labdarúgókról, illetve át is nevezheted őket. A játék menetét az átadás orientált játék jellemzi. A találkozók 10 percesek, van szöglet, s adott esetben 11-es párbaj. Akár játék közben is váltva a 3x3x3, 3x4x2, 4x3x2, 2x3x4 felállásokba tudod a játékosaidat szervezni.

    Képernyőkép a Fociünnep sorozat egyik tagjáról.

    focijatek-neked-1_0_0-project.zip

  • A Hetedik Szem sorozat tagjai a relaxáció és fantáziálás élményét adják a mobilodon. A mobil használata itt különösen indokolt, hiszen egy billentyűzettel az ölében a játékos nem tud relaxálni. A mi terminológiánkban ez a program egy „szabad akarat szonda”, ami mentális ujjlenyomatot tud felvenni a játékostól. A játék ötletét Kornhuber és Libet a tudatosság és az idő kapcsolatának vizsgálatában szerzett eredményei ihlették „ [Libet] ”, „ [Kornhuber] ”. Nálunk az akaratlagos mozgást az jelenti, hogy a játékos megnyomja a tűzgombot egy a 2048 egymást követő 100 milliszekundumos időszelet során vagy sem. Ennek megfelelően a játék által felvett tudatlenyomat 2048 bites.

    Képernyőkép a Hetedik szem sorozat egyik tagjáról.

    hetedik-szem-1_0_0-project.zip

Mindhárom fenti archívum egy tömörben is elérhető: javacska-one-1_0_0-projects.zip. Szerepelnek továbbá egyéb LEGO™ NXT robotos Java források is, ezek elkészítésénél úgy jártunk el, hogy a forrásokat önmagából ebből a könyvből másoltuk be és próbáltuk ki, így nem lehet majd gondod a példák kipróbálásánál, ha követed az utasításainkat.

A nyílt forrású kibocsátás előtt a játékokon átalakításokat végeztünk, de természetesen úgy, hogy közben funkcióikból nem, vagy alig veszítettek. Az átalakítás célja az volt, hogy ne portolásokat, hanem egyetlen, könnyen karbantartható kiadást adjunk a közösségnek. Ezeknek a kiadásoknak a neveit az „NYFK” (nyílt forráskódú kiadás, open source edition, azaz röviden OSE) részszóval láttuk el.

[Megjegyzés]Jávácska ONE

A megnyitott forrásokat nem csak e könyv fent belinkelt mellékleteként érheted el, hanem megtalálod a Javacska ONE (Jávácska ONE) projekt név alatt a nyílt forrású fejlesztések anyahajóján, a SourceForge.net portálon, illetve a szerző saját lapján is megvan mindhárom játékból egy speciális kiadás: mindhárom helyen (tehát a jelen könyv mellékleteként, a SourceForge-on és a szerző lapján) Maven projektek formájában vannak közzé téve a játékok. Az első esetben a hozzáadott érték nyilván triviálisan maga ez a könyv, a második esetben a közösség: a levelezési lista, a fórum, a verziókövetés, hibakövetés stb. A harmadik esetben (azaz a szerző honlapján) pedig számos speciális riport is kikerült a Maven projektek mellé (a következők: Checkstyle, CPD Report, FindBugs, JavaDocs, JDepend, PMD Report, Source Xref, Tag List, persze a Maven projektekből ezeket magad is automatikusan legenerálhatod a mvn site paranccsal).

[Fontos]A könyvhöz mellékelt forrásokról

Jelen könyv minden forrásfájl csipetének sorait megszámoztuk és a könyv szövegében számos helyen hivatkozunk ezekre a számokra, ezért fontos, hogy a források ne változzanak. Ez persze egy teljesíthetetlen kritérium! Ami azért esetünkben természetesen feloldható: a könyv mellékleteként belinkelt (azaz a Tankönyvtár lapjairól elérhető) forrásokat soha nem fogjuk változtatni, a szerző lapjain ritkán és esetlegesen, a SourceForge-on pedig állandóan változhatnak a források, lévén, hogy itt élnek, itt fut a verziókezelő rendszer, itt tartjuk karban a forrásokat.

A játékok gondozása, felhasználása az oktatásban

Debreceni Fejlesztői Hálózat

Nem elegendő csupán a források megnyitása, kell egy hordozó közösség, amelynek tagjai a projekteket gondozzák. Az általunk tervezett egyetemi fejlesztő közösség gerincét a nemrégiben elindított Debreceni Fejlesztői Hálózat Debrecen Developer Network, DDN képezi.

Debreceni Fejlesztői Hálózat használati esetei

A DDN célja egy széles hallgatói bázisra alapozott egyetemi szoftverfejlesztői közösség kialakítása és fenntartása. Íme, az ábra alapján, a DDN legegyszerűbb használati esetei: az érdeklődő hallgatók jelentkeznek, mert égnek a vágytól, hogy bekapcsolódjanak egy érdekes fejlesztésbe. A diákok elsősorban megfelelő egyetemet, a fejvadász cégek munkatársai pedig gyakorlott hallgatókat keresnek. Jelen pillanatban már ez az önkéntes szervezet a hallgatókkal való szakmai kapcsolattartásom (fejlesztésekbe való bekapcsolódás, diplomamunka téma választása, stb.) alapja.

Hogyan lehetek DDN tag?

Ez az egyetem érdeklődő hallgatóinak tipikus első kérdése. A belépés szabályozása folyamatosan változik. Jelen pillanatban három lehetőség közül választhatsz.

  • Beküldöd a Nehogy már a mobilod nyomkodjon Téged! könyv NehogyMar7 Java ME™ példájának és az AndroidosNehogyMar3 példájának olyan felélesztését, melyben a saját képeidet használod.

  • Valamelyik Jávácska kupára sikeres istállót alakítasz, azaz olyan istállót, hogy az általatok irányított autó legalább három kört képes megtenni a kupa szabványos pályáján.

  • Elkészítesz egy szurkolói avatárt, azaz feldolgozol egy labdarúgó mérkőzést, ami alapján egy (a Relax NG kompakt szintaxisa szerint megadott nyelvtannak megfelelő) érvényes XML állományt készítesz.

Mobil programozás

Egy szélesebb közösséget képeznek a mindenkori Mobil programozás című kurzus hallgatói, mert tulajdonképpen ennek a labornak a jegyzeteként szolgál a könyv. Egyetemünkön ez tipikusan a programtervező informatikus BSc szakon futó INDV331L, INAV331L és T_I3789L kódú tárgy.

A beadandó feladat

A Mobil programozás laboron a félév teljesítésének feltétele, hogy az alább felsorolt feladatokból egyet elkészítesz.

A választható feladatok listája a következő:

Értékelés

A félévben gyakorlati jegyet kell szerezni! Nullától tíz pontig értékeljük a fejlesztésre szánt, munkaórában számított időt, a játékba kódolt játékélményt és a felhasznált API-t. A Mobil programozás laboron kialakult gyakorlat szerint az összpontszám a 3 * játékélmény + 2 * API + munkaóra alapján adódik. A Java EE™ szerveroldai munkával további plusz pontok szerezhetők. Nézzünk néhány használati esetet, hogy hányast fogsz kapni?

  • Jelest kaptam: dolgoztam rajta 10 órát, a játékélmény tovább javult, így szerényen eléri a 10 pontot, további „extra” API-kat nem is használtam: ez pontszám alapján (3*10 + 2*4 + 10 = 48) tipikusan elég volt egy jeleshez.

  • Jót kaptam: az előző esethez képest a játékélményt valamelyest lerontottam, például 3*8 + 2*4 + 10 = 42.

  • Közepest kaptam: ha a játékélmény iménti lerontása mellett csak fele annyit dolgozok, az a hármas környékére pozícionál: például , például 3*8 + 2*4 + 5 = 37.

  • Elégségest kaptam: ha durván elrontom az élményt és alig dolgozok vele, akkor a kettesnél járok.

  • Akad elégtelen osztályzat is, ami azért meglepő egy választható tárgynál...

A pontos ponthatárok félévenként változnak, az elmúlt félévben az alábbi határok voltak érvényben:

  • 45 ponttól jeles,

  • 38 ponttól jó,

  • 30 ponttól közepes,

  • 22 ponttól elégséges.

Lehetséges „házi” vagy órai feladatok listája

A listázott feladatokat egy-egy szóval abból a szempontból jellemezzük, hogy milyen jellegű munkát igényel a kidolgozásuk, illetve a megoldás részletesen-tételesen megtalálható-e a jelen jegyzetben.

Továbbá minden fejezet végén bemutatunk újabb feladatokat. Ezeket (az általunk vélt) nehézségük szerint 1-20 pontig pontozzuk.

Jávácska Kupák

Az elmúlt félévben jó tapasztalatokat szereztünk azzal, hogy a beadható feladatok listáját LEGO™ NXT robotok Java, azaz leJOS programozási feladatokkal bővítettük. Ezt a lehetőséget a továbbiakban is fenntartjuk az alábbiak szerint. A Jávácska Kupában, a Kiterjesztett Jávácska Kupában, vagy a Központosított Jávácska Kupában saját istállóval induló hallgatók külön elbírálás alapján szerezhetik meg a labor érdemjegyét. Az említett kupák egy LEGO robotos autóverseny platform részei, egyelőre tesztfutamok alapján tudsz képet alkotni róluk.

Ennek megfelelően a jegyzet mellékleteként részletesen foglalkozunk a LEGO robotok Java programozásával, amivel azt is elérjük, hogy a jegyzet a Magasszintű programozási nyelvek 2 kurzusban is felhasználható legyen egy előadás részlet és két-négy laborfoglalkozás erejéig.

Egy tipikus félév heti bontásban

  1. A mobil fejlesztési platformokat, az aktuális mobil piaci trendeket, a Java ME és az Android platformot részletesebben bemutató bevezető előadás levetítése, megbeszélése. Otthoni feladat: a kapcsolódó megadott könyv és internetes szemelvények elolvasása. Laborfeladat: A Nehogy már a mobilod nyomkodjon Téged! [NEHOGY] első rész feladatai közül az elsőtől a hatodikig, azaz a NehogyMar1- NehogyMar6 Java ME™ példáknak a kipróbálása.

  2. A Nehogy már a mobilod nyomkodjon Téged! [NEHOGY] első rész hetedik NehogyMar7 Java ME™ példájának és az AndroidosNehogyMar3 példájának kipróbálása. Otthoni feladat: a két példa egyikének módosítása. Például saját szprájtok és csempézett háttér alkalmazása, esetleg a háttér mozgási irányának megváltoztatása, vagy függőleges mozgatási irányba bővítése. Fontos, hogy a megoldás során csak olyan kép (és bármilyen más, például hang) erőforrásokat használhatsz fel, amelyek kapcsán szerzői jogi kérdések nem merülnek fel. Tehát például írásos anyagot tudsz bemutatni, ami engedélyezi egyetemi kurzusokon, hallgatói dolgozatokban, munkákban történő felhasználásukat.

  3. A jelen jegyzet Jávácska ONE játékainak felélesztése Maven projektben, illetve NetBeans környezetben. Otthoni feladat: a következő laborra saját horgászhely fotózása.

  4. Saját horgász játék elkészítése

  5. LEGO™ NXT robot és Java MEJSR 82 alapú Bluetooth™ kommunikációs példa bemutatása.

  6. Saját szabadon választott továbbfejlesztés vagy portolás megbeszélése, a feladat kitűzése, elfogadása.

  7. A választott saját feladat fejlesztése.

  8. A választott saját feladat fejlesztése.

  9. A választott saját feladat fejlesztése.

  10. A választott saját feladat fejlesztése.

  11. A választott saját feladat bemutatása, értékelése. (Ha nem rendelkezel a szükséges készülékkel, akkor a DDN lehetőségei szerint a labor rendelkezésére bocsájtja a megfelelő eszközt.) A bemutatóról videó-dokumentáció készítése a laboron. (A kamerát a DDN lehetőségei szerint a labor rendelkezésére bocsájtja. )

  12. A választott saját feladat bemutatása, értékelése. A bemutatóról videó-dokumentáció készítése a laboron.

  13. A választott saját feladat bemutatása, értékelése. A bemutatóról videó-dokumentáció készítése a laboron.

  14. Érdemjegyek lezárása, rögzítése. Az utolsó labor végével bezárul az ajtó bármiféle javítási próbálkozás előtt, tehát dolgozz a félév közben!

Magas szintű programozási nyelvek 2

Egyetemünkön belül a legszélesebb közösséget képeznek a mérnök informatikus BSc szakon futó Magas szintű programozási nyelvek 2 című (INBK302E, INBK302L) kurzus hallgatói, mert a mérnökök számára a mobil programozás, LEGO robot programozás külön hangsúlyt kap. Ezért a jelen jegyzet (bár nem olyan részletesen programozott formában, mint azt a Mobil programozás esetén teszi) támogatást nyújt ehhez a tárgyhoz is az alábbiak szerint.

Javasolt használati esetek néhány labor erejéig

  • Az első laboron fordítsuk le a RobotCarRacing osztályt! Második feladatként a névtelen osztályok használata helyett írjuk át úgy a forrást, hogy minden viselkedés külön fordítási egységbe, azaz külön forrásba kerüljön és legyen egy „main jellegű” további osztály. Végül bővítsük a forrásokat „debug”

    System.out.println("Megy viselkedés");

    utasításokkal és figyeljük a tégla kijelzőjét!

  • A félév első felében dolgozzuk fel a Bluetooth® alapú LEGO robot távirányító példát.. Ezt teljes kidolgozással támogatjuk a LEGO mellékletben.

  • A félév második felében dolgozzunk ki egy esettanulmányt valamelyik Jávácska Kupára. Ezt részlegesen támogatjuk a LEGO mellékletben.

HTML, XML

Ugyancsak egyetemünkön belül, bár egy vékonyabb közösséget képeznek a programtervező informatikus BSc szakon futó HTML, XML című (INDK202L) kurzusom hallgatói. A jegyzet a focis játék „továbbfejlesztése” kapcsán korlátozottan itt is használható néhány labor erejéig.

Javasolt használati esetek a szurkolói avatárokkal kapcsolatban

  • Az első laboron validáljunk le néhány szurkolói avatárt! Második feladatként élesszük fel a Public Resource Football Computing projektet és validáljuk ezzel a szurkolói avatárokat!

  • A félév DocBook XML 5.0-ban összefoglalandó feladatait a foci iránt érdeklődő hallgatók szurkolói avatáros feladatokkal kiválthatják, helyettesíthetik.

  • Az [KAVATAR] cikk alapján az RDF-be (Resource Description Framework) konvertált szurkolói avatárjaikat SPARQL végpontunkon keresztül a szemantikus web részévé tehetik.

Játékgráfok

A mellékletben felvillantjuk a játékok tipikus képernyőképei közül a leggyakoribbakat, s két képenként néhány mondatos megjegyzéseket is fűzünk a pillanatfelvételekhez. Így részletesebb bepillantást kaphatsz a játékokba, könnyebben el tudod dönteni, melyikkel szeretnél foglalkozni.

A szerzőről

Bátfai Norbert, nbatfai@inf.unideb.hu

Bátfai Norbert 1996-ban szerzett programozó matematikusi, majd 1998-ban kitüntetéses programtervező matematikusi oklevelet a Debreceni Egyetemen. 1998-ban megnyerte a Java Szövetség Java Programozási Versenyét.

Bátfai Erikával közös mobil információtechnológiai cége, az Eurosmobil [EUROSMOBIL], második helyezést ért el 2004- ben a Motorola JavaJáték Versenyén, ugyancsak az Eurosmobil 2004-ben a Sun és a Nokia közös Mobil Java Fejlesztői Versenyén a „Ha hívsz, támadok!” (H.A.H) hálózati ( Java EE™ szerver, Java ME™ kliens) játéksorozattal első díjat nyert. A mobil játékfejlesztés elmélete és gyakorlata és a kék (JSR 82) játékok címmel előadott az Eurosmobillal a Sun Java Fejlesztői Konferencián 2005-ben.

Társszerzője a Fantasztikus programozás [J] című ismeretterjesztő kalandregény sorozatnak, illetve a 2007-ben megjelent Javát tanítok [JT] digitális szakkönyvnek. Szerzője e könyv elődjének, a Nehogy már a mobilod nyomkodjon Téged! [NEHOGY] című könyvnek.

Közel 10 évig volt a Debreceni Egyetem Informatikai Kar, Alkalmazott Matematika és Valószínűségszámítás Tanszékének munkatársa. Jelenleg ugyenezen a karon, az Információtechnológiai Tanszék egyetemi tanársegéde. Oktatási tapasztalata az alábbi előadásokon: Magas szintű programozási nyelvek 2, Operációs rendszerek, Operációs rendszerek 2; illetve az alábbi tárgyak gyakorlatain alapul Java esettanulmányok, J2SE hálózatok, Java appletek, CORBA, Programozás, Hálózatok, Formális nyelvek és automaták, Algoritmuselmélet, Bevezetés az informatikába, Operációs rendszerek, Alkalmazások fejlesztése WWW-re, XML-HTML, Objektumorientált programozás a középiskolában, Mobil programozás, Internettartalom menedzsment, Tartalomszolgáltatás, Magas szintű programozási nyelvek 2.

A VISZ (Vezető Informatikusok Szövetsége) a 2008-as évben az Év Informatikai Oktatójának választotta.

Jelen pillanatban doktori disszertációján dolgozik, az e könyv tárgyát képező mobil játékok is ennek a disszertációnak a keretében kerültek megnyitásra. A dolgozat és a tézisfüzetek [PHD] elérhetőek a honlapján.

Miért is írom ezt a könyvet?

A prózai ok magától érthetődő: egy pályázat, a TÁMOP 4.2.1 pályázat keretében írom, amiért megfizetnek.

Van számos további motivációm, amiket talán érdemes megemlíteni, mert nem nyilvánvalóak. Az egyik például, hogy az élesben 2010 januárjában elinduló Debreceni Fejlesztői Hálózat (röviden csak DDN) helyi népszerűségének növekedésével egyre több hallgató keres fel érdeklődéssel, a csatlakozás szándékával. Mint minden egyetemi fejlesztői közösség, a DDN is erősen épít a hallgatók között önszerveződéssel kialakuló, laza mentori hálózat szervező és tanító erejére: mert ha mindenki csak rám akar csatlakozni, az már néhány hallgató után is a diák-tanár, oktató-hallgató vagy fejlesztő-fejlesztő jellegű kapcsolatok minőségének rovására menne. A jelen könyv tartalmi kialakításával is a DDN hálózat életképességét szeretném szerény mértékben javítani.

Mire gondolok pontosan? Amikor az egyetemre kerültem, akkor azokban a közösségekben, amelyekbe mindenki természetesen bekerül (kollégiumi szoba, szakon belüli tanuló közösség, barátok stb.) természetes volt a mémek cseréje. Ennek tipikus eszköze, hogy ki milyen könyvet olvasott, milyen filmet látott, s akinek hiányossága volt, az a szorgalmi időszakban (sok esetben szívesen) bepótolta azokat. Tehát ennek a könyvnek az írása során igyekeztem olyan információkat, hivatkozásokat, szemléletmódot beleszőni a könyv testébe, ami elősegíti a közös informatikai mém készlet, azaz egy olyan közös mentális felület kialakítását, ami erősebben összeköthet minket mint leendő fejlesztő vagy oktató kollégákat. Ezért a DDN tagoknak, ahogyan a bevezető lapon említettem, a könyv fellapozása kötelező!

Tehát, akinek az alábbi listából van pótolnivalója, annak irány a könyvtár és a videó-kölcsönző! Láttad például

filmeket? Ha igen, akkor az jó kezdet, de nem sokat ér, ha nem olvastad őket könyvben is!

Olvastad hát

könyveket?

Kötelező mozik, olvasmányok

  • Ha a fent említett kultúrából még nem fogyasztottál, akkor a doksi szellemében [Hacker] pótold ezen hiányosságaidat!

A lektorokról

Bátfai Mária Erika, ebatfai@lib.unideb.hu

Bátfai Mária Erika a jegyzet szakmai lektora. 1997-ban szerzett magyar nyelv és irodalom tanári, majd 1998-ban finn tanári és informatikus könyvtárosi oklevelet a Debreceni Egyetemen.

Az Eurosmobilban Bátfai Mária Erika vezette a szóban forgó (megnyitott és a jelen jegyzetben tárgyalt) játékok tesztelését.

Illyés Ildikó, ilyesildiko73@yahoo.co.uk

Novák Ildikó a jegyzet nyelvi lektora. 1996-ban szerzett angol középiskolai tanári és informatikus könyvtáros oklevelet a Debreceni Egyetemen.

A szakmai lektor vélekedése a könyvről

A könyv sokak által közkedvelt témájú, megnyitott forrású játékokon át (horgászat, foci, ezotéria) játszi könnyedséggel vezeti be olvasóját a mobilprogramozba. Eközben szinte észrevétlenül érinti a fő alapfogalmakat (pl. CLDC, JSR, MIDP, API) és az alapvető programozási környezeteket (Marven, NetBeans).

Mellékleteként az összes részletesen kommentált forrás elérhető, amelyek így a könyv mellett mintegy járulékos segítséget adnak.

Külön kiemelendő, hogy a szerző egyaránt támogatást nyújt a GNU/Linux és Windows környezetben történő fejlesztéshez; valamint a játékok portolását nem csupán egy-egy telefonra, hanem adott esetben másik platformra például asztali gépre és böngészőben/alkalmazásként futtatható Appletre is elkészíti vagy megint csak adott esetekben teljes képernyős PC-s játékhoz vagy a Google Android platformjához ötletet ad, iránymutatást nyújt.

A könyv olvasása után akkor is mobilt szeretnék programozni, ha egyébként eszembe sem jutott volna – és sikerülni is fog.

A nyelvi lektor vélekedése a könyvről

Korábban a focit, a horgászatot, az ezotériát, csakúgy, mint a programozást csupa unalmas tevékenységként tartottam számon. Ezt a könyvet elolvasva azonban mind a négy tevékenységhez kedvet kaptam, hiszen Bátfai Norbert könyve olyan gyakorlatias megközelítésből tárja elénk a mobilprogramozás rejtelmeit, hogy egy laikus is késztetés érez a kipróbálására. Közvetlen nyelvezetével, könnyen követhető útmutatásaival és bőséges példáival minden segítséget meg is kapunk ehhez.



[1] Konkrétan a frame alapú animáció API szintű használata nem működött a specifikációnak, példáknak megfelelően. (A jelen jegyzetben elkészítjük az említett Androidos NehogyMar4 példát.)

[2] Az említett díj elnyerésében a bejelentésnek nem volt szerepe, csak a díjátadó szülte figyelmet használtuk ki arra, hogy ezt a bejelentést megtegyük. [PHD] .

[3] A licenc magyar fordítása be van linkelve ugyanerre a http://gnu.hu/gplv3.htm lapra.

I. rész - Tartalom menedzsment

Ebben a részben megtanuljuk, hogyan élesszük fel a megnyitott játékokat: mi módon készítsük el belőlük a valódi telefonra tölthető fájlokat. Illetve megnézzük, hogy milyen saját változatokat tudunk készíteni belőlük azzal a feltétellel, hogy a Java forrásprogramokat még nem módosítjuk, hanem csupán a játékok kép- és hangerőforrásait, esetleg a felhasználói felületük nyelvét változtatjuk meg.

1. fejezet - A játékok felélesztése

Ebben a fejezetben a Java ME™ platform rövid bemutatása után felélesztjük a játékokat és segítséget adunk ahhoz, hogyan töltsd őket fel valódi mobiltelefonodra.

Ennek megfelelően ebben a fejezetben

  • áttekinted a CLDC, MIDP, JSR, API fogalmakat

  • bemelegítésként felidézzük a korábbi „Nehogy már...” könyv forrásainak szerkezetét

  • letöltheted a könyvhöz mellékelt megnyitott játék-projekteket

  • megismered, hogyan kell Maven projektként

  • illetve NetBeans környezetben feléleszteni a megnyitott játékokat

  • végül meglátod, hogyan készíthetsz más nyelvű portolásokat a megnyitott játékokból.

„By 2012, 80 percent of all commercial software will include elements of open-source technology.”

A Java ME™ platform

 

„The GNU General Public Licence is the most popular and most widely used Free Software licence. The special thing about this licence is that it's a copyleft licence, that is to say: all versions of the program must carry the same licence. So the freedoms that the GNU GPL gives to the users must reach all the users of the program. And that's the purpose for which I wrote it.”

 
 --Richard Stallman [Stallman] Free and Open Source Java stallman3.ogg

A Java ME™ programozó API programozó, azaz programja írása során egy olyan világban, esetünkben egy olyan objektum orientált világban mozog, amelyet az API dokumentáció (a továbbiakban csak API doksi) ír le. Programjának elkészítése során, főleg eleinte, folyamatosan olvasnia kell az API doksit, hogy tudja használni, hogy jól megismerje azt a világot, amelyben le kell írnia programját. Az API doksi választ ad az olyan egyszerű kérdésekre, hogy milyen csomagok, objektumok, interfészek, metódusok vannak a világunkban, vagy a kicsit kifinomultabb kérdésekre, hogy ha származtatunk egy osztályból, akkor az osztály mely tagjait kell implementálnunk, akár üres testtel is, hogy sikerrel le tudjuk fordítani a programunkat.

Konfiguráció és profil

A Java ME™ platform kapcsán két alapvető fogalommal kell megismerkedned, ezek a fogalmak a konfiguráció és a profil. Természetesen ezen a platformon is Java nyelven fogalmazza meg szándékát, akaratát a programozó. A konfiguráció, esetünkben a Connected Limited Device Configuration (CLDC), a virtuális gép minimális tulajdonságait és a core API-t határozza meg. Előbbire példa az a kérdés, hogy tud-e a virtuális gép lebegőpontos számokkal dolgozni, azaz használható-e a nyelv float vagy double típusa? Utóbbira példák az e platformbeli a java.lang vagy java.util csomag osztályai lehetnek.

A Java ME™ platform.

A platform (esetünkben a Mobile Information Device Profil, MIDP) a konfigurációt egészíti ki további API-kkal, például a HTTP hálózatkezelést, a perzisztens tárolást vagy a felhasználói felületet absztraháló API-kat tartalmazza.

De számos, a programozó szempontjából fontos API van, ami nem része a MIDP profilnak. Ezeket a specifikációkat külön JSR (Java Specification Request) dokumentumokban fejlesztik és rögzítik. Ha például a Java programodból akarsz Bluetooth® kapcsolattal dolgozni, akkor olyan telefonnal kell tesztelned, ami megvalósítja a JSR 82 API-t, azaz implementálva van benne a Java APIs for Bluetooth. Tehát maga az, hogy a telefon egy Bluetooth® készülék, nem elég, egy JSR 82 készülékre lesz szükséged ebben az esetben. A gyakorlatban a legtöbb olvasó a saját telefonja kapcsán fog találkozni a JSR-ekkel: célszerű a készülék megvásárlása előtt szétnézni a gyártó lapjain, például, ha Nokia készüléket szeretnél, akkor a Fórum Nokia megfelelő lapjain.

[Fontos]Fontos

A CLDC, MIDP és általában a JCP-n (Java Community Process) belül életre kelt JSR dokumentumok csak specifikációk, olyan készüléket vásárolj, ami megvalósítja azokat a szabványokat, vagy a szabványok azon verzióit, amelyre szükséged van!

[Tipp]Olvasnál még róla? Olvass!

  • A Java API doksinál megszokott, frames böngészhető MIDP API doksiban ismerkedhetsz meg ennek az objektumorientált rendszernek a szerkezetével: a csomagokkal, osztályokkal, interfészekkel.

  • A MIDP specifikáció.

  • Királyi út nincs, ám itt a gyorstalpaló: ennek a könyvsorozatnak az előző tagja, a Nehogy már a mobilod nyomkodjon Téged! című könyvem.

[Megjegyzés]Nincs Java csapda

Voltak, akik aggódtak, hogy ugyan ők nyílt forráskódban fejlesztenek Javában, de saját munkájuk egy zárt kódú rendszertől függve csapdába eshet. Ezeket az aggályokat oszlatta el végleg, hogy a Sun 2006 novemberében mindhárom Java kiadás kódját megnyitotta a GNU GLP v2 licenc hatása alatt (ugyenez a licenc védi a GNU/Linux kernelt is). Ennek megfelelően a következő három reinkarnációban él tovább az említett három kiadás.

1.1. példa - A megjegyzések

Vegyük fel a fonalat! A következő néhány példában idézzük fel a Nehogy már a mobilod nyomkodjon Téged! [NEHOGY] könyv első, bevezető forrását!

A megnyitott források is ehhez a kódhoz hasonlóan lesznek bekommentezve, de a fájlokat kezdő megjegyzés hosszabb, mert magának a GNU GPL v3 licenc szövegének az iránymutatását követve itt helyeztük el a licencre utaló megjegyzésrészt is. A fejlesztés során törekedtünk betartani a Java kódolási konvencióit és természetesen neked is ezt ajánljuk. Az osztály forrása egy (az állomány nevét megadó és azt általánosan jellemző) megjegyzéssel indul.

                            
/*
 * NehogyMar1MIDlet.java
 *
 * Bátfai Norbert: Nehogy már a mobilod nyomkodjon Téged!
 * nbatfai@gmail.com
 *
 * Ezt a forrásfájlt (és a hozzá esetlegesen kapcsolódó erőforrásokat,
 * például képeket) letöltheted a http://www.eurosmobil.hu/NehogyMar/
 * címről.
 *
 */
                        

Ezt egy olyan speciális megjegyzés követi, ami bekerül az osztály dokumentációjába. Ezt a tipikusan böngészhető dokumentációt a javadoc programmal vagy néhány kattintással magával a NetBeans környezettel generálhatod le. Ha továbbfejlesztesz egy osztályt, akkor ne felejtsd el hozzáadni a saját author tagodat és növelni a version tag értékét.

/**
 * A könyv első programozási példája, bemutatja a
 * MIDlet osztály használatát: a MIDlet objektumok
 * életét irányító startApp(), pauseApp() és
 * destoyApp() metódusok használatát.
 *
 * @author Bátfai Norbert, nbatfai@gmail.com
 * @version 0.0.1
 */
                        

[Tipp]Olvasnál még róla? Olvass!

Fejlesztőként Te már egy olyan környezetben fogsz dolgozni, melynek alapjellemzője a csoportmunka. Ha már láttál olyan forrást, amit több különböző kommentezési stílust, egyéni szokást felvett programozó is karbantartott, akkor nem ismeretlen előtted az a tapasztalat, hogy a kommentek csinosítgatásával megy el az első néhány óra... Nos, ezért jó, ha egy nyelvhez vannak rögzített konvenciók: ajánlások, amik rögzítik, hogyan nevezd el az osztályaidat, azok metódusait, a változókat, hogyan kommentezd a forrásodat stb.

  • A Java kódolási konvencióit itt böngészheted,

  • vagy letöltheted például egy pdf könyv formájában.

  • Királyi út nincs, ám itt a gyorstalpaló: a belinkelt dokumentumok végén nézd meg a szereplő, egyszerű publikus osztály példájának forrását!

  • Arról, hogyan tudod jól kihasználni a javadoc lehetőségeit, példákkal bőven fűszerezve itt olvashatsz.

Mi minden forrásunk esetén a GNU GPL v3 licenc használatát jelző alábbi - például éppen a KapitalisVaszon.java forrásból kivágott - megjegyzést fűzzük a fájlok elejéhez. Minden esetben a forrás korábbi életéből származó verziótörténetből is meghagytunk valamennyit, mert történeti szempontból ez még érdekes lehet.

/*
 * KapitalisVaszon.java
 *
 * Bátfai Norbert: Mobiltelefonos játékok tervezése és fejlesztése
 * Doktori (PhD) értekezés, Debreceni Egyetem, Informatikai Kar,
 * Információtechnológia Tanszék, http://www.inf.unideb.hu/~nbatfai/phd/
 *
 * Copyright (C) 2010, Bátfai Norbert
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * Ez a program szabad szoftver; terjeszthető illetve módosítható a
 * Free Software Foundation által kiadott GNU General Public License
 * dokumentumában leírtak; akár a licenc 3-as, akár (tetszőleges) későbbi
 * változata szerint.
 *
 * Ez a program abban a reményben kerül közreadásra, hogy hasznos lesz,
 * de minden egyéb GARANCIA NÉLKÜL, az ELADHATÓSÁGRA vagy VALAMELY CÉLRA
 * VALÓ ALKALMAZHATÓSÁGRA való származtatott garanciát is beleértve.
 * További részleteket a GNU General Public License tartalmaz.
 *
 * A felhasználónak a programmal együtt meg kell kapnia a GNU General
 * Public License egy példányát; ha mégsem kapta meg, akkor
 * tekintse meg a <http://www.gnu.org/licenses/> oldalon.
 *
 * Dokumentáció: készül a "Nehogy már megint a mobilod nyomkodjon Téged!"
 * című egyetemi jegyzet. Fő célja a megnyitott források kapcsán a Debreceni
 * Egyetem Informatikai Karának Mobil programozás laborját támogatni. A
 * jegyzet DocBook XML-ben készül, továbbá a "Nehogy már a mobilod nyomkodjon
 * Téged!" című könyv folytatásának szánjuk, további információk majd a szerző
 * honlapján: http://www.inf.unideb.hu/~nbatfai
 *
 * --------------------------------------------------------------
 *
 * Motorola E398, V300
 *
 * 2004. szept. 4.
 * 2005. dec. 24., Téli Kapitális
 * 2005. dec. vége, Úszós
 * 2006. febr. 28, 100% Horgászat
 * 2010. febr. 4. - OSE
 *
 *
 * --- Ragadozó Fenekező-ból a Téli Kapitális-ből úszós ---
 * --- 102Nyari_NOK403rd_240, 2007.02.11
 *
 * EUROSMOBIL Játék- és Alkalmazásfejlesztő Bt.
 * http://www.eurosmobil.hu
 * Bátfai Norbert
 *
 * Verziótörténet:
 * 0.1.0    start
 * 0.1.1    kapásjelző helyett úszó a téliben
 * 0.1.2    2006.01.02, portolások előtti átnézés, takarítás
 * 0.1.3    MIDlet.megvan()-ba téve a mindKifogva vizsgalat (csak halfogaskor)
 * 0.1.4    100% Horgászat: HÚZ-TEKER fárasztás (bot animáció - is könnyen lehetne, de most nincs)
 * 0.1.5    2006.05.28, 102% Kapitális, vékonyabb damillal, kisebb horoggal is felveszi a
 *          csalit, majd a farasztasnal esetleg leakad stb.
 * 0.2.0    2010.02.10, OSE, Maven projekt
 *
 */
                        

1.2. példa - A MIDlet osztály

A forrásokban tartózkodunk az importálásoktól, ezért tipikusan a teljes csomagnévvel minősítve írjuk az osztályok neveit, azaz a szóban forgó forrás tekintetében a MIDlet osztály előtt a tartalmazó csomagnevet is szerepeltetjük, esetünkben tehát a javax.microedition.lcdui csomagnévvel minősített MIDlet osztályból származtatunk.

                            
public class NehogyMar1MIDlet
        // Kiterjesztjük a MIDlet osztályt:
        extends javax.microedition.midlet.MIDlet
        // Figyelünk majd parancsokra:
        implements javax.microedition.lcdui.CommandListener {
                        

Következnek a példánytagok, például programunk kilépés (softkey) gombját a javax.microedition.lcdui.Command osztálybeli kilepesGomb objektum reprezentálja majd.

                                
    /** A mobiltelefon kijelzőjét reprezentáló objektum. */
    javax.microedition.lcdui.Display mobilKijelzoje =
            javax.microedition.lcdui.Display.getDisplay(this);
    /** A Kilépés gombot reprezentáló objektum. */
    javax.microedition.lcdui.Command kilepesGomb =
            new javax.microedition.lcdui.Command("Kilépés",
            javax.microedition.lcdui.Command.EXIT, 20);
    /** Egy "karatkeres" képernyőt reprezentáló objektum. */
    javax.microedition.lcdui.Form karakteresKepernyo;
                            


1.3. példa - Az API doksi használata

Itt emlékeztetőül azt emeljük ki, hogy az API doksinak megfelelően az ott protected módosítóval jelölt startApp(), pauseApp() és destroyApp() metódusokat implementáltuk a saját MIDlet osztályunkban.

    /** Mit tegyek én (this, azaz az aktuális MIDlet objektum)
     * ha elindítottak? */
    public void startApp() {
        // Elkészítek egy "karakteres" képernyőt
        karakteresKepernyo =
                new javax.microedition.lcdui.Form("Nehogy már a");
        // aminek a címe az, hogy "Nehogy már a"
        // Erre a "karakteres" képernyőre pedig ráteszek egy
        // szöveges elemet, ami két részből áll
        karakteresKepernyo.append(new
                javax.microedition.lcdui.StringItem("Nehogy már a",
                "mobilod nyomkodjon Téged!"));
        // Legyen a kijelzőn az imént készített
        // "karakteres" képernyő látható!
        mobilKijelzoje.setCurrent(karakteresKepernyo);
        // Legyen a "karakteres" képernyőn a Kilépés parancs!
        karakteresKepernyo.addCommand(kilepesGomb);
        // Aztán, ha kattintanak rajta, akkor majd
        // én (this, azaz az aktuális MIDlet objektum)
        // reagálok erre a commandAction() viselkedésemben.
        karakteresKepernyo.setCommandListener(this);
    }
    /** Mit tegyek én (this, azaz az aktuális MIDlet objektum)
     * ha futásom közben jön egy SMS, vagy hívja valaki a
     * tulajomat? */
    public void pauseApp() {
    }
    /** Mit tegyek én, ha futásomnak vége... */
    public void destroyApp(boolean unconditional) {
    }
                        

Alig néhány (az eseménykezeléssel kapcsolatos) sor maradt ki a korábbi Nehogy már a mobilod nyomkodjon Téged! [NEHOGY] könyv bevezető forrásából, ami mindössze a Kilépés gomb megnyomásának kezelésére, de ezt elég unalmas lenne megismételve tárgyalni, ezért térjünk is rá a megnyitott forrásokra.

A játékok felélesztése

 

„Tapasztalatunk szerint a program minőségének legjobb kritériuma az olvashatóság: ha egy program könnyen olvasható, valószínűleg jó; ha nehezen olvasható, valószínűleg nem jó.”

 
 --Kernighan-Plauger [KERNIGHANP] A programozás magasiskolája

Ha ki akarod próbálni a könyvben tanultakat, vagy egyszerűen csak futtatni akarod a könyv játékait a mobilodon, akkor is le kell töltened a forrásokat, a források által használt és megszervezett erőforrásokat és ezekből el kell készítened a telefonra tölthető állományokat!

A játékok letöltése forrásban

[Megjegyzés]Letöltési alternatívák

A megnyitott játékok elérésére számos további alternatív lehetőséget tudunk ajánlani, ezeket a Jávácska One tippben ismertettük részletesen.

Minden játékot külön zip fájlba csomagoltunk, az archívumon belül megtalálod a Java forrásfájlokat az src/main/java könyvtárban és a kapcsolódó, szüksége erőforrásokat a src/main/resources könyvtárban.

Kérdés, hogy a NetBeans környezetet vagy a Maven-t használod (azaz tulajdonképpen IDE független vagy)?

  • A NetBeans használatának esetére a korábbi: a Nehogy már a mobilod nyomkodjon Téged! című könyv leírja, hogyan tudsz egy új projektet elkészíteni, de készítettem egy rövid filmet is, amit ebbe a vetítésbe ágyazva találsz meg.

  • A Maven használata esetén nem kell mást tenned, mint a mvn package parancsot kiadnod és a telefonra tölthető állományok automatikusan elkészülnek. (Ezzel az esettel kapcsolatban további részleteket találsz a projektek gyökerében a README.txt fájlokban.)

A játékok felélesztése Maven projektben

Néhány képernyőkép felvillantásával Linux és Windows alól is beizzítjuk a Maven projekteket.

A 110% Nyári Kapitális NYFK installálása Windows alatt

  1. Első lépés a Maven beszerzése és beállítása: töltsd le a projekt lapjáról! Itt én most a apache-maven-3.0-alpha-6-bin.zip állományt választottam.

  2. A letöltött állományt a c:\Users\Norbi\Prg\apache-maven-3.0-alpha-6\ könyvtárba csomagolom ki.

  3. Beállítom ennek megfelelően az M2_HOME és az M2 változókat, illetve módosítom a PATH-ot az alábbiak szerint. Az M2_HOME változót a kicsomagolt c:\Users\Norbi\Prg\apache-maven-3.0-alpha-6\ könyvtárra, az M2-t ennek a bin könyvtárára, az elérési utat pedig frissítem ugyancsak a kicsomagolt bin könyvtárával. Fontos, hogy a JAVA_HOME is legyen beállítva, ennek kapcsán további infót találhatsz a korábbi „Nehogy már...” könyvben, de elég annyi, hogy ránts le egy JDK-t és állítsd a könyvtárára a JAVA_HOME és ennek bin-jével bővítsd az elérési utat!

    Maven beállítása parancssorból.

    Maven beállítása panelen.

  4. Miután az imént látott módon, az mvn -version parancs kiadásával meggyőződtem arról, hogy a Maven beállításaival minden OK, lefordíthatom a saját projektünket. Ezt a Jávácska One tippben ismertetett címről rántom le például, majd kicsomagolgatva belépek, megint csak például a horgászos projekt c:\Users\Norbi\Documents\NehogyMarMEGINT\nyari-kapitalis-1.0.0\ könyvtárba gyökerébe. Ahol nincs is más dolgom, mint a

                                                
    C:\Users\Norbi\Documents\NehogyMarMEGINT\nyari-kapitalis-1.0.0>mvn package
                                            

    parancsot kiadni, miután is a projekt elkészül, s a telefonra tölthető állományok a target, tehát a c:\Users\Norbi\Documents\NehogyMarMEGINT\nyari-kapitalis-1.0.0\target\ könyvtárban keletkeznek.

  5. A target könyvtárba generált nyari-kapitalis-1.0.0-me.jad és nyari-kapitalis-1.0.0-me.jar fájlok a telefonra tölthető állományok (hogy melyik éppen, az készülékfüggő, ha megakadsz, további infókat a korábbi „Nehogy már...” könyvben találsz). Ha a Java ME SDK 3.0 SDK-d, vagy a Sun Java Wireless Toolkit 2.5.2_01 for CLDC szimulátorod megfelelően installálva van, akkor a jad fájlon kattintva máris mehet a horgászás!

    Indul a szimulátorban a horgász program.

    A legtöbb gyártó saját készülék-specifikus szimulátorait is használhatod, ezekről is szólunk a számtalanszor hivatkozott korábbi „Nehogy már...” könyvben, például Sony Ericsson készülékek esetén a Sony Ericsson SDK for the Java ME platform 2.5.0.6 tetszhet.

A játékok felélesztése Maven projektben GNU/Linux alatt

Itt lényegesen egyszerűbb az életünk, ami nem meglepő: lévén egy programozási projektről van szó. A Linuxunkon tipikusan menni fog az mvn parancs. Ha mégsem, akkor például Ubuntu alatt a

                                    
norbi@sgu:~$ sudo apt-get install maven2
                                

parancs azonnal felrántja a gépre. Nincs más dolgunk, mint lerántani és kicsomagolni a vágyott megnyitott játék projektjét, majd belépni ide, a pom.xml állományt tartalmazó szintre, például magam:

                                    
cd Dokumentumok/Projects/NehogyMarMEGINT/javacska-one-1.0.0-projects/nyari-kapitalis-1.0.0/
                                

és itt kiadni az mvn package parancsot, mely eredményeként a telefonra tölthető állományok elkészülnek.

GNU/Linux alatt fut az mvn package parancs.

A képen a szöveges kimenetet megfigyelve észrevehetjük, hogy a pom.xml állományból a mobil programok obfuszkálását (obfuscation) is elvégezzük.

   <plugin>
                <groupId>com.pyx4me</groupId>
                <artifactId>j2me-maven-plugin</artifactId>
                <version>${me2Version}</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>package</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <encoding>UTF-8</encoding>
                    <fileEncoding>UTF-8</fileEncoding>
                    <inputEncoding>UTF-8</inputEncoding>
                    <outputEncoding>UTF-8</outputEncoding>
                    <useWtkLibs>false</useWtkLibs>
                    <proguardPreverify>true</proguardPreverify>
                    <proguard>true</proguard>
                    <obfuscate>true</obfuscate>
                                

1

Kérjük a projekt obfuszkálását, az Apache licenccel elérhető pyx4me Maven plugint használva.

Ennek itt nem az a jelentősége, hogy a programunk bájtkódját ne lehessen visszafejteni, hanem az, hogy az eredmény Java archívumok méretét csökkentsük. A Proguard obfuszkátort használjuk erre a célra, mely innen is letölthető, de a mai NetBeans verziók is tartalmazzák már. Megemlíthetjük, hogy vannak olyan esetek, amikor az obfuszkátor használatát nem is mellőzhetjük: amikor mobilunkon kriptográfiát, például a Bouncy Castle kriptográfiai csomagot kell alkalmaznunk, használnunk.

A játékok felélesztése NetBeans környezetben

Az iménti ponthoz hasonlóan néhány képernyőkép felvillantásával Linux és Windows alatt is beizzítjuk a NetBeans környezetben a projekteket. De mivel a NetBeans egy Java alapú GUI-s eszköz, így a két platformon nincs különbség a használatában. (Pusztán a telepítésében van annyi differencia, hogy előbbi esetben egy .sh állományt, utóbbiban egy .exe állományt, a telepítőt kell lefuttatnod.) Ezért most elég például a Windowsos képeket mutatnunk.

A 110% Nyári Kapitális NYFK installálása a NetBeans-ben

  1. Első lépés természetesen a NetBeans beszerzése: töltsd le a projekt lapjáról! Magam ezt az IDE-t sokszor használom mindhárom Java kiadás: Java SE™, Java ME™, Java EE™ esetén (például még arra is képes, hogy Portleteket deployoljak fel egy futó WebSynergy portálra), ezért itt a letöltési mátrixból azt szoktam választani, amelyben minden benne van, most tehát a netbeans-6.8-ml-windows.exe állományt töltöttem le. Futtasd le, s a NetBeans rendben is van. Feltéve, hogy korábban már lerántottál egy JDK-t! Ha nem tudod, hogy ez miért kell, akkor nem árthat fellapozni a korábbi „Nehogy már...” könyvet, de mindenesetre töltsd le (jelen pillanatban az aktuális a JDK 6 Update 18) és hasonló módon telepítsd fel!

  2. Most hozz létre a NetBeans-ben egy mobilos projektet!

    Projekt létrehozása a NetBeans-ben

    Java ME rojekt létrehozása a NetBeans-ben

    A SajatHorgaszom nevet adjuk a projektnek.

    A SajatHorgaszom nevet adjuk a projektnek.

    Beállítjuk a megcélzott platformot, a játéknak CLDC 1.0 és MIDP 2.0 kell, de a valódi telefonod is biztosan tudja ezt.

    A SajatHorgaszom CLDC 1.0, MIDP 2.0 projekt lesz.

  3. Erre a projektek fülben megjelenik a projekted.

    Erre a projektek fülben megjelenik a projekted.

    Amin egy jobb gombot nyomva hozzá tudsz adni a projekthez egy MIDlet osztályt, aminek a neve fontos, hogy megegyezzen a megnyitott KapitalisMIDlet.java forrásbeli nyilvános MIDlet osztály nevével!

    Egy MIDlet hozzáadása.

    A KapitalisMIDlet a MIDlet osztályod neve.

    Erre az IDE ki is tölti néhány sorral az újonnan létrejött forrásodat (a MIDlet osztály absztrakt metódusaira ad egy üres testű implementációt).

    A MIDlet osztály absztrakt medódusainak alapértelmezett üres testű implementációi az IDE-ben.

    Amire Neked nem lesz szükséged, ezért másold be a letöltött és kicsomagolt horgász játék c:\Users\Norbi\Documents\NehogyMarMEGINT\nyari-kapitalis-1.0.0\src\main\java\ könyvtárából a Java forrásokat a saját projekted c:\Users\Norbi\Documents\NetBeansProjects\SajatHorgaszom\src\ könyvtárába. Ekkor az IDE-ben rögtön megjelenik az új tartalom.

    Megjelent a KapitalisMIDlet.java valódi tartalma.

  4. Immár csupán a kép- és hangerőforrások megadása választ el minket a teszteléstől. Újra nyomj jobb gombot a projekt nevén, majd válaszd a Properties menüpontot!

    A projekt tulajdonságainak beállítása.

    Itt közben készíts egy res könyvtárat a c:\Users\Norbi\Documents\NetBeansProjects\SajatHorgaszom\src\ könyvtárral egy szinten és másod be ide a c:\Users\Norbi\Documents\NehogyMarMEGINT\nyari-kapitalis-1.0.0\src\main\resources\ könyvtár tartalmát! S ezt a könyvtárat add meg a párbeszédablakban!

    A res könyvtár hozzáadása.

    Megjelentek az erőforrások.

  5. Nincs más dolgunk, mint az F6 gomb lenyomásával futtatni a projektet.

    A horgász játék fut a szimulátorban.

A játékok új nyelvre fordítása

Mindhárom játékra igaz, hogy szöveges literálokat nem találunk elszórva a kódban, hanem minden szöveges erőforrás a Szoveg.java állományban van összegyűjtve.

1.4. példa - A Szoveg.java állományok szervezése

/**
 * Szöveg erőforrások.
 *
 * @author      Bátfai Norbert
 * @version     0.1.5
 */

interface Szoveg {

    // névjegy infók
    public static final String nevjegyFej =  "110% Nyári Kapitális OSE\n";
    public static final String nevjegyTest = "Copyright (C) 2010, Bátfai Norbert\nEz a program szabad szoftver; terjeszthető illetve módosítható a Free Software Foundation által kiadott GNU General Public License dokumentumában leírtak; akár a licenc 3-as, akár (tetszőleges) későbbi változata szerint.\n\nEz a program abban a reményben kerül közreadásra, hogy hasznos lesz, de minden egyéb GARANCIA NÉLKÜL, az ELADHATÓSÁGRA vagy VALAMELY CÉLRA VALÓ ALKALMAZHATÓSÁGRA való származtatott garanciát is beleértve.\n\nhttp://www.inf.unideb.hu/~nbatfai/phd/";

    // Ált. játék infó
    public static final String jateknev = "110% Nyári Kapitális OSE";
    public static final String jatekcimFej = "110% Nyári OSE\n";
                    

Tehát a játékok nyelvi portolása mindössze annyi, hogy ebben a Szoveg.java állományban elvégezzük a fordítást, illetve még a Parancs.java fájlban kell lefordítanunk a célnyelvre az itt szereplő parancsok szövegét.

1.5. példa - A Parancs.java állományok szervezése

/**
 * Parancsok felsorolása.
 *
 * @author      Bátfai Norbert
 * @version     0.1.1
 */
interface Parancs {

    // Kilépés a MIDletből
    public static final javax.microedition.lcdui.Command kilep =
            new javax.microedition.lcdui.Command("Kilép",
            javax.microedition.lcdui.Command.EXIT, 25);
    public static final javax.microedition.lcdui.Command kilep2 =
            new javax.microedition.lcdui.Command("Kivesz",
            javax.microedition.lcdui.Command.EXIT, 25);
    // Ált. tovább a kezdő formokról
    public static final javax.microedition.lcdui.Command tovabb =
            new javax.microedition.lcdui.Command("Horgászat",
            javax.microedition.lcdui.Command.SCREEN, 1);
                    

A fejezet feladatainak összefoglalása

A feladatok mellett feltüntetett szám a feladat általunk feltételezett nehézségére utal. Az egy pont a jegyzetben mutatottak egyszerű megismétlését jelenti, a maximális húsz a teljesen egyéni munkát.

  1. Éleszd fel Maven környezetben valamelyik megnyitott játékot! (2 pont)

  2. Éleszd fel NetBeans környezetben valamelyik megnyitott játékot! (2 pont)

  3. A pom.xml módosításával változtasd meg a generált JAD (Java Application Descriptor) adatait! (2 pont)

                        <jadAttributes>
                            <MIDlet-Name>${project.name}</MIDlet-Name>
                            <MIDlet-Icon>/ikon.png</MIDlet-Icon>
                            <MIDlet-Vendor>${project.organization.name}</MIDlet-Vendor>
                            <MIDlet-Version>1.0.0</MIDlet-Version>
                            <MicroEdition-Configuration>CLDC-1.0</MicroEdition-Configuration>
                            <MicroEdition-Profile>MIDP-2.0</MicroEdition-Profile>
                            <Created-By>Batfai Norbert</Created-By>
                        </jadAttributes>
                        <midlets>
                            <MIDlet>
                                <name>${project.name}</name>
                                <icon>/ikon.png</icon>
                        
  4. A NetBeans Refactor használatával nevezd át valamelyik játék MIDlet osztályát! (2 pont)

  5. Készíts egy új nyelvi portolást valamelyik megnyitott játékhoz! (5 pont)

2. fejezet - A játékok erőforrásainak lecserélése

Nagyon könnyen lehet sikerélményünk, ha ezt a fejezetet dolgozzuk fel. Mert tipikusan nem kell mást tennünk, mint kisétálni kedvenc horgászhelyünkre, ott kattintani néhányat digitális fényképezőnkkel és gyakorlatilag szinte már kész is van egy új, egy saját portolásunk a horgász játékból!

Tehát ebben a fejezetben

  • megismered, hogy milyen képerőforrásokat és hogyan használunk a programokban

  • készíthetsz egy saját horgász játékot

  • vagy módosíthatod, lecserélheted a focis játék csapatait a sajátjaidra.

„However, new winds blew in from the Hungarian Steppe. The Hungarian team played with two inside forwards in the front line and the center forward withdrawn”

Björn Bolling [Bolling] Football (Soccer) Handbook of Sports Medicine and Science

Képek lecserélése

 

„Az online közösségi játékok – amelyekben a fejlesztések főhangsúlya a grafikáról a mesterségesintelligencia-megoldásokra helyeződik át – a valós és a virtuális világot összekapcsoló majdani globális méretű információs tér meghatározó részeként, a jelenleginél sokkal fontosabb tudatformáló tényezőkké válnak.”

 
 --Kömlődi Ferenc [NHIT] Égen-földön informatika: az információs társadalom technológiai távlatai

A szereplő képerőforrások cseréjét igazán a horgász és a focis játék kapcsán értelmezhetjük. Előbbi esetén a játékból készíthetünk olyan portolásokat, melyekben a saját horgászhelyünk, vagy akár saját halaink képe jelenik meg. Az előbbi feladat nem feltételezi, hogy a Java forráskódokhoz egyáltalán hozzányúljunk, az utóbbi esetén, ha újabb halfajokat is szerepeltetni akarunk, akkor némi visszakommentezést kell eszközölnünk a forrásokban.

A foci játék esetén a labdarúgók mozgását (ez konkrétan most az állás és a futás) megadó kereteket cserélhetjük le könnyen. Ha viszont további mozgásokat is szeretnénk megjeleníteni: például a játékos megfordulását, fejelést, rúgást stb., akkor ennek az átalakításnak megfelelően majd a kódhoz is hozzá kell nyúlnunk.

Új horgászhelyes portolás elkészítése

Tegyük fel, hogy készítettél néhány fotót kedvenc horgászhelyedről! Vágd ki a képnek azt a részét, amit a mobil játékba át akarsz tenni: hogy minél egyszerűbb legyen, ez a rész arányaiban jó, ha 240 pixel x 320 pixel méretű, mert majd ekkorára kell átméretezned, s ennek során nem torzul majd a kép. (Tipikus megoldás, hogy először átméretezed nagyjából és ebből az átméretezettből vágsz ki egy 240x320 méretű téglalapot.)

A horgászhely fotójának kivágott és 240x320 pixel méretűre alakított képe.

Majd vágd fel ezt a 240x320 méretű képedet két 240x160 méretű részre, azaz középen vágd ketté! Ezzel két képet kapsz: a horgászhely tetejét és alját.

A horgászhely fotójának kivágott és 240x320 pixel méretűre alakított képének felső része. A horgászhely fotójának kivágott és 240x320 pixel méretűre alakított képének alsó része.

A felső részt mentsd el hhely1.png, az alsót pedig hhely2.png néven. Ezzel majdnem kész is a saját portolásod előkészítése. Annyi van még, hogy az alsó kép tetejéből vágj ki egy szabálytalan darabot és ments el hhely2szel.png néven, ezt fogjuk majd picit mindig 1-2 pixellel máshova elmozgatva rárajzolni az alsó képre, hogy a víz enyhe mozgásának illúzióját keltsük az úszók körül.

A hhely2szel.png fájl tartalma.

Készen is vagy! Írd felül a res könyvtárad (vagy Maven használata esetén resources könyvtárad) képeit az új képekkel és máris mehet az újrafordítás.

[Tipp]A képek kezelése

  • Dolgozz a GIMP programmal! Ez egy szinte minden platformra letölthető, GNU-s képfeldolgozó program, amelynek használatát már a korábbi Nehogy már könyvben bevezettük.

  • A képfájlok méretét jelentősen csökkentheted, ha beindexelt színeket használsz. Alakíts ki egy megfelelő méret/minőség arányt! A GIMP programban ehhez válaszd a Kép/Mód/Indexelt... menüt.

Saját horgászjátékod elkészítése

  1. Az imént olvasottak alapján készítsd el saját horgászos játékod! Az alábbi pontokban magam is megteszem, hogy bemutassam, milyen egyszerű dologról van szó.

  2. Ma reggel zsebre vágtam a digitális fényképezőgépem (persze a mobilom is megtette volna) és a munkalyemre (a kép jobb felső sarkában a fák mögött sápadtan derengő sárga épület) jövet beugrottam az innen alig 100 méterre lévő egyetemi Botanikus Kertbe (http://botkert.unideb.hu/), ahol lefotóztam a tavat.

    Fotó a Botanikus Kertben.

  3. Ebből a fotóból átméterezés után kivágva elkészítettem az alábbi 240x320-as méretű képet.

    Az átméretezett fotóból kivágott 240x320-as méretű részkép.

  4. Középen kettévágva elkészítettem a horgászhely tetejét és alját.

    Az új horgászhely fotójának kivágott és 240x320 pixel méretűre alakított képének felső része.

    Az új horgászhely fotójának kivágott és 240x320 pixel méretűre alakított képének alsó része.

  5. Az alsó kép felső részéből az úszók környékéről kijelöltem egy szabálytalan darabot és külön kimentettem.

    Az új hhely2szel.png fájl tartalma.

  6. Majd ezzel a három képpel felülírtam a projektben az eredeti képeket, újra buildeltem és íme alább az eredmény.

    2.1. táblázat - Pillanatkép a most elkészített Saját horgász játékból

    Pillanatkép a Saját horgász játékból.

    Pillanatkép a Saját horgász játékból.


    2.2. táblázat - Pillanatkép egy kisebb kijelzőjű szimulátorban a Saját horgász játékból

    Pillanatkép a Saját horgász játékból egy kisebb képernyőméretű szimulátorban.

    Pillanatkép a Saját horgász játékból egy kisebb képernyőméretű szimulátorban.


Új focis portolás elkészítése

Technikailag ebben az esetben is ugyanúgy kell eljárnod, mint az előbbi, a horgászos példa esetén. Esetleg egy valami lehet meglepő, nevezetesen az, hogy a korábbi Nehogy már könyv keret alapú animációjánál is látott esettől (azaz amikor a mozgás minden kerete egy állományban van összegyűjtve) eltérően itt minden keretet külön állományba mentve találsz.

A korábbi Nehogy más könyv keret alapú animációjának kereteket tartalmazó állománya. (Az említett Nehogy már 7-es példában a MIDP 2-ben megjelent Game API Sprite osztályát használtuk az animációknál.)

A szimmetrikus állapotokat tükrözzük, a többi csapat mezének színeit pedig az RGB kódok manipulálásával állítjuk elő a kódban, ezt majd később bemutatjuk.

A („saját ”, a magyar csapatbeli) labdarúgó futását (tükrözéseket nem számolva) kilenc keret alkotja.

2.3. táblázat - A „saját ” labdarúgó futásának keretei

A labdarúgó futásának kerete.

A labdarúgó futásának kerete.

A labdarúgó futásának kerete.

A labdarúgó futásának kerete.

A labdarúgó futásának kerete.

A labdarúgó futásának kerete.

A labdarúgó futásának kerete.

A labdarúgó futásának kerete.

A labdarúgó futásának kerete.


A labdarúgó állását (tükrözéseket nem számolva) két keret alkotja. A labdarúgó állásának kerete.

A labdarúgó állásának kerete.

A másik csapatbeli (az „ellen ”, a színei miatt a német csapatbeli) labdarúgó futását (tükrözéseket ugyancsak nem számolva) megint csak kilenc keret alkotja, ezek a következők.

2.4. táblázat - A „ellen ” labdarúgó futásának keretei

A labdarúgó futásának kerete.

A labdarúgó futásának kerete.

A labdarúgó futásának kerete.

A labdarúgó futásának kerete.

A labdarúgó futásának kerete.

A labdarúgó futásának kerete.

A labdarúgó futásának kerete.

A labdarúgó futásának kerete.

A labdarúgó futásának kerete.


A másik csapatbeli labdarúgó állását is (tükrözéseket nem számolva) két keret alkotja. A labdarúgó állásának kerete.

A labdarúgó állásának kerete.

Női foci

  • Az imént olvasottak alapján készítsd el a játék női focis változatát! Nem kell mást tenned, mint mondjuk egy kamerával rögzíteni a futó hölgy futását állását és az imént felvillantott, szereplő kereteket lecserélned a filmből kikockázottakra.

[Tipp]A focista kereteinek kivágása

  • Ha megvannak a mozgás új keretei, dolgozd fel őket a GIMP programmal! Néhány egérkattintással ki tudod jelölni a képeken a focista hölgyet, hogy aztán az útvonal szerint kijelölve betehesd egy transzparens keretbe.

A játékban minden játékosnak egy aktuális kerete van kirajzolva, annak megfelelően, hogy éppen áll vagy fut. Az imént a saját és az ellen jelzőket a csapatok előtt azért szerepeltettük idézőjelek között, mert a játékos megválaszthatja, hogy éppen kivel akar lenni az aktuálisan egymásnak feszülő két csapat közül.

A játékos megválaszthatja, hogy éppen kivel akar lenni az aktuálisan egymásnak feszülő két csapat közül.

A fájlból betöltött keretek színeit (vörös, illetve fehér-fekete) viseli a magyar, illetve a német válogatott.

A fájlból betöltött keretek színeit (vörös, illetve fehár-fekete) viseli a magyar, illetve a német válogatott.

A játékban szereplő többi hat: francia, brazil, angol, amerikai, svéd és olasz nemzeti válogatottakat jellemző mezszínű kereteket, mint említettük nem képfájlból töltjük be, hanem a szoftverben, a betöltött két csapatbeli játékoskeretekből kombináljuk ki a képpontok RGB kódjainak manipulálásával. Erre azért van szükség, mert a szereplő két (természetesen beindexelt színű) keret garnitúra mérete 14 kilobájt, ha a többi hat csapatot is képként töltenénk be, az további 42 kilobájtot jelentene.

                            
    protected int r, g, b;

    protected void mezek(int sajat, int ellen) {

        // RGB feldolgozas

        int melyikbol = 0; // 0 vagy 1, hogy a ket betoltott csapatbol
        // melyiket kell atszinezni hozza
        int hanyadik = 0; // hogy melyik alg csinálja meg:
        // az elsőből:
                       /* 0
        // eredeti
        // vörösök - magyarok
         */

        /* 1
        //kékek - franciák
        r = (buffer[j] & 0x00ff0000) >> 16;
        g = (buffer[j] & 0x0000ff00) >> 8;
        b = buffer[j] & 0x000000ff;
        buffer[j] = r|g<<8|b<<16| 0xff000000;
         */

        /* 2
        // sárga - brazilok
                        

Bekommentezve láthatóak a majdani tényleges átalakítások. Az eredeti képpont R, G és B komponensének bájtját bemaszkoljuk, majd értékét rendre betesszük az r, g és b változókba, amelyekből kikombináljuk az új szint, amit most éppen a „kék felé” tolunk el. Színezzük a sajat

                            
        switch (sajat) {
            case 0:
                // magyarok
                melyikbol = 0;
                hanyadik = 0;
                break;
            case 1:
                // francik
                melyikbol = 0;
                hanyadik = 1;
                break;
            case 2: ...
              .
              .
              .
            case 7:
                // olasz
                melyikbol = 1;
                hanyadik = 3;
                break;

        }

        mez(melyikbol, hanyadik, 0);
                        

és az ellen csapatot is.

                            
        switch (ellen) {
            case 0:
                // magyarok
                melyikbol = 0;
                hanyadik = 0;
                break;
            case 1:
                // francik
                melyikbol = 0;
                hanyadik = 1;
                break;
            case 2: ...
              .
              .
              .
            case 7:
                // olasz
                melyikbol = 1;
                hanyadik = 3;
                break;

        }

        mez(melyikbol, hanyadik, 1);
                        

A színezést magát majd a meghívott

protected void mez (kep,  
 alg,  
 melyikbe); 
int kep ;
int alg ;
int melyikbe ;
 

függvény végzi el, mely paraméterként kapja, hogy melyik képekből (a korábban mutatott vörös vagy fehér-fekete) végezzük a konverziót, pontosan hogyan történik a konverzió (ez volt fentebb kikommentezve mutatva a kékek - franciák esetben) és hová tesszük az eredményül kapott képet.

                            
protected void mez(int kep, int alg, int melyikbe) {
                        

A 2x9 futást tartalmazó kereten és 3 állást mutató kereten, azaz összesen 21 kereten dolgozunk, sorban egymás után. A buffer egész tömbbe beolvasunk egy keretet binárisan.

                            
        for (int i = 0; i < 21; ++i) {

            int[] buffer = new int[jKep[kep][i].getWidth() * jKep[kep][i].getHeight()];
            jKep[kep][i].getRGB(buffer, 0, jKep[kep][i].getWidth(), 0, 0,
                    jKep[kep][i].getWidth(), jKep[kep][i].getHeight());
                        

Majd végrehajtjuk az RGB kódolások megfelelő átalakítását.

                            
                    switch (alg) {

                        case 0:
                            // eredeti
                            // vörösök - magyarok
                            break;

                        case 1:
                            //kékek - franciák
                            r = (buffer[j] & 0x00ff0000) >> 16;
                            g = (buffer[j] & 0x0000ff00) >> 8;
                            b = buffer[j] & 0x000000ff;
                            buffer[j] = r | g << 8 | b << 16 | 0xff000000;
                            break;
                        

Végül az átalakításból egy új képet készítünk az adott keretből.

                            
            jKepOK[melyikbe][i] = javax.microedition.lcdui.Image.createRGBImage(buffer,
                    jKep[kep][i].getWidth(), jKep[kep][i].getHeight(), true);
                        

Munkánk eredményét mutatja a következő két ábrán látható csapatok mezeinek színe: a francia és az amerikai válogatott kék, illetve fekete-fehér és az olasz és a brazil válogatott fehér-kék , illetve sárga színei.

A francia és az amerikai válogatott színei.

Az olasz és a brazil válogatott színei.

Keverj ki egy új csapatot

  • Cseréld le valamelyik nemzeti válogatottat és adj nekik megfelelő színt. Ez esetben a fentiek mintájára más, a forráskódban való módosításokkal kell kísérletezned!

A fejezet feladatainak összefoglalása

A feladatok mellett feltüntetett szám a feladat általunk feltételezett nehézségére utal. Az egy pont a jegyzetben mutatottak egyszerű megismétlését jelenti, a tíz a teljesen egyéni munkát.

  1. Készíts egy saját új horgászhelyes portolást! (4 pont)

  2. A labdarúgó képeit (például magadról kamerával felvett futás kereteiből készítettekkel) lecserélve készíts egy új focis portolást! (5 pont)

  3. Készíts egy női focis portolást! (5 pont)

  4. Készíts saját világbajnokságot, válassz ki 8 csapatot, majd a zászlókat és a csapatot jellemző színeket cseréld le a választásodnak megfelelően! (8 pont)

II. rész - Szoftverfejlesztés

3. fejezet - A játékok továbbfejlesztése

Ebben a fejezetben annyira megismerkedünk a játékok forrásaival, hogy képesek legyünk belenyúlni a kódba.

Ennek megfelelően

  • megismered a horgász játék vezérlését

  • ezzel egyidőben mindhárom játék alapműködését, mert ugyanazon egyszerű OO struktúra alapján vannak felépítve, de közülük is a horgász játék a legegyszerűbb,

  • majd belepillantasz a foci szimulátor működésébe

  • végül megismered a Ziv-Lempel algoritmus szófájának felépítését az ezoterikus játékban

„Csak akkor értesz valamit, ha be tudod programozni. Te magad és nem valaki más! Ha nem tudod beprogramozni, akkor csak úgy gondolod, hogy érted.”

Gregory Chaitin [METAMATH] META MATH! The Quest for Omega

A játékok szervezése, megírása

 

„Nem tudok kimerítő leírást adni arról, hogy hogyan tudsz megtanulni programozni -- nagyon összetett tudásról van szó. Egyet azonban elárulhatok: a könyvek és tanfolyamok nem érnek túl sokat (sok, valószínűleg a legtöbb hacker autodidakta). Aminek van értelme: (a) kódot olvasni és (b) kódot írni.”

 
 --Eric S. Raymond (fordította: Kovács Emese) [Hacker] Hogyan lesz az emberből Hacker

A mobil programozásban (és általában, amikor előtérbe toljuk a teljesítményt a karbantarthatósággal vagy újra felhasználhatósággal szemben) természetes, hogy a programok bár természetesen objektum orientáltak, de ez a jelleg egyáltalán nem erős. Például a focis programban hiába keressük a Player osztályt, vagy annak valami megfelelőt, nem találunk csak natív Java tömböket: ezekben jellemezzük a játékosok tulajdonságait.

A játékok osztályszerkezetének kialakításakor is ennek szellemében jártunk el, így a megnyitott játékokat az alábbi, az ArgoUML-el legenerált osztály diagramok jellemzik. Mindhárom projektnek szinte teljesen azonos a szerkezete. Láthatóan nem használják a MIDP 2.0 megadta Game API-t, hanem klasszikusan (a Thread osztály konstruktorának egy Runnable interfészt implementáló objektumot átadva) saját játékszálat használnak.

A 110% Nyári Kapitális NYFK osztálydiagramja.

A 110% Nyári Kapitális NYFK osztálydiagramja csak annyiban különbözik a másik kettőtől, hogy a vászonban magában foglalkozunk a vásznon keletkező parancsokkal kapcsolatos eseménnyel.

                        
    /** Parancsok kezelése. */
    public void commandAction(javax.microedition.lcdui.Command c, javax.microedition.lcdui.Displayable d) {

        if (c == Parancs.kezeles) {
            midlet.segit0();
        } else if (c == Parancs.kilep2) {

            horgaszat = false;
            midlet.kivesz();

        } else if (c == Parancs.madarak) {
            midlet.madarak();
        }

    }
                    

Pontosabban csak visszahívjuk a MIDlet osztályunkat.

A Focijáték Neked NYFK osztálydiagramja.

A Focijáték Neked NYFK osztálydiagramjában annyi az újdonság, hogy például a fotózás során készített képeknél, azok mentésekor a felület átmenetileg lefagyna, ezért egy külön szálban végezzük ezeket a tevékenységeket.

A Hetedik Szem NYFK osztálydiagramja.

A Hetedik Szem NYFK osztálydiagramja. Itt a Ziv-Lempel szófa felépítése és elemzése az időigényes feladat, ezért ezt külön szálban implementáltuk.

1. Miért szeretjük az ArgoUML szoftvert?

1.

Miért szeretjük az ArgoUML szoftvert?

Mert forrásokból is tud UML diagramokat generálni! Szerintem sokan értjük a választ, de félre a tréfával! Valóban érdemes tervezni, sőt a szóban forgó programforrást is képes generálni.

A következő néhány osztály diagramon a tartalmazási relációkat is feltüntettük. Így megismerkedhetünk néhány további osztállyal.

A 110% Nyári Kapitális NYFK osztálydiagramja.

A 110% Nyári Kapitális NYFK osztálydiagramján megjelent a Hal osztály.

A Focijáték Neked NYFK osztálydiagramja.

A Focijáték Neked NYFK osztálydiagramja.

A Hetedik Szem NYFK osztálydiagramja.

A Hetedik Szem NYFK osztálydiagramján megjelent a rekurzív fa építés adatszerkezete, a (jól láthatóan önhivatkozó) TudatFa, illetve a statisztikai próbát megvalósító StatProba osztály.

A néhány megszemlélt diagram alapján távolról megismerkedtünk projektjeink osztályaival, a továbbiakban a forráskódok átnézésével folytatjuk.

A 110% Nyári Kapitális OSE

A három játék közül ennek a játéknak a legegyszerűbb a szervezése. A KapitalisVaszon osztályból a Runnable interfész implementálásával majd egy szál objektumot készítünk, ez lesz a játékot vezérlő szál.

                            
public class KapitalisVaszon extends javax.microedition.lcdui.Canvas implements
        Runnable, javax.microedition.lcdui.CommandListener {
                        

3.1. példa - A játékot vezérlő szál elkészítése és elindítása a KapitalisMIDlet.java állományban

                                
        } else if (c == Parancs.tovabb) {

            kimentBeallitasok();

            kapitalisVaszon = new KapitalisVaszon(this);
            t = new Thread(kapitalisVaszon);
            t.start();

            displayable = kapitalisVaszon;
            display.setCurrent(displayable);

        } else if (c == Parancs.kilep) {
                            

1

Meglehet, hogy a játékos már beállított valamit a splash képernyőn, például kikapcsolta a madárdalt, ezért a defenzív taktika az, ha a kimentBeallitasok metódus hívásával mentjük az esetlegesen módosított beállításokat a továbblépés előtt.

2

Elkészítjük a Runnable interfészt implementáló KapitalisVaszon vásznunkat: ezen a grafikus képernyőn megy majd maga a horgászat, itt mozgatják az úszókat a halak stb. A KapitalisVaszon konstruktornak átadjuk a saját, azaz a MIDlet osztályunk this referenciáját, hogy adott esetben a vásznunk vissza tudja hívni a midlet metódusait.

3

Elkészíti a játék logikájának szálját. Technikailag egy Runnable interfészt implementáló KapitalisVaszon objektumot adunk át a Thread konstruktornak.

4

Nincs más hátra, mint az elkészített szál elindítása a Thread osztálybeli t példány start metódusának meghívásával. Technikailag ez a mi esetünkben a KapitalisVaszon osztálybeli kapitalisVaszon objektum run metódusának meghívását jelenti. Ide kell tehát kódolnunk a játék logikáját!

5

Végül képernyőre helyezzük az elkészített vásznunkat.


A Focijáték Neked OSE bemutatása

A már megismert módon a FociVaszon osztályból a Runnable interfészt implementálásával majd egy szál objektumot készítünk, ez lesz a játékot vezérlő szál.

                            
public class FociVaszon extends javax.microedition.lcdui.Canvas
        implements Runnable {
                        

3.2. példa - A játékot vezérlő szál elkészítése és elindítása a FociMIDlet.java állományban

A foci játék indulásánál vagy új meccset kezdünk, vagy egy korábban megkezdettet folytatunk, ezt mondja meg a meccsMegy tag. Ha újat kezdünk, akkor meghatározzuk a két játékra következő csapatot, inicializáljuk az állást, az órát stb. Ezektől eltekintve a játék vezérlését ugyanazon módon szerveztük, mint amelyet megismertünk a horgász játék esetén.

                            
        } else if (c == Parancs.foci) {

            if (!meccsMegy) {

                FociVaszon.sajatCsapat = meccsek[meccsekI][csapatChoice.getSelectedIndex()];
                FociVaszon.ellenCsapat = meccsek[meccsekI][(csapatChoice.getSelectedIndex() + 1) % 2];
                FociVaszon.allas[0] = 0;
                FociVaszon.allas[1] = 0;
                FociVaszon.jatekIdoVege = false;
                FociVaszon.tizenegyesekSzama = 0;
                FociVaszon.jatekIdo = 0l;
            }

            mezek(FociVaszon.sajatCsapat, FociVaszon.ellenCsapat);

            fociVaszon = new FociVaszon(this);
            fociVaszon.addCommand(Parancs.segit);
            fociVaszon.addCommand(Parancs.kilep);
            fociVaszon.setCommandListener(this);

            fociVaszonSzal = new Thread(fociVaszon);
            fociVaszonSzal.start();

            kijelzore = fociVaszon;
            kijelzo.setCurrent(kijelzore);
                        

Az EM foci szimulátora

A játékba épített foci szimulátort a szimulacio függvény tartalmazza.

                            
    /**
     * EM MOTBALL Szimuláció
     */
    protected void szimulacio() {
                        

Ezt a függvényt a játékot vezérlő szál 155, 95 vagy 90 milliszekundumonként hívja meg, attól függően, hogy mekkora méretű pálya nézet van beállítva éppen a játékban. (Ezeket az időket a megjelenés, a játék látható sebessége határozza meg, mert a vezérlő szál a szimulacio függvény hívása után a vásznat újra rajzoló repaint függvényt hívja majd meg.)

                            
    protected long idos;
    protected final int varakozas[] = {155, 95, 90};
                        

A szimuláció előkészítése

A szimulációban használt adatszerkezetek sajnos egyáltalán nem objektum orientált természetűek, tehát például nincs elegánsan egy játékos osztály, amelyeknek ilyen meg olyan tulajdonságai vannak, hanem a jobb teljesítmény elérése miatt, maximum tömbökkel dolgozunk.

A szimuláció során a játékosokat a jatekosok nevű három dimenziós tömbbel jellemezzük. Az első dimenzió azt mondja meg, hogy a saját vagy az ellen csapat tagjáról van-e szó. A második dimenzió azonosítja a játékos mezszámát, a harmadik dimenzióban adjuk meg a tényleges tulajdonságokat:

  • a játékos oszlop pozíciója

  • sor pozíciója

  • a játékos cél oszlop pozíciója

  • sor pozíciója

  • labdatechnikája

  • játékérzéke

  • gyorsasága

  • melyik mozgás animációs keretet kell kirajzolni

Láthatóan tehát a játékos van egy pozícióban a pályán és törekszik elérni egy másikat, ez a cél pozíció. Ezek és a jsebNegyzet szabják meg a pályán a játékos mozgásának alapjait. A pályán egy diszkrét rácsra szorított euklideszi világban élünk, sebességbeli megfontolásokból használunk négyzeteket, hogy elkerülhessük a gyökvonás szükségessését.

                                
    /*
     * A játékosok tulajdonságai
     */
    protected int jx, jy, jcx, jcy, jdx, jdy, jdx2, jdy2;
    protected int jsebNegyzet = 49;
    protected int[][][] jatekosok = new int[2][10][8];
    // [csapat: 0 v.1][tagok (játékosok): 0-9.][tulajdonságok: jx jy jcx jcy labdatechnika jatekerzek gyorsasag]
    // tulajdonságok: x y cx cy
                            

Az iménti kódcsipet kapcsán említett jatekosok tömb labdatechnika, játékérzék és gyorsaság értékei, azaz azon két csapatnak a játékosainak az értékeim akik részt vesznek az aktuális szimulációban, vagyis, akik vívják a találkozót, a csapatTulajd tömbökben kerülnek előzetesen meghatározásra.

                                
    public static final int csapatTulajd[][][] = {
        { // a sajat csapat

            // {labda technika, játék érzék, gyorsaság}
            // a játékosok tömbben: ezek a 4. 5. 6. elemek

            {30, 60, 35}, // kapus

            {90, 25, 90}, // csatársor
            {92, 24, 100},
            {89, 30, 94},
            {62, 62, 60}, // középpályás sor
            {78, 60, 62},
            {67, 60, 58},
            {55, 89, 58}, // hátvédsor
            {60, 91, 40},
            {56, 92, 35}
        },
        { // az 1-es ellen csapat
        ...
                            

A játékot azért végső soron a labda hajtja meg, a labda mozgatja, ennek tükröződnie kell a szimulációban is. A labda alapvető állapotát a labdaAllapot rögzíti.

                                
   /*
     * A labda tulajdonságai
     */
    protected int labdaAllapot, lx, ly, lcx, lcy, ldx, ldy, ldx2, ldy2;
    protected final static int MOZGASBAN = 0;
    protected final static int KOZEPRE = 1;
    protected final static int KOZEPKEZDES = 2;
    protected final static int VEZETVE = 3;
    protected final static int KIRUGAS = 4;
    protected final static int GOLOROM = 5;
    protected final static int TALALKOZO_VEGE = 6;
    protected final static int SZOGLETHEZ = 7;
    protected final static int SZOGLET = 8;
    protected final static int TIZENEGYESHEZ = 9;
    protected final static int TIZENEGYES = 10;
    protected final static int MOZGASBAN11 = 11;
    protected final int lsebNegyzet = 300;
    protected int lbJatekos, lcJatekos; // labda birtokló és cél játékos
    // megjelenítés
    protected int lki = 0; // labda forgás anim
                            

Alapvető szerepet játszik a játékosok pályán történő mozgásának szervezésében a felállás. Ez egyszerűen minden játékosnak egy olyan pozíciót tűz ki, amelyet igyekszik elfoglalni, ha éppen nem más feladatot hajt végre.

                                
protected int[][][] felallasok = {
        // [hányadik felállás][játékosok][cx cy]
        // 3x3x3
        // kozépkezdéskori felállás
        // majd az ennek megfelelő egész pályás felállás
        // 3x4x2
        // kozépkezdéskori felállás
        // majd az ennek megfelelő egész pályás felállás
        // 4x3x2
        // kozépkezdéskori felállás
        // majd az ennek megfelelő egész pályás felállás
        // 2x4x3
        // kozépkezdéskori felállás
        // majd az ennek megfelelő egész pályás felállás

        // mindent a b.o.-i (SAJAT) csapatra vonatkozóan kell megadni,
        // az ELLEN majd PX - a megadott
                            

Adott felálláshoz tartozik egy középkezdéskori pozíció halmaz

                                
        { // egy felállás, a csapat minden tagjának
            // taktikai (x,y) koordinatája:
            // ez a 3x3x3 felállás a középkezdéshez
            {10, 320}, // a kapus: 0.

            {480, 470}, // 1-9 csatároktól a hátvédekig
            {495, 320}, // elhelyezkedes, mint a telefonon a num
            {470, 230}, // billentyuk

            {310, 530}, // középpálya
            {320, 310},
            {310, 100},
            {110, 400}, // hátvédsor
            {170, 330},
            {110, 240}
        },
                            

illetve egy egész pályás:

                                
        {
            // ez a 3x3x3 egész pályás
            {10, 320}, // a kapus: 0.

            {480 + 365, 470}, // 1-9 csatároktól a hátvédekig
            {495 + 365, 320},
            {470 + 365, 230},
            {310 + 330, 530},
            {320 + 330, 310},
            {310 + 330, 100},
            {110 + 300, 400},
            {170 + 300, 330},
            {110 + 300, 240}
        },
                            

De ugyanez a tömb írja le nem csak a felállásokat, hanem például a szögletnél a támadó és a védő viselkedését, azaz tervezett helyezkedését is.

A felállások mellett alapértelmezésben tételezünk fel emberfogást is, ezt a hozzárendelést a fogoJatekos tömb rögzíti.

                                
    protected int[][] fogoJatekos = {
        { //0. 3x3x3 <-> 3x3x3
            2, // ki megy a kapusra
            7, 8, 9, 4, 5, 6, 1, 2, 3 //(ki megy a megfelelő tömbindexűre?)
        },
        { //1. 3x3x3 <-> 3x4x2
            1, // ki megy a kapusra
            7, 8, 9, 4, 5, 6, 3, 1, 2 //(ki megy a megfelelő tömbindexűre?)
        },
        ...
                            

A szimuláció futása

A labda a szimuláció során, a korábban ismertetett számos állapotban lehet. A szimuláció ennek az állapotnak a vizsgálatával kezdődik.

Ha a labda MOZGASBAN van, akkor végigmegyünk az összes játékoson

                                
    protected void szimulacio() {

        switch (labdaAllapot) {

            case MOZGASBAN:

                // a játékosok mozgása
                for (int j = 0; j < jatekosok[kiLep].length; ++j) {
                    if (j != lcJatekos) { // csapaton belüli játékosokon
                    
                            

és minden játékos esetén elővesszük az adatait

                                
                        jx = jatekosok[kiLep][j][0];
                        jy = jatekosok[kiLep][j][1];
                        jcx = jatekosok[kiLep][j][2];
                        jcy = jatekosok[kiLep][j][3];
                        jsebNegyzet = jatekosok[kiLep][j][6];
                            

a jelen és tervezett cél pozíciójából, sebességéből kiszámoljuk a következő aktuális pozícióját, egészen pontosan az aktuálisat inkrementáljuk egy előjelen növekménnyel.

                                
                        jdy2 = (jsebNegyzet * (jcy - jy) * (jcy - jy)) / ((jcx - jx) * (jcx - jx) + (jcy - jy) * (jcy - jy) + 1);
                        jdx2 = jsebNegyzet - jdy2;

                        jdx = gyok(jdx2) + 1;
                        jdy = gyok(jdy2) + 1;

                        int jdxs = Math.abs(jcx - jx);

                        jdx = jdxs / jdx + 1;
                        jdy = Math.abs(jcy - jy) / jdy + 1;

                        jatekosok[kiLep][j][0] += ((jcx - jx) / jdx);
                        jatekosok[kiLep][j][1] += ((jcy - jy) / jdy);
                            

majd arról gondoskodunk, hogy a következő kirajzoláskor a játékos mozgásának megfelelő mozgásfázis keretét rajzoljuk majd ki:

                                
                        if (jdxs != 0) {
                            jatekosok[kiLep][j][7] = ((jcx - jx) / jdxs + 1) / 2 * 10 + (ido + j) % 9;
                            // *hol kezdődik a 2. garnitúra futás
                            // %hány kép a futás animáció
                        } else {
                            jatekosok[kiLep][j][7] = 20;
                        }
                            

s ugyanezeket megtesszük a másik csapattal is.

Majd a labda mozgásáról gondoskodunk

                                
                // a labda mozgása
                ldy2 = (lsebNegyzet * (lcy - ly) * (lcy - ly)) / ((lcx - lx) * (lcx - lx) + (lcy - ly) * (lcy - ly) + 1);
                ldx2 = lsebNegyzet - jdy2;

                ldx = gyok(ldx2) + 1;
                ldy = gyok(ldy2) + 1;

                ldx = Math.abs(lcx - lx) / ldx + 1;
                ldy = Math.abs(lcy - ly) / ldy + 1;

                lx += ((lcx - lx) / ldx);
                ly += ((lcy - ly) / ldy);
                // a labda mozgása
                            

miután a labda új pozíciót vesz fel, megnézzük, hogy történt-e valami esemény: gól, szöglet stb. Tehát ha a labda elhagyta a játékteret, akkor lehetett gól:

                                
                // kint van?
                if (lx < 0) { // elég redundáns itt a kód, annek ellenére, hogy a
                    // tennivaló szimmetrikus a két fél esetében csak nem akartam vagyolni
                    // az itteni if-ben

                    if (gol()) {

                        golorom(SAJAT); // ki kapta, ez biztos, mert tudjuk, hogy
                        // melyik oldalon van a labda, hogy ki rugta, az mar nem
                        // ennyire egyertelmu...
                        return;
                            

vagy szöglet, ha mi rúgtuk ki

                                
                    } else if (kiLep == SAJAT) {
                        // szoglet
                        kiLep = ELLEN;

                        if (ly < 284) {
                            szoglet(3);
                        } else {
                            szoglet(0);
                        }

                        return;
                             
                            

illetve kirúgás, ha az ellenfél:

                                
                    } else if (kiLep == ELLEN) {
                        //kirugas

                        kiLep = SAJAT;

                        lbJatekos = 0;
                        labdaAllapot = KIRUGAS;
                            

ha a labda nem ment ki, akkor meglehet, hogy éppen véget ér egy átadás, vagy az ellenfél szemfüles játékosa elcsípi a labdát, ennek vizsgálata következik. Ha itt a feltétel teljesül, azaz megfelelően közelre ér a labda ahhoz, akinek az átadást szánták, akkor leveszi a labdát és vezetni kezdi.

                                
                // átvesz, elvesz
                if (lTavolsag(jatekosok[kiLep][lcJatekos][0],
                        jatekosok[kiLep][lcJatekos][1]) < 10) { // 9 volt eddig

                    lbJatekos = lcJatekos;
                    labdaAllapot = VEZETVE;

                    tamad(kiLep);
                    ...
                            

Ha a különben ág teljesül, akkor az ellen elcsípte a labdát:

                                
                } else { // megszerzi az ellenfél az átadást

                    masikCsapat = (kiLep + 1) % 2;
                    for (int j = 0; j < jatekosok[masikCsapat].length; ++j) { // csapaton belüli játékosokon

                        if (lTavolsag(jatekosok[masikCsapat][j][0],
                                jatekosok[masikCsapat][j][1]) < 82) {

                            kiLep = masikCsapat;

                            lbJatekos = j;

                            tamad(kiLep);
                            

Ezzel röviden áttekintettük, mi történhet a labdával, ha mozgásban van.

További állapotokat nem vizsgálunk részletesen, csak felvillantjuk a VEZETVE állapot elejét. Itt azt láthatjuk, hogyan érvényesítjük a felállás mellett az emberfogást.

                                
            case VEZETVE:

                lki = (lki + 1) % 3;

                // fogó játékos rámegy
                masikCsapat = (kiLep + 1) % 2;
                jatekosok[masikCsapat][fogoJatekos[seFelallas][lbJatekos]][2] = jatekosok[kiLep][lbJatekos][2];
                jatekosok[masikCsapat][fogoJatekos[seFelallas][lbJatekos]][3] = jatekosok[kiLep][lbJatekos][3];
                // fogó játékos rámegy

                // a játékosok mozgása
                            

A Hetedik Szem NYFK bitmintáinak elemzése

Vezérlésben nincs újdonság a korábban tárgyalt két játék és e között. Ami viszont említést érdemel, az a felvett tudat-lenyomatok összehasonlítása, ezt nézzük meg ezekben az elkövetkező pontokban.

Ennél a játéknál különösen indokolt a mobil használata, hiszen használata során feltételezzük, hogy a játékos egy megváltozott tudatállapotban, azaz mondjuk relaxálva „játszik”, s közben szabad akaratából nyomja a tűzgombot vagy nem nyomja a vizsgált időszeletben. Döntéseiből összeállítunk egy 2048 bites bináris mintát, az adott felvételi kontextust jellemző úgynevezett „tudat-lenyomatot”. Kérdés, hogyan tudjuk értelmes módon összehasonlítani az ilyen mintákat. Ezt a kérdést részletesen tárgyaljuk a szerző [PHD] dolgozatában. Most elég annyi, hogy a például az [ALGORITMUSOK] könyvben is ismertetett Ziv-Lempel-Welch (LZW) algoritmus szófáját használjuk fel, miközben a [SZTOCHSZT] könyv utalására építünk, miszerint – az ismeretlen adatsorokkal való első ismerkedés során – érdemes összevetni az LZW során épített szófa ághosszainak szórását.

Esetünkben, bináris mintáról lévén szó, ez egy bináris fa lesz, amit a TudatFa.java forrás rekurzív szerkezetével építünk fel.

                        
public class TudatFa {

    TudatFa bo = null;
    TudatFa jo = null;
                    

Az említett számításokat a TudatSzamitas.java forrásban végezzük. Az picit nehezítheti a kód olvasását, hogy a mobilon a halomnak mindig híján lévén, bitenként kezeljük a sorozatot, ezt segítik a bajtIndex és a bitIndex változók:

                            
    public TudatFa elemzes(byte [] t) {

        // Fakezelés
        TudatFa gyoker = new TudatFa();
        TudatFa fa = gyoker;
        // Mintán bitenként léptetés
        int bajtIndex = 0;
        int bitIndex = 0;
        byte ertek = 0x01;
                        

ezzel a megjegyzéssel már könnyű olvasni, mert bitenként végigszaladunk a mintán:

                            
        for(int i=0; i<TudatVaszon.MINTA_MERET; ++i) {
            // Mintán bitenként léptetés
            bajtIndex = i/8;
            bitIndex = i%8;
            ertek = 0x01;
            ertek = (byte)(ertek & (t[bajtIndex] >>> (8-bitIndex-1)));
            // Fakezelés
            if(ertek == 0) {

                if(fa.bo == null) {

                    fa.bo = new TudatFa();
                    fa = gyoker;

                } else {

                    fa = fa.bo;
                }

            } else {

                if(fa.jo == null) {

                    fa.jo = new TudatFa();
                    fa = gyoker;

                } else {

                    fa = fa.jo;
                }

            } // if(ertek == 0) {

        } // Mintán bitenként léptetés

        return gyoker;
    }
                        

miközben felépítjük az LZW algoritmusnak megfelelő szófát és visszaadjuk a felépített fa gyökerének referenciáját.

Az elkészített fát a klasszikus módon járjuk be [4] az elemzések során. Egy ilyen bejárást mutat például az ághosszak hosszának átlagát kiszámoló atlag függvény.

                            
    // az atlag() hívásakor is inicializálni kell őket, a
    // a rekurziv bejárás használja őket
    int atlagosszeg = 0, melyseg = 0, atlagdb = 0;

    public void atlag(TudatFa fa) {

        if(fa != null) {
            ++melyseg;
            atlag(fa.bo);
            atlag(fa.jo);
            --melyseg;

            if(fa.bo == null && fa.jo == null) {

                ++atlagdb;
                atlagosszeg += melyseg;

            }

        }

    }
                        

Az elemzést (tehát a fa felépítését és az ághosszak szórásának kiszámítását) mint időigényes, tehát a felületet blokkolni képes tevékenységet, egy párhuzamos szálban valósítottuk meg:

                            
    /*
     * LZW fa ághosszainak átlaga és szórása, Hamming táv.
     */
    public void run() {

        // utólag bevett F próbához a korrigált empirikus szórásnégyzetek
        double szorasn1, szorasn2, szorasn3, szorasn4;

        // LZW fák felépítése és feldolgozása

        /* I. normál görbe */

        /* LZW fa felépítése */
        TudatFa gyoker = elemzes(midlet.tudatLenyomat[0][0]);

        /* Átlagos szóhossz kiszámítása */
        atlagosszeg = 0; melyseg = 0; atlagdb = 0;
        atlag(gyoker);
        atlag1 = atlagosszeg/atlagdb;

        szoszam1 = atlagdb;

        /* Ághosszak szórásának kiszámítása */
                        

Sőt, utólag a szórások vizsgálatára (a két összehasonlított szereplő egy-egy megfelelő fájának összehasonlításakor a két fából épített LZW szófa ághosszai szórásainak egyezéséről szóló hipotézist vizsgáló) F statisztikai próbát is készítettünk, ennek beprogramozását a StatProba.java állományban találjuk meg.

Továbbfejlesztések

 

„Az Úr

                        Karod erős - szíved emelkedett:
                        Végetlen a tér, mely munkára hív,”
                    

 
 --Madách Imre [EMBER]

Mindhárom játék esetén számos irányt meg tudunk jelölni, amerre érdemes elindulni a módosításokkal, most leírunk néhányat.

  • A horgász játékban sokszor terveztem, hogy a fárasztás mellé beteszek egy animációt, ami a horgászbot hajlását mutatja.

  • Ugyancsak a horgászban el tudnám képzelni, hogy maga a játék adna lehetőséget a horgászhely megadására: a kamerával készítjük magából a játékból a fotót, kettévágjuk szoftverből és kitesszük a korábban látott, de akkor kézimunkával elvégzett módon.

  • A focis játékban rögtön adódik számos fejlesztési cél, hiszen a Football(er) Simulation Markup Language (röviden FerSML) (http://sourceforge.net/projects/footballerml/) [FERSML] projektnél felhasználjuk az ezekből a forrásokból készített előzetes elemzések eredményeit. Egy ilyet fogunk kibontani a következő pontban.

  • Az ezoterikus játéknál a szerver oldali kiterjesztés lehet különösen érdekes: a minták összegyűjtése és elemzése. Eldöntendő, hogy lehetne-e a tudatlenyomatokra alapozottan - mondjuk egy közösségi portál keretein belül - egy újfajta kapcsolati hálót létrehozni. Ezek a kérdések Digitális Tudatlenyomatok Összehasonlító Könyvtára és Hetedik Szem alapú közösségi portál címszavak alatt mélyebben ki vannak bontva a [PHD] dolgozatban.

Két gépi játékos a foci játékban

 

„Az Úr

                            A gép forog, az alkotó pihen.
                            Év-milliókig eljár tengelyén,”
                        

 
 --Madách Imre [EMBER]

Most a focis játékban fogunk egy olyan praktikus változtatást eszközölni, aminek a mobil játék kapcsán igaz nincs sok értelme, de annál inkább használható lesz az említett Football(er) Simulation Markup Language projekthez való tapasztalatgyűjtésre. Jelen pillanatban a focis játékban az emberi játékos játszik a gépi játékossal: mindketten a saját csapatuk játékosait irányítják közvetlenül azzal, hogy az átadás orientált játékban direktben megadják, kinek menjen a passz. Azt szeretnénk elérni, hogy a foci szimulátort tudjuk használni nagy számú mérkőzés legenerálására. Ehhez ugye az kell, hogy a játék interakcióját elvegyük, azaz ne várjon arra, hogy a játékos bármit nyomjon a felületen. Pontosabban figyelembe veheti a játékos interakcióját, de anélül is fusson automatikusan. Például ne várjon akár 10 percet is azért, hogy a játékos a középkörben a kezdőrúgással egyáltalán elkezdje a mérkőzést, ne várjon egy labda birtokláskor arra, kinek kell átadni, vagy lőni: passzoljon vagy akár lőjön a játékost képviselő gépi játékos!

Ez az átalakítás annyiból viszont érdekes, hogy megismerjük vele immár teljes mélységében a foci szimulátor működését.

Maga az átalakítás egyébként viszonylag egyszerű, alig pár helyen kell beavatkoznunk és csupán a FociVaszon.java állomány forrásában. Ezek a (legfőbb helyek) következők.

A valódi játékos szükségességének megszüntetése

  1. Az alábbi VEZETVE ágban

                                            
                case VEZETVE:
                                        

    találjuk azt a kódrészletet, ami megmondja, mit tegyen az ellenfél játékosa, aki (hiszen) eddig is saját „belátása” szerint játszott.

                                        
                    // ellen taktika
                    if (kiLep == ELLEN) {
    
                        int r = rAbs(100); // vigyazni, hogy if(r...) után az r-t használva az már az emlitett if-el szurt r!
                        int kinek = 5;
    
                        switch (lbJatekos) { //kinek?
    
                            case 0: // a kapus nem taktikazik, esz nelkul
                                // passzol valakinek
                                kinek = 7 + (r % 3);
    
                                lcx = jatekosok[kiLep][kinek][0];
                                lcy = jatekosok[kiLep][kinek][1];
                                atadas(kinek);
                                break;
    
                            case 7: // a hatvedsor viselkedese
                            case 8:
                            case 9:
    
                                if (r < jatekosok[kiLep][lbJatekos][5]) { // passzol
                                    

    A játékos mezszáma alapján láthatjuk, ki miként fog viselkedni. Első dolgunk tehát, hogy egy ilyen kódot kell beültetnünk a SAJAT játékosok vezérlésére. A kód láthatóan szimmetrizálható, azaz olyan általánosan van megírva, hogy a saját játékost azonnal hivatkozzák a kiLep és a lbJatekos változók megfelelő értékei. Egy probléma viszont lehet. Ha megfigyeljük a csatársor viselkedését leíró kódot:

                                        
                            case 1: // csatársor viselkedése
                            case 2:
                            case 3:
    
                                int segedx = jatekosok[kiLep][lbJatekos][0];
    
                                // ötösnel közelebb, biztosan rálő
                                //if(segedx < 55 || segedx > PX-55) { a PX- nem kell, mert a terfelek fixek,
                                // majd a sajat lovesnel kell
                                if (segedx < 55) {
                                    

    ahol az 55 egy olyan érték, ami jellemzi a pálya egyik oldalát. S nekünk éppen a másik irányba kellene játszani. Ha így hagyjuk a kódot, akkor a feltételek sosem teljesülnek és a csatáraink ennek megfelelően soha nem rúgnak rá, csak egymás között passzolgatnak, amíg le nem szerelik őket. A saját csatársornak megfelelő értékeket az eseménykezelőben, a FIRE gombhoz rendelt

                                            
                    case FIRE:
    
                        if (kiLep == SAJAT) {
    
                            if (labdaAllapot == VEZETVE) {
    
                                // kapura lövés
                                int segedx = jatekosok[SAJAT][lbJatekos][0];
                                        

    részben láthatjuk:

                                        
                                if (segedx > PX - 55) { // otos vonalan belul
    
                                    lcx = 1010;
                                    lcy = 320 + r(Math.abs(320 - jatekosok[SAJAT][lbJatekos][1]) / 2 + 40);
    
                                } else if (segedx > PX - 165) { // 16-os vonalan belul
    
                                    lcx = 1010;
                                    lcy = 320 + r(Math.abs(320 - jatekosok[SAJAT][lbJatekos][1]) / 2 + 100);
    
                                    // legyen szöglet?
                                    if (lcy < 282 || lcy > 358) {
                                    

    Tehát a SAJAT játékosok vezérlésére az alábbi apró módosításokat kell elvégezni a másolt különben ágban:

                                            
                        } // switch
                    } // if ellen
                    // ellen taktika
                    else {
                    .
                    .
                    .
                            case 1: // csatársor viselkedése
                            case 2:
                            case 3:
    
                                int segedx = jatekosok[kiLep][lbJatekos][0];
                            .
                            .
                            .
                                if (segedx > PX - 55) {
                                .
                                .
                                .
                                    lcx = 1010;
                                    lcy = 320 + r(Math.abs(320 - jatekosok[SAJAT][lbJatekos][1]) / 2 + 40);
                                    .
                                    .
                                    .
                                } else if (segedx > PX - 165) {
                                .
                                .
                                .
                                        lcx = 1010;
                                        lcy = 320 + r(Math.abs(320 - jatekosok[SAJAT][lbJatekos][1]) / 2 + 100);
                                        .
                                        .
                                        .
                                } else if (segedx > PX - 180) {
                                .
                                .
                                .
                                        lcx = 1010;
                                        lcy = 320 + r(315);
                                        

                                            
                                        
                                        

                                            
                                        
                                        

  2. Ha ezek után tesztelünk, láthatóan a rögzített helyzetekkel, mint például triviálisan a középkezdéssel baj van.

                                            
                case KOZEPKEZDES:
    
                    lki = 0;
    
                    if (kiLep == SAJAT) {
                        // várjuk a játékostól az inputot
                    } else { // ELLEN
    
                        int kinek = rAbs(2);
                        kinek = 2 + (2 * kinek) - 1;
    
                        lcx = jatekosok[kiLep][kinek][0];
                        lcy = jatekosok[kiLep][kinek][1];
                        atadas(kinek);
    
                    }
    
                    break;
                                        

    itt láthatóan semmi nem is fog történni addig, amíg nem jön valami input a felhasználótól. Tehát szükséges a beavatkozásunk: egyszerűen blokk-másoljuk az ELLEN ág tartalmát!

                                        
                    if (kiLep == SAJAT) {
                        // várjuk a játékostól az inputot
    
                        /* Vártuk eddig, de most automatizáljuk a
                         játék működését: */
    
                        int kinek = rAbs(2);
                        kinek = 2 + (2 * kinek) - 1;
    
                        lcx = jatekosok[kiLep][kinek][0];
                        lcy = jatekosok[kiLep][kinek][1];
                        atadas(kinek);
    
                    } else { // ELLEN
    
                        int kinek = rAbs(2);
                        kinek = 2 + (2 * kinek) - 1;
    
                        lcx = jatekosok[kiLep][kinek][0];
                        lcy = jatekosok[kiLep][kinek][1];
                        atadas(kinek);
    
                    }
    
                    break;
                                    
  3. Ugyanígy kell eljárnunk a KIRUGAS esetén.

                                        
                case KIRUGAS:
    
                    lki = 0;
    
                    if (kiLep == SAJAT) {
                        // várjuk a játékostól az imputot
    
                        /* Vártuk eddig, de most automatizáljuk a
                         játék működését: */
    
                        int kinek = 4 + rAbs(3);
    
                        lcx = jatekosok[kiLep][kinek][0];
                        lcy = jatekosok[kiLep][kinek][1];
                        atadas(kinek);
    
                    } else { // ELLEN
    
                        int kinek = 4 + rAbs(3);
    
                        lcx = jatekosok[kiLep][kinek][0];
                        lcy = jatekosok[kiLep][kinek][1];
                        atadas(kinek);
    
                    }
    
                    break;
                                    
  4. Még a SZOGLET és a TIZENEGYES esetén kell teljesen hasonlóan eljárnunk és készen is vagyunk, ezután a játék önjáróvá vált! Az utóbbi esetén így festhet az új kód:

                                            
                    if (kiLep == SAJAT) {
    
                        jatekosok[ELLEN][0][7] = 19; //25; // oldalt fordul
                        jatekosok[SAJAT][lbJatekos][7] = 9; //12;  // oldalt fordul
    
                        // várjuk a játékostól az imputot
    
                        /* Vártuk eddig, illetve ennyi volt eddig, de most
                        automatizáljuk a játék működését: */
    
                        kommentator.delete(0, kommentator.length());
                        kommentator.append(sajatNevek[SAJAT][lbJatekos]);
                        kommentator.append(Szoveg.ellovi);
    
                        ++jatekosStat[kiLep][lbJatekos][3];
                        midlet.startPassz();
    
                        lcx = -10;
                        lcy = 320 + r(40);
    
                        labdaAllapot = MOZGASBAN11;
    
                    } else { // ELLEN
                                        

    vannak igaz számok, de itt már egy kapuzunk, így nincs jelentőségük.

    Az előbbi, a SZOGLET esetében pedig így festhet:

                                            
                case SZOGLET:
    
                    lki = 0;
    
                    if (kiLep == SAJAT) {
                        // várjuk a játékostól az inputot
    
                        /* Vártuk eddig, de most automatizásás: */
    
                        int kinek = rAbs(2);
                        kinek = 2 + (2 * kinek) - 1;
    
                        lcx = jatekosok[kiLep][kinek][0];
                        lcy = jatekosok[kiLep][kinek][1];
                        atadas(kinek);
    
                    } else { // ELLEN
    
                        int kinek = rAbs(2);
                        kinek = 2 + (2 * kinek) - 1;
    
                        lcx = jatekosok[kiLep][kinek][0];
                        lcy = jatekosok[kiLep][kinek][1];
                        atadas(kinek);
    
                    }
    
                    break;
                                        

    itt láthatóan teljesen ártatlan kódot vágtunk be, hiszen ez tulajdonképpen csak egy speciális átadás.

A fejezet feladatainak összefoglalása

A feladatok mellett feltüntetett szám a feladat általunk feltételezett nehézségére utal. Az egy pont a jegyzetben mutatottak egyszerű megismétlését jelenti, a tíz a teljesen egyéni munkát.

  1. Készíts olyan változatot a focis játékból, ami nem vesz fel inputot a játékostól, hanem a két csapat automatikusan játszik benne! (10 pont)

  2. Változtasd a focis játék feltételeit úgy, hogy az egymással automatikusan játszó csapatok közül az egyik sokkal jobban játsszon! Például jobban passzoljon, szereljen, lőjön kapura. (11 pont)

  3. Bővítsd új elemekkel a foci szimulátort! Például egy szabálytalansággal és a szabálytalanságot követő szabadrúgással. (14 pont)

  4. Írd úgy át a horgász játékot, hogy az egyik bot fenekező legyen! (12 pont)

  5. Módosítsd úgy a horgász játék RMS (Record Management System) tárolóját, hogy a fogási naplóba elmentse a halfogás helyét is! (13 pont)

  6. Módosítsd úgy a horgász játékot, hogy a valódi időnek megfelelően legyen nappali és éjszakai horgászat! (14 pont)

  7. Készíts Java Servlet alapú szerver oldalt az ezoterikus játékhoz! Tárolja és hasonlítsa össza a többiek mintáival az aktuálisan feltöltöttet és az összehasonlítás eredménye alapján javasoljon ismerősöket a feltöltőnek! (16 pont)

  8. Hozz létre a mentális lenyomatokra alapozott új közösségi portált! (19 pont)



[4] Ha esetleg nem ismered ezt a bejárási módot, megtalálod a klasszikus [KERNIGHANC] C programozási tankönyvben.

4. fejezet - A játékok portolása

Ebben a fejezetben a játékok portolására, azaz más környezetre való átalakítására láthatsz példát.

Ilyen lehet például a

  • Google Android® mobil platformjára átírni,

  • vagy asztali gépekre, Full Screen API-t használó Java SE, azaz teljes képernyős PC-s játékká alakítani

  • itt azt nézzük, meg, hogyan tudod a focit Java Appletként, azaz asztali böngészőben vagy alkalmazásként futtathatóra átírni.

„Talk to other programmers; read other programs. This is more important than any book or training course.”

Peter Norvig [TenYears] Teach Yourself Programming In Ten Years

Portolás

 

„AZ ÚR

                        Mondottam, ember: küzdj és bízva bízzál!”
                    

 
 --Madách Imre [EMBER]

A portolás a Java ME™ világában nem ritka, mert jellemző a platform töredezettsége. Például ha a MIDP 2 (játék API-jának teljes képernyős játékvászna) előtt a fejlesztő teljes képernyős játékot szeretett volna készíteni, ezt adott eszközcsalád tekintetében, a gyártó saját API felületét használva meg tudta tenni, más gyártók esetén pedig nem vagy ha valami általános „extra dolog” használata esetén igen, akkor inkompatibilis módon. Nem ismeretlen dolog ez a szabványosítással ellenkező előjelű folyamat az informatikában, csak egy példát említve: ugyanezzel küzdött a CORBA világa, amikor az ORB-ket szállító szoftvercégek, természetesen a felhasználói igényeket igyekezve kielégíteni, különböző és nem kompatibilis termékekkel álltak elő, ezen a helyzeten segített a hordozható (POA) objektumadapter szabványosítása.

De ennél prózaibb esetben is szükség lehet a portolásra: tegyük fel, hogy valami megy sok készüléken, hiba nélkül, de van egy, amin (mondjuk vélhetően memóriakezelési okokból) mégsem. Kísérletezünk azzal, hogy olyan objektum gazdálkodást folytassunk a programozás során, amivel ugyanolyan szépen kéne mennie a programnak az eddigieken és mennie kéne a problémáson is, de eljöhet az idő, amikor jobban megéri kettéválasztani a forrásokat és használni valami eszköz specifikus stílust. Ez persze mindig nagyon megterhelő extrát jelent a fejlesztésben, de előfordulhat.

Ha persze egy másik platformot is megcélzunk a fejlesztéssel, akkor a portolás szükségessége egyértelmű.

Android platformos horgász

Ha Androidra akarjuk átírni, az bizony abból a szempontból nem egyszerű, hogy ez nem Java ME, de vigasz, hogy legalább Java. Ez még mindig egyszerűbb átalakítást jelent, mint mondjuk a Nokia 60-as sorozatbeliekre natívban, azaz Symian C++-ba áttenni.

A horgászból egy Androidos portolás egyébként nem túl nehéz, például a korábbi „Nehogy már...” könyv NehogyMar3-as példájából kiindulva elkezdhető a platformmal való ismerkedés. De itt nem tervezzük bemutatni ezt a portolást, mert a jövő félévtől ez lesz a DDN-be való jelentkezés belépő feladata. Viszont, mivel a hallgatók többségének probléma a korábbi „Nehogy már...” könyv ezen Androidos példájának felélesztése, így teszünk néhány hasznos megjegyzést.

A korábbi „Nehogy már...” könyv Androidos NehogyMar3 példájának felélesztése

  1. Először is: használd az Eclipse IDE-t! Sajnos hivatalos NetBeans plugin nincs. Például az Eclipse Classic 3.5.2 megfelelő lesz.

  2. Az Android telepítésénél járj el a http://developer.android.com/sdk/installing.html utasításai szerint (az Android SDK és az Eclipse környezethez az ADT Plugin kell telepítened).

  3. Ha megvan a korábbi „Nehogy már...” könyv, akkor abból sokminden kiderül, ha nincs, akkor a következő ábrák megmondják majd, hogy az innen (http://www.eurosmobil.hu/NehogyMar) letöltött fájlok közül mit és hova másolj be.

    Az Androidos projekt létrehozása.

    A letöltött fájlok helyei.

  4. Mivel a könyv az Android születésekor íródott, így 1.5-ös példáin kicsit patkolnod kell, hogy menjenek a most 2.1-es platformon. Az XML forrásokban hajts végre az első kettő, a Java forrásban a harmadik szöveges helyettesítést:

    • android:layout_toRight helyett android:layout_toRightOf

    • id helyett android:id

    • android.view.animation.Animation.CYCLE helyett android.view.animation.Animation.RESTART

  5. S futtatva máris itt az animáció:

    Pillanatkép a NehogyMar3 Androidos példáról.

A jelen „Nehogy már MEGINT...” könyv Androidos NehogyMar4 példája

A példa egy frame alapú animációt valósít meg. „Nehogy már...” szokásainkhoz híven az előző példából kindulva fejlesztjük ki.

  1. Első lépésben készítsd el a hozzávalókat, a korábbi könyv Java Game API alapú kereteit tartalmazó képet vágd fel 9 darab 120x150 méretű képre. (A jelen jegyzetben ezt a képet itt láttad.)

  2. Majd létrehozzuk a NehogyMar4 új projektet.

    Az Androidos projekt létrehozása.

    A NehogyMar4 projekt adatainak megadása.

  3. Felületünket csupán annyiban módosítjuk, hogy a NehogyMar3 esetében használt tenyér képének helyére a futás animálását helyezzük.

    <?xml version="1.0" encoding="utf-8"?>
    	<!--
    		main.xml
    
    		Bátfai Norbert: Nehogy már MEGINT a mobilod nyomkodjon Téged!
    		nbatfai@gmail.com
    
    		Ezt a forrásfájlt (és a hozzá esetlegesen kapcsolódó erőforrásokat,
    		például képeket) letöltheted a http://www.tankonyvtar.hu címről.
    	-->
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    	android:orientation="vertical"
    	android:layout_width="fill_parent"
    	android:layout_height="fill_parent"
    	android:background="@color/hatter_szin"
    	android:padding="5px">
    	<ImageView android:id="@+id/fut"
    		android:layout_width="wrap_content"
    		android:layout_height="wrap_content"
    		android:layout_centerHorizontal="true"
    		android:layout_alignParentBottom="true" />
    	<Button android:id="@+id/kilep_gomb"
    		android:layout_width="wrap_content"
    		android:layout_height="wrap_content"
    		android:layout_above="@id/fut"
    		android:layout_toRightOf="@id/fut"
    		android:text="@string/kilep_gomb" />
    	<Button android:id="@+id/fut_gomb"
    		android:layout_width="wrap_content"
    		android:layout_height="wrap_content"
    		android:layout_above="@id/fut"
    		android:layout_toLeftOf="@id/fut"
    		android:text="@string/fut_gomb" />
    </RelativeLayout>
                                            
  4. Az animációt a fut.xml állományban adjuk meg.

    <?xml version="1.0" encoding="utf-8"?>
    	<!--
    		fut.xml
    
    		Bátfai Norbert: Nehogy már MEGINT a mobilod nyomkodjon Téged!
    		nbatfai@gmail.com
    
    		Ezt a forrásfájlt (és a hozzá esetlegesen kapcsolódó erőforrásokat,
    		például képeket) letöltheted a http://www.tankonyvtar.hu címről.
    	-->
    <animation-list xmlns:android="http://schemas.android.com/apk/res/android"
    	android:oneshot="false">
    	<item android:drawable="@drawable/j0" android:duration="150" />
    	<item android:drawable="@drawable/j1" android:duration="150" />
    	<item android:drawable="@drawable/j2" android:duration="150" />
    	<item android:drawable="@drawable/j3" android:duration="150" />
    	<item android:drawable="@drawable/j4" android:duration="150" />
    	<item android:drawable="@drawable/j5" android:duration="150" />
    	<item android:drawable="@drawable/j6" android:duration="150" />
    	<item android:drawable="@drawable/j7" android:duration="150" />
    	<item android:drawable="@drawable/j8" android:duration="150" />
    </animation-list>
  5. Szöveges erőforrásainknak csak a nevén változtatunk.

    <?xml version="1.0" encoding="utf-8"?>
    	<!--
    		strings.xml
    
    		Bátfai Norbert: Nehogy már MEGINT a mobilod nyomkodjon Téged!
    		nbatfai@gmail.com
    
    		Ezt a forrásfájlt (és a hozzá esetlegesen kapcsolódó erőforrásokat,
    		például képeket) letöltheted a http://www.tankonyvtar.hu címről.
    	-->
    <resources>
    	<string name="app_name">Nehogy már 4</string>
    	<string name="fut_gomb">Fut</string>
    	<string name="kilep_gomb">Kilépés</string>
    </resources>
    
  6. A vászon háttérszínéhez nem nyúlunk.

    <?xml version="1.0" encoding="utf-8"?>
    	<!--
    		szinek.xml
    
    		Bátfai Norbert: Nehogy már MEGINT a mobilod nyomkodjon Téged!
    		nbatfai@gmail.com
    
    		Ezt a forrásfájlt (és a hozzá esetlegesen kapcsolódó erőforrásokat,
    		például képeket) letöltheted a http://www.tankonyvtar.hu címről.
    	-->
    <resources>
    	<color name="hatter_szin">#00aa00</color>
    </resources>
  7. A felvilantott fut.xml, main.xml, szinek.xml, strings.xml források elhelyezését segíti a következő, az Eclipse Package Explorer füléből kivágott kép.

    Az Eclipse Package Explorer füléből kivágott kép segíti az XML erőforrásfájlok helyes elhelyezését.

  8. Java forrásunk némiképp egyszerűsödik, mert az eseménykezelőben csak elindítjuk az előkészített animációt (ettől eltekintve a kód megegyezik az előző NehogyMar3 kódjával).

    /*
     * NehogyMar3Activity.java
     *
     * Bátfai Norbert: Nehogy már MEGINT a mobilod nyomkodjon Téged!
     * nbatfai@gmail.com
     *
     * Ezt a forrásfájl (és a hozzá esetlegesen kapcsolódó erőforrásokat,
     * például képeket) letöltheted a http://www.tankonyvtar.hu
     * címről.
     *
     */
    package nehogy.mar4;
    
    /**
     * A Nehogy már MEGINT könyv első Android programozási példája, bemutat egy
     * frame alapú animációt.
     */
    public class NehogyMar4Activity extends android.app.Activity {
    	android.graphics.drawable.AnimationDrawable frameAnimation;
    
    	/** Az Activity elkészítésekor hívódik. */
    	@Override
    	public void onCreate(android.os.Bundle bundle) {
    		super.onCreate(bundle);
    		/*
    		 * Mi látszódjon a képernyőn: a NehogyMar3/layout/main.xml fájl tartalma
    		 */
    		setContentView(R.layout.main);
    
    		/* Hozzáférünk a képhez, amit animálni akarunk. */
    		android.widget.ImageView integetoKep =
    			(android.widget.ImageView) findViewById(R.id.fut);
    
    		integetoKep.setBackgroundResource(R.anim.fut);
    		frameAnimation =
    			(android.graphics.drawable.AnimationDrawable) integetoKep.getBackground();
    
    		/* Hozzáférünk a Fut gombhoz. */
    		android.widget.Button futGomb =
    			(android.widget.Button) findViewById(R.id.fut_gomb);
    
    		futGomb.setOnClickListener(
    				new android.widget.Button.OnClickListener() {
    					// Ha a Fut gombra nyomtak, akkor
    					public void onClick(android.view.View v) {
    
    						frameAnimation.start();
    					}
    				});
    
    		/* Hozzáférünk a kilépés gombhoz. */
    		android.widget.Button kilepesGomb =
    			(android.widget.Button) findViewById(R.id.kilep_gomb);
    		kilepesGomb.setOnClickListener(
    				new android.widget.Button.OnClickListener() {
    					// Ha a Kilépés gombra nyomtak, akkor
    					public void onClick(android.view.View v) {
    						// befejezzük a futást.
    						finish();
    					}
    				});
    	}
    }
  9. S futtatva máris itt az animáció:

    Pillanatkép a NehogyMar4 Androidos példáról.

    Amit bemutatunk egy Motorola Droid készüléken is.

    Pillanatkép a NehogyMar4 Androidos példáról egy Motorola Droid készüléken.

Teljes képernyős asztali alkalmazás

A teljes képernyőssé alakítást közösen nem végezzük el, mert ez a következő Appletes változatból már könnyen előállítható. Ehhez segítségül a Javát tanítok [JT] digitális szakkönyv Java a játékokban: egy teljes képernyős példa - Labirintus Játék című fejezetének tanulmányozását javasoljuk.

Megvalósítás Java Appletként

Az apletté alakítást viszont most közösen is elvégezzük. Első dolgunk a felhasználói input elnyomása, azaz az előző pontban kidolgozott két gépi játékossá alakítás. Ezt követően a mobiltelefonos vásznat a leendő Applet vásznává alakítjuk. Ez nem könnyű, mert a mobilos játékban a megjelenítés és a logika nem váltak szét, hanem egy osztályban, a FociVaszon osztályban kerültek megvalósításra.

Megoldásunkban a FociVaszon osztályt három osztályra bontottuk, pontosabban két osztályra, ezek az ASApplet (Automated Soccer Applet) és a FootballMatch, melyeket a ViewableField interfész köt össze oly egyszerű módon, hogy az ASApplet ennek draw és commentator módszereit implementálja, a FootballMatch osztály pedig konstruktorában megkapja ezt az applet osztályt. Így amikor a futball mérkőzés logika szerint történik valami rajzolandó, akkor a tartalmazott applet objektum implementálta említett függvényeket meg tudjuk hívni.

Teljes megoldásunkban Automated Soccer Applet név alatt letölthető a FerSML https://sourceforge.net/projects/footballerml/files/Automated%20Soccer%20Applet%20for%20FerSML/ lapjáról.

Szurkolói avatárok

Az Automated Soccer Applet alkalmazással nem állt meg a focis játék továbbfejlesztése, jelen pillanatban a FerSML platform még mindig ezeken a kódokon alapul, az aktuális változat a Public Resource Football Computing. Ez már arra is lehetőséget ad, hogy a szurkolók által megadott XML állományok (avatárok) hajtsák meg a szimulációkat. Ez ugyanúgy Maven forrás csomagban érhető el, mint a Jávácska ONE mobil játékai. Az előző pontban említett osztályok még mindig hangsúlyosak, szerepük változatlan.

                            
public interface ViewableField {

    void draw();
    void commentator(String msg);
    void setSquadColours(int home, int away);
    void setTeamLogo(int teamIdx, java.awt.Image logo);

}
                            
                          

A módszerek listája két új metódussal bővült a Automated Soccer Applet alkalmazáshoz képest. A setSquadColours metódust is a mobil játék ihlette, egészen pontosan ugyanazt a funkciót valósítja meg, ami a mobilos játékban is megvolt, színezi a csapatok mezét.

                            
public class FootballMatch implements Runnable, FootballField, Text {

  protected ViewableField display = null;
                            
                          

Időközben a SFApplet osztály elvesztette indító szerepét, illetve további interfészt, a SimulationType interfészt is megvalósít. Ez a szimulációk típusainak megfelelő konstans nevek használatát teszi lehetővé az osztályban.

                            
public class SFApplet extends java.applet.Applet
        implements java.awt.event.KeyListener, FootballField, ViewableField, SimulationType {

  /** A Football Match that must display in this Applet. */
  FootballMatch footballMatch;
                            
                          

Az indítás ebben a verzióban a JSFA swinges osztályra hárul.

Szurkolói avatárok validálása GNU/Linux alatt

  1. Első lépés egy szurkolói avatár elkészítése, az egyszerűség kedvéért most letöltünk egyet. Például a Debreceni VSC 2010/2011 Bajnokok Ligája selejtezőkbeli Basel FC ellen vívott márkőzése alapján készítettet: http://footballerml.sourceforge.net/supporter_avatars/0.0.9/FerSML.Debrecen.avatar.xml

                                                
    $ wget http://footballerml.sourceforge.net/supporter_avatars/0.0.9/FerSML.Debrecen.avatar.xml
                                            

  2. A letöltött XML állománynak egy Relax NG kompakt szintaxissal megfogalmazott nyelvtan szerint kell érvényesnek lennie. Az ilyen nyelvtanok alapján történő validálást a jing-trang 20091111 verzójával tudjuk elvégezni. Innen töltsük le: http://jing-trang.googlecode.com/files/jing-20091111.zip Az alábbi két paranccsal letöltjük és kitömörítjük a jing csomagot.

                                                
    $ wget http://jing-trang.googlecode.com/files/jing-20091111.zip
    $ unzip jing-20091111.zip
                                            

  3. Az avatár fájlokban tipikusan használt XInclude hivatkozások feloldásához szükségünk van a Xerces2 Java csomagra, töltsük le például erről a tükörről: http://xenia.sote.hu/ftp/mirrors/www.apache.org//xerces/j/Xerces-J-bin.2.10.0.zip Az iménti lépéshez hasonlóan letöltjük és kicsomagoljuk a Xerces-t.

                                                
    $ wget http://xenia.sote.hu/ftp/mirrors/www.apache.org//xerces/j/Xerces-J-bin.2.10.0.zip
    $ unzip Xerces-J-bin.2.10.0.zip
                                            

  4. Megvan mit akarunk levalidálni és megvan, amivel. Kell még az a nyelvtan, ami szerint validálni szeretnénk. Ezt a FerSML projekt SourceForge.net lapjáról töltjük le: https://sourceforge.net/projects/footballerml/files/Football%28er%29%20Simulation%20Markup%20Language/

                                                
    $ wget https://downloads.sourceforge.net/project/footballerml/Football%28er%29%20Simulation%20Markup%20Language/FerSML0.0.9.zip
    $ unzip FerSML0.0.9.zip
                                            

  5. Nincs más hátra, mint kiadni a validáló parancsot.

                                                
    $ java -Dorg.apache.xerces.xni.parser.XMLParserConfiguration="org.apache.xerces.parsers.XIncludeParserConfiguration" -classpath jing-20091111/bin/jing.jar:xerces-2_10_0/xercesImpl.jar com.thaiopensource.relaxng.util.Driver -c 0.0.9/FerSML.avatar.rnc FerSML.Debrecen.avatar.xml
                                            

    Az a jó, ha semmi választ nem ad a program, ez a jó UNIX filozófia[5] szerint annyit tesz, hogy minden rendben. Tegyél egy próbát, rontsd a szurkolói avatár XML állományát, például törölj ki egy bezáró XML elemet és futtasd újra a parancsot!

    Szurkolói avatár validálása parancssorból.

A Public Resource Football Computing felélesztése GNU/Linux alatt

  1. Az előző feladat validálási parancs előtti lépéseire most is szükséged van, hiszen a Public Resource Football Computing maga is elvégzi a GUI felületről a validálást. S természetesen kell maga FerSML projekt aktuális Public Resource Football Computing változata. Ez egy maven forrás csomag, amit a SourceForge.net lapjáról tölthetsz le: https://sourceforge.net/projects/footballerml/files/Public%20Resource%20Football%20Computing/

                                                
    $ wget --no-check-certificate https://downloads.sourceforge.net/project/footballerml/Public%20Resource%20Football%20Computing/PublicResourceFCforFerSML-0.0.14-project.zip
    $ unzip PublicResourceFCforFerSML-0.0.14-project.zip
                                            

  2. A már megismert módon készítheted elő futtatásra a projektet.

                                                
    $ cd PublicResourceFCforFerSML-0.0.14
    $ mvn package
                                            

  3. Végül nem marad más hátra, mint kiadni az indító parancsot.

                                                
    $ java -Dorg.apache.xerces.xni.parser.XMLParserConfiguration="org.apache.xerces.parsers.XIncludeParserConfiguration" -classpath ../jing-20091111/bin/jing.jar:../xerces-2_10_0/xercesImpl.jar:target/PublicResourceFCforFerSML-0.0.14.jar hu.javacska.jsfa.JSFA
                                            

    A Public Resource Football Computing swinges indító felülete.

    A Public Resource Football Computing szimulációs felülete.

Szurkolói avatárok validálása és a Public Resource Football Computing felélesztése Windows alatt

  • Windows alatt egészen pontosan ugyanúgy kell eljárnod, mint ahogyan az imént GNU/Linux alatt bemutattuk. Azzal a különbséggel, hogy ebben az esetben a perek fordítva dőlnek és kettőspont helyett pontosvesszőt írsz. Ezért csak a grafikus programot indító utolsó parancsot mutatjuk be.

                                                
    C:\Users\Norbi\Documents\TAMOP\PublicResourceFCforFerSML-0.0.14>java -Dorg.apache.xerces.xni.parser.XMLParserConfiguration="org.apache.xerces.parsers.XIncludeParserConfiguration" -classpath ..\jing-20091111\bin\jing.jar;..\xerces-2_10_0\xercesImpl.jar;target\PublicResourceFCforFerSML-0.0.14.jar  hu.javacska.jsfa.JSFA
                                            

    A Public Resource Football Computing indítása Windows parancssorból.

A fejezet feladatainak összefoglalása

  1. Készíts Appletes portolást a focis játékból! (13 pont)

  2. Készíts egy szurkolói avatárt és validáld parancssorban! (6 pont)

  3. Készíts egy szurkolói avatárt és validáld a Public Resource Football Computing programmal! (6 pont)

  4. Készíts teljes képernyős (Java Full Screen API alapú) portolást a focis játékból! (17 pont)

  5. Portold Androidra a focis játékot! (18 pont)



[5] A program hasznos építőkocka lehet mindenféle parancssorok felépítésében.

III. rész - MELLÉKLET

5. fejezet - Funkcionális képernyőképek

Ebben a fejezetben bemutatjuk a játékok tipikus képernyőképeit:

  • 13 képet a 110% Nyári Kapitális NYFK játékból

  • 24 képet a Focijáték Neked NYFK játékból

  • és 10 képet a Hetedik Szem NYFK játékból.

Játék gráfok

A következő három pontban felvillantjuk a játékok tipikus képernyőképei közül a leggyakoribbakat, s két képenként néhány mondatban megjegyzéseket is fűzünk a képekhez.

Funkcionális pillanatképek a 110% Nyári Kapitális NYFK játékból

5.1. táblázat - A 110% Nyári Kapitális NYFK induló splash képernyője

Pillanatkép a 110% Nyári Kapitális NYFK játékból

Pillanatkép a 110% Nyári Kapitális NYFK játékból


A játék egy splash képernyővel indul. Ez mindhárom játékra igaz, bár ezek nem valódi splash képernyők, inkább csak a divat miatt kerültek a játékok elejére, hiszen egyik játék sem végez olyan hosszabb ideig tartó betöltést, amely indokolná a valódi használatukat. Ennek megfelelően nem is külön szálban kerültek megvalósításra, hanem az első induláskori betöltés alól változtatjuk az állapotjelző értékét. A jobb oldali képen az innen elérő parancsokat mutatjuk meg.

5.2. táblázat - A 110% Nyári Kapitális NYFK Névjegy parancsának részlete

Pillanatkép a 110% Nyári Kapitális NYFK játékból

Pillanatkép a 110% Nyári Kapitális NYFK játékból


A Névjegy parancsot választva a program névjegyében a licenccel kapcsolatos információkat látjuk. Jobbra a szerelék összeállítását mutató űrlapot.

5.3. táblázat - Csalizás a 110% Nyári Kapitális NYFK játékban

Pillanatkép a 110% Nyári Kapitális NYFK játékból

Pillanatkép a 110% Nyári Kapitális NYFK játékból


Itt a csali kiválasztásával folytatódik a szerelék összeállítása, illetve a játék vásznán a horgászhelyet látjuk.

5.4. táblázat - A 110% Nyári Kapitális NYFK játék horgászhelye

Pillanatkép a 110% Nyári Kapitális NYFK játékból

Pillanatkép a 110% Nyári Kapitális NYFK játékból


Ugyancsak a horgászhely, de mindkét botunk bedobva. A jobb oldali képen a telepített halak listája, ez fogási naplóként is szolgál, jelenleg üres, nincs semmi „kifogva” felirattal megjelölve.

5.5. táblázat - Halradar és kapás a 110% Nyári Kapitális NYFK játékban

Pillanatkép a 110% Nyári Kapitális NYFK játékból

Pillanatkép a 110% Nyári Kapitális NYFK játékból


Halradar segíti a csali ígéretes helyre való bedobását. A másik képen egy bődületes nagy kapás van a bal oldali boton!

5.6. táblázat - A 110% Nyári Kapitális NYFK játék horgász vásznán elérhető parancsok

Pillanatkép a 110% Nyári Kapitális NYFK játékból

Pillanatkép a 110% Nyári Kapitális NYFK játékból


Kapás a jobb oldalon is, illetve a vásznon élő parancsokat listáztuk.

5.7. táblázat - A madárdal ki-/bekapcsolásának lehetősége a 110% Nyári Kapitális NYFK játékban

Pillanatkép a 110% Nyári Kapitális NYFK játékból

 


És a néhány telefonon akár kellemetlenül is megszólalni képes madárdalt ki is tudjuk kapcsolni.

Funkcionális pillanatképek a Focijáték Neked NYFK játékból

5.8. táblázat - A splash képernyő a Focijáték Neked NYFK játékban

Pillanatkép a Focijáték Neked NYFK játékból

Pillanatkép a Focijáték Neked NYFK játékból


Bár itt több a képerőforrás, de a splash képernyő szerepe ugyanaz, mint a horgásznál.

5.9. táblázat - A 110% Nyári Kapitális NYFK játék induló képernyőre helyezett parancsai

Pillanatkép a Focijáték Neked NYFK játékból

Pillanatkép a Focijáték Neked NYFK játékból


Ennél a játéknál láthatóan több parancsot használunk, illetve jobb oldalon a szokásos névjegy részlet.

5.10. táblázat - Saját játékos labda technika, játékérzék és gyorsaság értékei Focijáték Neked NYFK játék foci szimulátorában

Pillanatkép a Focijáték Neked NYFK játékból

Pillanatkép a Focijáték Neked NYFK játékból


Listázhatjuk a saját csapatunk tagjainak aktuális labda technika, játék érzék és gyorsaság értékeit. A másik képen az eddigi VB-k statisztikáit látjuk.

5.11. táblázat - A Focijáték Neked NYFK játékban a telefon kamerája is fontos szerepet kap

Pillanatkép a Focijáték Neked NYFK játékból

Pillanatkép a Focijáték Neked NYFK játékból


A bal oldalon az aktuális VB-t jellemző adatokat mutattuk meg, a jobb oldalon az egyik „fan funkció”, a képkészítés a játékosról a telefon kamerájával.

5.12. táblázat - Indul egy mérkőzés Focijáték Neked NYFK játékbeli VB-n

Pillanatkép a Focijáték Neked NYFK játékból

Pillanatkép a Focijáték Neked NYFK játékból


Itt az elkattintott képet látjuk, illetve a játék induló képernyőjét, ahol vagy a VB egy korábban félbehagyott mérkőzését folytathatjuk, vagy elölről indul éppen valamelyik.

5.13. táblázat - Ki-kivel játszik az aktuális sorsolás szerint a Focijáték Neked NYFK játékban

Pillanatkép a Focijáték Neked NYFK játékból

Pillanatkép a Focijáték Neked NYFK játékból


Ezen a képen az itt aktuális parancsokat mutattuk meg, illetve lekértük a VB menetrendjét.

5.14. táblázat - Olasz-brazil mezőnyjáték a Focijáték Neked NYFK játékban

Pillanatkép a Focijáték Neked NYFK játékból

Pillanatkép a Focijáték Neked NYFK játékból


Az olasz-brazil meccs mezőnyjátékát és egy brazil gólt látunk.

5.15. táblázat - Az aktuális olasz-brazil mérkőzés statisztikái Focijáték Neked NYFK játékban

Pillanatkép a Focijáték Neked NYFK játékból

Pillanatkép a Focijáték Neked NYFK játékból


A következő mérkőzést ajánlja a játék, illetve az aktuális olasz-brazil statisztikáit (passzok, szerelések, gólok, lövések száma alakjában) mutatja.

5.16. táblázat - Új mérkőzés: indul a svéd-angol a Focijáték Neked NYFK játék VB-jének valóságában

Pillanatkép a Focijáték Neked NYFK játékból

Pillanatkép a Focijáték Neked NYFK játékból


Indul a következő meccs: a svéd-angol, illetve egy mezőnyjátékot mutató kép nagyobb pályaméret nézetet kérve.

5.17. táblázat - Egy angol szöglet Focijáték Neked NYFK játékban

Pillanatkép a Focijáték Neked NYFK játékból

Pillanatkép a Focijáték Neked NYFK játékból


Ugyancsak mezőnyjáték, illetve egy angol szöglet.

5.18. táblázat - Egy védés a német-amerikai meccsen Focijáték Neked NYFK játékban

Pillanatkép a Focijáték Neked NYFK játékból

Pillanatkép a Focijáték Neked NYFK játékból


Egy védés a német-amerikai meccsről, illetve mezőnyjáték a brazil-angolról.

5.19. táblázat - Tizenegyes párbaj Focijáték Neked NYFK játékban

Pillanatkép a Focijáték Neked NYFK játékból

Pillanatkép a Focijáték Neked NYFK játékból


Egy tizenegyes párbaj és a mérkőzés végének mutatása az amerikai-angol összecsapásról.

Funkcionális pillanatképek a Hetedik Szem NYFK játékból

5.20. táblázat - A Hetedik Szem NYFK játék indulása

Pillanatkép a Hetedik Szem NYFK játékból

Pillanatkép a Hetedik Szem NYFK játékból


Az előző két játék kapcsán is megemlített (a horgász esetén meg is indokolt) indító képernyő és azok parancsai láthatóak itt.

5.21. táblázat - A Hetedik Szem NYFK grafikus vászonra rajzolt menüje

Pillanatkép a Hetedik Szem NYFK játékból

Pillanatkép a Hetedik Szem NYFK játékból


A leíró képernyők közül a szokásos, a játék névjegyének licenccel kapcsolatos részletét listázót mutatjuk, illetve a játék fő vászontartalma: egy grafikus menü a jobb oldalon.

5.22. táblázat - A Hetedik Szem NYFK vásznának parancsai

Pillanatkép a Hetedik Szem NYFK játékból

Pillanatkép a Hetedik Szem NYFK játékból


A vászon választható parancsai láthatóak.

5.23. táblázat - A tudat-lenyomatok vizsgálata a Hetedik Szem NYFK játékban

Pillanatkép a Hetedik Szem NYFK játékból

Pillanatkép a Hetedik Szem NYFK játékból


Bal oldalon a minta rögzítése, jobb oldalon az elemzés és a hipotézis vizsgálat eredménye szövegesen.

5.24. táblázat - A tudat-lenyomatok vizsgálatának megjelenítése a Hetedik Szem NYFK játékban

Pillanatkép a Hetedik Szem NYFK játékból

Pillanatkép a Hetedik Szem NYFK játékból


S ugyanez grafikusan box diagramal. (A diagramok és az elemzés matematikai hátteréről részletesen a szerző doktori disszertációjában olvashatsz [PHD].)

6. fejezet - LEGO robotok Java programozása

Ebben a fejezetben megismerkedsz a LEGO robotok Java programozásával.

  • Megismered a processzor téglát és a hozzávalókat

  • lecseréled a tégla operációs rendszerét

  • elkészítesz egy viselkedés alapú robotvezérlő programot

  • majd egy PC-s és mobilos Bluetooth alapú távírányító programmal zárod le a melléklet feldolgozását.

LEGO© NXT

A korábbi LEGO© Mindstorms® Robotics Invention System (RIS 2.0) csomaghoz hasonlóan az NXT esetén is lehetőségünk van lecserélni az eredeti operációs rendszert és egy Java virtuális gépet, a leJOS rendszert tölteni a téglára. Ez megnyitja az utat, hogy Java nyelven készíthessük el robotos programjainkat. Két lehetőséget kínál a leJOS: vagy a roboton fut a vezérlő programunk (NXJ API), vagy egy távoli egységen (PC API), mondjuk asztali gépen, vagy akár egy mobilon és ekkor USB vagy Bluetooth kapcsolaton keresztül vezérli a téglát. A megfelelő API-k a projekt lapján böngészhetőek:

Első leJOS osztályaim

A RobotCarRacing osztály három névtelen osztályt tartalmaz, melyek egy-egy viselkedést reprezentálnak. Feltételezzük, hogy a robotunk két motorja (az A és a B) a két hátsó kereket hajtja meg. A harmadik kerék pedig egy bolygókerék. S az autó elejére van helyezve az (1-es portba csatlakoztatott) ultrahangos érzékelő. A leJOS rendszerben lehetőségünk van viselkedés alapú megközelítésre (behavior-based robotics, subsumption architecture [AI], [LEGO]) a robotprogramok fejlesztésénél. Ebben a példában megmutatjuk, hogyan élhetünk ezzel a lehetőséggel.

                            
/*
 * RobotCarRacing.java
 *
 * Operációs rendszerek, Mobil programozás példaprogram.
 * http://dev.inf.unideb.hu:8080/web/api
 *
 * Copyright (C) 2008 Bátfai Norbert, batfai.norbert@inf.unideb.hu
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

/**
 * A program a bevezető Matyi2Elso.java egyszerű módosításával
 * készült. Célja bemutatni olyanoknak a LEGO Javás viselkedéses
 * API-t, akik még sosem láttak ilyet. Feltesszük, hogy a robot
 * bolygókerekes.
 *
 * A Matyi2Elso.java a leJOS Viselkedés API-t bemutató példaprogram.
 * A program vezérelte MATYI-2 robot képei és videója itt
 * található: http://dev.inf.unideb.hu:8080/web/bnt
 *
 * A program három belső osztályból áll, ezek növekvő priorítás szerint a
 * következők:
 *              - megy előre (mindig)
 *              - fordul (ha az ultrahangos szenzor jelez)
 *              - leáll  (ha megnyomják az ESC gombot a proci téglán)
 *
 * @author Bátfai Norbert, batfai.norbert@inf.unideb.hu
 * @version 0.0.1
 * @see Matyi2Elso
 * @see Matyi2Masodik
 */
public class RobotCarRacing {

  public static void main(String[] args) {
    lejos.robotics.subsumption.Behavior megyViselkedes =
            new lejos.robotics.subsumption.Behavior() {

              public boolean takeControl() {
                return true;
              }

              public void suppress() {
                lejos.nxt.Motor.A.stop();
                lejos.nxt.Motor.B.stop();
              }

              public void action() {
                lejos.nxt.Motor.A.forward();
                lejos.nxt.Motor.B.forward();

              }
            };

    lejos.robotics.subsumption.Behavior fordulViselkedes =
            new lejos.robotics.subsumption.Behavior() {

              lejos.nxt.UltrasonicSensor ultrasonicSensor =
                      new lejos.nxt.UltrasonicSensor(
                      lejos.nxt.SensorPort.S1);

              public boolean takeControl() {
                return (ultrasonicSensor.getDistance() < 30);
              }

              public void suppress() {
                lejos.nxt.Motor.A.stop();
                lejos.nxt.Motor.B.stop();
              }

              public void action() {
                lejos.nxt.Motor.A.forward();
                lejos.nxt.Motor.B.backward();

              }
            };

    lejos.robotics.subsumption.Behavior leallViselkedes =
            new lejos.robotics.subsumption.Behavior() {

              public boolean takeControl() {
                return lejos.nxt.Button.ESCAPE.isPressed();
              }

              public void suppress() {
              }

              public void action() {
                System.exit(0);
              }
            };
    lejos.robotics.subsumption.Behavior[] behaviors = {megyViselkedes,
      fordulViselkedes, leallViselkedes
    };
    new lejos.robotics.subsumption.Arbitrator(behaviors).start();

  }
}
                       

10

A tömbben elfoglalt hely mutatja az adott viselkedés priorítását. Legkisebb a megyViselkedes objektum, legnagyobb a leallViselkedes mutatta objektum priorítása.

1

A megyViselkedes viselkedést feltétel nélkül hajtjuk végre, azaz, ha nincs fontosabb, akkor a robot menni fog.

3

Menni fog, méghozzá azáltal, hogy egyszerűen bekapcsoljuk a motorokat.

2

Ha ezt a „megy” viselkedést le kell állítani, nincs más dolgunk, mint a motorok leállítása (de itt állítanánk le az akció függvényben indított szálat is például).

4

A fordulViselkedes viselkedés akkor aktiválódik, ha 30 centinél közelebbinek észlel bármit az érzékelő.

6

Ekkor a kormányt kezelő motor bekapcsolásával kanyarodunk.

5

A kanyarodás leállítása kapcsán nincs további tennivalónk, így a suppress függvényt üres testtel implementáltuk.

7

A „leall” viselkedés fontosságát ne becsüljük alá! Ha nem lenne, minden alkalommal resetelhetnénk a téglát „kilépéskor”.

9

Akciója a virtuális gép leállítása.

8

S itt már (a szó szoros értelmében) nincs mit tenni...

A RobotCarRacing osztály felélesztése Windows alatt

  1. Első lépés a leJOS beszerzése és beállítása: töltsd le a projekt lapjáról! Itt én most a leJOS_NXJ_0.8.5-Setup.exe állományt választottam. Ez egy GUI alapú telepítő, ami utolsó lépésként a tégla eredeti operációs rendszerét (firmware) is lecseréli Javára. Fontos, hogy ehhez USB kapcsolat kell a tégla és a PC között (feltöltésre és kommunikációra majd alternatívaként már a Bluetooth kapcsolatot is használhatod). Ezért a leJOS telepítő előtt, követve a tutorial útmutatását, telepítsd a megfelelő USB meghajtót a gépedre!

  2. A telepítő esetemben a c:\Program Files (x86)\leJOS NXJ könyvtárba csomagolta ki a leJOS rendszert.

  3. Beállítom ennek megfelelően az NXJ_HOMEváltozót, illetve módosítom a PATH-ot az alábbiak szerint. Az az NXJ_HOME változót a kicsomagolt PATH=c:\Program Files (x86)\leJOS NXJ könyvtárra állítom, az elérési utat pedig a c:\Program Files (x86)\leJOS NXJ\bin könyvtárával frissítem, parancssorból például a

                                                
    set PATH=c:\Program Files (x86)\leJOS NXJ\bin;%PATH%

    paranccsal. Fontos, hogy a JAVA_HOME is legyen beállítva, ennek kapcsán további infót találhatsz a korábbi „Nehogy már...” könyvben, de elég annyi, hogy ránts le egy JDK-t és állítsd a könyvtárára a JAVA_HOME és ennek bin-jével bővítsd az elérési utat!

    Parancssorból az alábbi utasításokkal tudod lefordítani, majd a téglára tölteni a RobotCarRacing osztályt.

                                                
    C:\Users\Norbi\Documents\TAMOP\robot>nxjc RobotCarRacing.java
    C:\Users\Norbi\Documents\TAMOP\robot>nxjlink -v RobotCarRacing -o RobotCarRacing.nxj
    C:\Users\Norbi\Documents\TAMOP\robot>nxjupload RobotCarRacing.nxj
                                            

    A feltöltés aktuális módja attól függ, hogy be van-e dugva az USB kábel, vagy ezt mellőzve már párosítottad a téglát, mint Bluetooth eszközt.

    A leJOS használata parancssorból.

    A RobotCarRacing osztály robotra töltése.

Kormányzott autó viselkedésekkel

A BehaviorCarRacing osztály úgy készült, hogy a RobotCarRacing osztály három névtelen osztályát „nevesítettük”, külön fordítási egységbe helyeztük és egy további viselkedést adtunk a projekthez. Az itt feltételezett autó első két kereke a C motorral kormányzott.

A tapasztalatok szerint élmény tekintetében ez a projekt kissé elmarad a bolygókerekes elődjétől, de szabadon engedve a „teszt dobozok” és falrészletek alkotta alkalmi „pályán” (néha egy bogár makacsságát is belelátható) életszerű viselkedést mutat.

A BehaviorCarRacing osztályban annyi újdonsággal találkozunk, hogy a viselkedések priorításos tömbjében megjelenik az új, a FordulViselkedes osztálybeli hátratolató viselkedés. A szenzort felhasználó viselkedéseknek konstruktoraikban átadjuk ennek az objektumnak a referenciáját, hogy a viselkedések vissza tudják hívni, mert az ultrahangos szenzor lekérdezését itt valósítottuk meg. (Mert a szenzor helyes működése kapcsán keresve több helyen, például itt is találkozunk azzal a tanáccsal, hogy időben ne kérdezzük le folyamatosan az érzékelőt.)

/*
 * BehaviorCarRacing.java
 *
 * Operációs rendszerek, Mobil programozás példaprogram.
 * http://dev.inf.unideb.hu:8080/web/api
 *
 * A BehaviorCarRacing névtelen osztályainak nevesítése és további
 * viselkedés felvétele.
 *
 * Copyright (C) 2008 Bátfai Norbert, batfai.norbert@inf.unideb.hu
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

/**
 * A program a BehaviorCarRacing.java egyszerű módosításával
 * készült. Célja bemutatni olyanoknak a LEGO Javás viselkedéses
 * API-t, akik még sosem láttak ilyet. Feltesszük, hogy a robot nem
 * bolygókerekes, hanem kormányzott.
 *
 * A Matyi2Elso.java a leJOS Viselkedés API-t bemutató példaprogram.
 * A program vezérelte MATYI-2 robot képei és videója itt
 * található: http://dev.inf.unideb.hu:8080/web/bnt
 *
 * A program három belső osztályból áll, ezek növekvő priorítás szerint a
 * következők:
 *              - megy előre (mindig)
 *              - hátra (ha valami nagyon közel került)
 *              - fordul (ha valami elég közel került)
 *              - leáll  (ha megnyomják az ESC gombot a proci téglán)
 *
 * @author Bátfai Norbert, batfai.norbert@inf.unideb.hu
 * @version 0.0.1
 * @see Matyi2Elso
 * @see Matyi2Masodik
 * @see BehaviorCarRacing
 */
public class BehaviorCarRacing {

  public static final int MEGY = 0;
  public static final int FORDUL = 1;
  public static final int HATRA = 2;
  protected int allapot = MEGY;
  protected lejos.nxt.UltrasonicSensor ultrasonicSensor;
  lejos.robotics.subsumption.Behavior[] viselkedesek;

  public BehaviorCarRacing() {

    ultrasonicSensor =
            new lejos.nxt.UltrasonicSensor(
            lejos.nxt.SensorPort.S1);

    viselkedesek = new lejos.robotics.subsumption.Behavior[]{
              new MegyViselkedes(this),
              new HatraViselkedes(this),
              new FordulViselkedes(this),
              new LeallViselkedes()
            };

    lejos.nxt.Motor.A.setSpeed(200);
    lejos.nxt.Motor.B.setSpeed(200);

  }

  int elottem = 255;
  private long elozoMeresIdeje = 0;

  public int getElottem() {

    long ido = System.currentTimeMillis();
    if (ido - elozoMeresIdeje > 250) {
      elozoMeresIdeje = ido;
      elottem = ultrasonicSensor.getDistance();
    }

    return elottem;
  }

  public int getAllapot() {
    return allapot;
  }

  public void setAllapot(int allapot) {
    this.allapot = allapot;
  }

  public void start() {
    new lejos.robotics.subsumption.Arbitrator(viselkedesek).start();
  }

  public void log(String uzenet) {
    lejos.nxt.LCD.clear();
    lejos.nxt.LCD.drawString(uzenet, 0, 0);
    lejos.nxt.LCD.drawInt(allapot, 0, 1);
    lejos.nxt.LCD.drawInt(elottem, 0, 2);
    lejos.nxt.LCD.refresh();
  }

  public static void main(String[] args) {
    new BehaviorCarRacing().start();
  }
}
                       

A feltétel nélküli előre haladást módosítottuk, akkor megy előre a robot, ha előtte 1 méterre tiszta az út.

/*
 * MegyViselkedes.java
 *
 * A Nehogy már MEGINT a mobilod nyomkodjon Téged! példaprogramja.
 *
 * Copyright (C) 2008 Bátfai Norbert, batfai.norbert@inf.unideb.hu
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

public class MegyViselkedes
        implements lejos.robotics.subsumption.Behavior {

  BehaviorCarRacing behaviorCarRacing;

  public MegyViselkedes(BehaviorCarRacing behaviorCarRacing) {
    this.behaviorCarRacing = behaviorCarRacing;
  }

  public boolean takeControl() {
    return (behaviorCarRacing.getElottem() > 100);
  }

  public void suppress() {
  }

  public void action() {
    behaviorCarRacing.log("Megy");
    behaviorCarRacing.setAllapot(BehaviorCarRacing.MEGY);
    lejos.nxt.Motor.A.forward();
    lejos.nxt.Motor.B.forward();
  }
}
                       

Hátra akkor tolat a robot, ha valami túlságosan, 20 centiméternél közelebb került hozzá.

/*
 * HatraViselkedes.java
 *
 * A Nehogy már MEGINT a mobilod nyomkodjon Téged! példaprogramja.
 *
 * Copyright (C) 2008 Bátfai Norbert, batfai.norbert@inf.unideb.hu
 *
 * This program is free software: you can redistribute it and/or modify
 ...
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

public class HatraViselkedes
        implements lejos.robotics.subsumption.Behavior {

  BehaviorCarRacing behaviorCarRacing;

  public HatraViselkedes(BehaviorCarRacing behaviorCarRacing) {
    this.behaviorCarRacing = behaviorCarRacing;
  }

  public boolean takeControl() {
    return (behaviorCarRacing.getElottem() < 20);
  }

  public void suppress() {
    lejos.nxt.Motor.A.stop();
    lejos.nxt.Motor.B.stop();
  }

  public void action() {
    behaviorCarRacing.setAllapot(BehaviorCarRacing.HATRA);
    behaviorCarRacing.log("Hatra");
    lejos.nxt.Motor.A.backward();
    lejos.nxt.Motor.B.backward();
  }
}
                       

A kormány forgatásával úgy előre, mint hátramenetben akkor próbálkozik a robot, ha az előtte lévő tereptárgyat 30 és 60 centiméter közötti közelségbe méri.

/*
 * FordulViselkedes.java
 *
 * A Nehogy már MEGINT a mobilod nyomkodjon Téged! példaprogramja.
 *
 * Copyright (C) 2008 Bátfai Norbert, batfai.norbert@inf.unideb.hu
 *
 * This program is free software: you can redistribute it and/or modify
 ...
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

public class FordulViselkedes
        implements lejos.robotics.subsumption.Behavior {

  BehaviorCarRacing behaviorCarRacing;

  public FordulViselkedes(BehaviorCarRacing behaviorCarRacing) {

    this.behaviorCarRacing = behaviorCarRacing;
  }

  public boolean takeControl() {

    int tav = behaviorCarRacing.getElottem();
    return ((tav < 60) && (tav > 30));
  }

  public void suppress() {
  }

  public void action() {

    behaviorCarRacing.setAllapot(BehaviorCarRacing.FORDUL);
    behaviorCarRacing.log("Fordul");

    lejos.nxt.Motor.C.rotate(220);
    lejos.nxt.Motor.C.rotate(-220);

  }
}
                       

A leállító viselkedésen nem módosítottunk, csak külön osztályban adtuk meg.

/*
 * LeallViselkedes.java
 *
 * A Nehogy már MEGINT a mobilod nyomkodjon Téged! példaprogramja.
 *
 * Copyright (C) 2008 Bátfai Norbert, batfai.norbert@inf.unideb.hu
 *
 * This program is free software: you can redistribute it and/or modify
 ...
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

public class LeallViselkedes
        implements lejos.robotics.subsumption.Behavior {

  public boolean takeControl() {
    return lejos.nxt.Button.ESCAPE.isPressed();
  }

  public void suppress() {
  }

  public void action() {
    lejos.nxt.LCD.clear();
    lejos.nxt.LCD.drawString("LEALL", 0, 0);
    lejos.nxt.LCD.refresh();
    System.exit(0);
  }
}
                       

A példa kipróbálásánál figyelj arra, hogy a téglára töltendő fájl neve (BehaviorCar.nxj) kevesebb legyen 20 karakternél.

C:\Users\Norbi\Documents\TAMOP\LEGO\kormányos>nxjc BehaviorCarRacing.java
C:\Users\Norbi\Documents\TAMOP\LEGO\kormányos>nxjlink -v BehaviorCarRacing -o BehaviorCar.nxj
C:\Users\Norbi\Documents\TAMOP\LEGO\kormányos>nxjupload BehaviorCar.nxj
                        

Bluetooth alapú távirányító

Amíg az előző példában a programunk a téglán futott, most annak egy része (a Bluetooth master része) fut majd a téglán, másik része, a BT kliens, pedig a PC-n vagy mobiltelefonon. A változatosság kedvéért ezt a példát Linuxon élesztjük fel. Bevezetésként két egyszerű osztályt készítünk. A BTHelloNXT a PC fut majd és beköszön a téglának, ahol a BTHelloPC figyel és ezt követően visszaválaszol a PC-nek.

A BTHelloNXT osztály

                                
public class BTHelloNXT {

    public static void main(String[] args) {

        lejos.pc.comm.NXTConnector nxt = new lejos.pc.comm.NXTConnector();

        if (!nxt.connectTo("btspp://00:16:53:07:49:A0")) {
            System.out.println("Nincs kapcsolat...");
            System.exit(-1);
        }

        java.io.DataOutputStream kimenoCsatorna = nxt.getDataOut();
        java.io.DataInputStream bejovoCsatorna = nxt.getDataIn();

        try {

            String hello = "Hello, NXT!";
            byte[] hellob = hello.getBytes("US-ASCII");

            kimenoCsatorna.writeInt(hello.length());
            kimenoCsatorna.write(hellob, 0, hellob.length);
            kimenoCsatorna.flush();

            int meret = bejovoCsatorna.readInt();
            byte[] uzenet = new byte[meret];
            bejovoCsatorna.read(uzenet, 0, meret);

            System.out.println(new String(uzenet));

            bejovoCsatorna.close();
            kimenoCsatorna.close();
            nxt.close();

        } catch (java.io.IOException e) {
            System.out.println(e.getMessage());
        }
    }
}                                
                                

A BTHelloPC osztály

                                
public class BTHelloPC {

  public static void main(String[] args) {

    lejos.nxt.LCD.clear();
    lejos.nxt.LCD.drawString("Kekules...", 0, 0);
    lejos.nxt.LCD.refresh();

    try {

      lejos.nxt.comm.BTConnection pc = lejos.nxt.comm.Bluetooth.waitForConnection();

      java.io.DataInputStream bejovoCsatorna = pc.openDataInputStream();
      java.io.DataOutputStream kimenoCsatorna = pc.openDataOutputStream();

      int meret = bejovoCsatorna.readInt();

      byte[] uzenet = new byte[meret];

      bejovoCsatorna.read(uzenet, 0, meret);

      String valasz = new String(uzenet);

      lejos.nxt.LCD.clear();
      lejos.nxt.LCD.drawString(valasz, 0, 0);
      lejos.nxt.LCD.refresh();

      String hello = "Hello, PC!";

      kimenoCsatorna.writeInt(hello.length());
      byte[] hellob = hello.getBytes("US-ASCII");
      kimenoCsatorna.write(hellob, 0, hellob.length);
      kimenoCsatorna.flush();

      bejovoCsatorna.close();
      kimenoCsatorna.close();
      pc.close();

      Thread.sleep(1000);

    } catch (Exception e) {

      lejos.nxt.LCD.clear();
      lejos.nxt.LCD.drawString(e.getMessage(), 0, 0);
      lejos.nxt.LCD.refresh();

    }
  }
}                                
                                

A példa felélesztése GNU/Linux alatt

  1. Mivel a jelen fejlesztési szintünkön a Windows parancssor nem tér el a Linuxos parancssortól, így a korábban ismertetett letöltést, kicsomagolást nem ismertetjük. A néhány szintaktikai különbség miatt (nem set, hanem export; nem pontosvessző, hanem kettőspont) viszont bemutatjuk a parancssorban most kiadott utasításokat.

                                                
    norbi@sgu:~/robot$ export NXJ_HOME=/home/norbi/robot/lejos_nxj/
    norbi@sgu:~/robot$ export PATH=/home/norbi/robot/lejos_nxj/bin/:$PATH
    norbi@sgu:~/robot$ export CLASSPATH=$CLASSPATH:.:/home/norbi/robot/lejos_nxj/3rdparty/lib/bluecove-gpl.jar:/home/norbi/robot/lejos_nxj/lib/pccomm.jar:/home/norbi/robot/lejos_nxj/3rdparty/lib/bluecove.jar
    
                                            

  2. A téglán elindítom az előző lépésben rátöltött BTHelloPC osztályt.

    A téglán futó BTHelloPC osztály.

  3. Lefordítom a téglára töltendő osztályt, majd a téglára töltöm.

                                                
    norbi@sgu:~/robot$ nxjc BTHelloPC.java
    norbi@sgu:~/robot$ nxjlink -v BTHelloPC -o BTHelloPC.nxj
    
    norbi@sgu:~/robot$ nxjupload BTHelloPC.nxj
    leJOS NXJ> Failed to load USB comms driver: Cannot load USB driver
    BlueCove version 2.1.0 on bluez
    leJOS NXJ> Connected to NXT
    leJOS NXJ> Upload successful in 5703 milliseconds
    BlueCove stack shutdown completed
    
                                            

  4. A PC-s részt a javac paranccsal fordítom és a PC-n futtatom.

                                                
    norbi@sgu:~/robot$ javac BTHelloNXT.java
    norbi@sgu:~/robot$ java BTHelloNXT
    BlueCove version 2.1.0 on bluez
    Hello, PC!
    BlueCove stack shutdown completed
    
                                            

  5. A lejos.pc.comm.NXTConnector osztály connectTo metódusának paraméterét fel tudod deríteni például a hcitool parancs használatával.

                                                
    norbi@sgu:~$ hcitool scan
    Scanning ...
            00:16:53:07:49:A0       NXT
                                            

A fejezet feladatainak összefoglalása

  1. Telepítsd fel a saját gépedre és tégládra a leJOS rendszert! (2 pont)

  2. Fordítsd le és futtasd a RobotCarRacing osztályt! (2 pont)

  3. Építs új szenzort a robotodra és írj hozzá egy viselkedést! Például sötétben menjen hátrafelé. (7 pont)

  4. A RobotCarRacing osztály viselkedéseit bővítsd a hártatolatás képességével. (9 pont)

  5. Találj ki és valósíts meg komplexebb viselkedést az action függvényben! Például egy új szálban. (10 pont)

  6. Fordítsd le és futtasd a távirányítós példa osztályait! (3 pont)

  7. Módosítsd úgy a a távirányítós példa osztályait, hogy implementáljanak egy egyszerű protokollt. A protokoll PC felőli utasításkészlete legalább olyan gazdag legyen, hogy tartalmazza a következő parancsokat: START (A|B|C), STOP (A|B|C), ROTATE (A|B|C), EXIT. (9 pont)

  8. Lásd el grafikus felülettel a távirányítót, azaz legyen lerajzolva! (9 pont)

  9. Alakíts olyan istállót, amely sikerrel tudja róni a köröket valamelyik Jávácska kupa rögzítette pályán! (20 pont)

Irodalomjegyzék

Idézetek

[MARX] Marx, György. Gyorsuló idő. Typotex . 2005.

[Stallman] Stallman, Richard. Free and Open Source Java. http://www.sun.com/software/opensource/java/ http://mediacast.sun.com/share/tmarble/stallman3.ogg . 2010.

[Bolling] Ekblom (editor), Bjorn. Football (Soccer) Handbook of Sports Medicine and Science. 0 632 03328 2. Blackwell Scientific Publications . 1994.

[Gartner] Gartner Highlights Key Predictions for IT Organisations and Users in 2008 and Beyond. http://gartner.com/it/page.jsp?id=593207 . 2010.

[NHIT] Dömölki (editor), Bálint. Égen-földön informatika: az információs társadalom technológiai távlatai. Typotex. 2008.

[METAMATH] Chaitin, Gregory. META MATH! The Quest for Omega. http://www.cs.auckland.ac.nz/CDMTCS/chaitin/omega.html .

[Hacker] Raymond, Eric S.. How To Become A Hacker (Hogyan lesz az emberből Hacker). http://catb.org/~esr/faqs/hacker-howto.html http://esr.fsf.hu/hacker-howto.html . 2010.

[TenYears] Norvig, Peter. Teach Yourself Programming In Ten Years. http://norvig.com/21-days.html . 2010.

[EMBER] Madách, Imre. AZ EMBER TRAGÉDIÁJA. http://mek.niif.hu/00800/00849/html/01.htm#15 . 2010.

[KERNIGHANP] Kernighan, Brian W. és Plauger, P. J.. A programozás magasiskolája. Műszaki. 1982.

Szórakoztató ismeretterjesztés

[KAPCSOLAT1] Zemeckis, Robert. Contact. http://www.imdb.com/title/tt0118884/ . 1997.

[KAPCSOLAT2] Sagan, Carl. Kapcsolat. Édesvíz. 1993.

[KVANTUM1] Arntz, William és Chasse, Betsy. What the #$*! Do We (K)now!? Mi a csudát tudunk a világról?. http://www.imdb.com/title/tt0399877/ http://www.whatthebleep.com/ . 2004.

[KVANTUM2] Penrose, Roger és Hawking, Stephen. A nagy, a kicsi és az emberi elme. Akkord. 2003.

Programozás

[NEHOGY] Bátfai, Norbert. Nehogy már a mobilod nyomkodjon Téged!. 978 963 473 094 1. Debrecen, DEENK http://www.eurosmobil.hu/NehogyMar . 2008.

[NEHOGY2] Bátfai, Norbert. Nehogy már megint a mobilod nyomkodjon Téged! (keziratban). Kempelen Farkas Digitális Felsőoktatási Tankönyvtár http://www.tankonyvtar.hu . 2010.

[KERNIGHANC] Kernighan, Brian W. és Ritchie, Dennis M.. A C programozási nyelv. Műszaki. 1993.

[REVOLUTION] Bátfai, Norbert, Bátfai, Erika, és Psenáková, Ildikó. Jávácska One: Open Source Mobile Games to Revolutionize Education of Programming (submitted). 2010.

[PHD] Bátfai, Norbert. Mobiltelefonos játékok tervezése és fejlesztése. Doktori (PhD) értekezés. http://www.inf.unideb.hu/~nbatfai/phd2/. Debrecen, DE IK http://www.inf.unideb.hu/~nbatfai/phd2/ . 2010.

[PP] Bátfai, Norbert. Programozó Páternoszter. http://www.inf.unideb.hu/~nbatfai/ProgramozoPaternoszter.pdf . 2007.

[JT] Bátfai, Norbert és Juhász, István. Javát tanítok. Bevezetés a programozásba a Turing gépektől a CORBA technológiáig. Kempelen Farkas Digitális Felsőoktatási Tankönyvtár http://www.tankonyvtar.hu/site/upload/pdf/b10108.pdf http://www.tankonyvtar.hu/informatika/javat-tanitok-javat-080904 . 2007.

Mobil

[EUROSMOBIL] EUROSMOBIL JÁTÉKOK - Eleve mobilra kitalált eredeti játékok!. http://www.eurosmobil.hu . 2007.

Gyerekeknek

[J] Bátfai, Norbert és Bátfai, Erika. Fantasztikus programozás. Debreceni Egyetem Egyetemi és Nemzeti Könyvtár http://javacska.lib.unideb.hu/konyv/bv-naploja-kezirat-I-5_0_0.pdf . 2004.

Foci

[FERSML] Bátfai, Norbert. Footballer and Football Simulation Markup Language and related Simulation Software Development. Journal of Computer Science and Control Systems. 2. 13-18. 2010. Journal of Computer Science and Control Systems http://electroinf.uoradea.ro . 2010.

[KAVATAR] Bátfai, Norbert és Bátfai, Erika. Kis XML állományok gyűjteményeinek kezelése a labdarúgásban (beküldve). 2010.

Tudat

[Libet] Libet et. al., Benjamin. Subjective referral of the timing for a conscious sensory experience. Brain. 102. 193-224. 1979.

[Kornhuber] Kornhuber et. al., Hans H.. Voluntary finger movement in man: Cerebral potentials and theory. Biological Cybernetics. 23. 1976.

[ALGORITMUSOK] Rónyai, Lajos, Ivanyos, Gábor, és Szabó, Réka. ALGORITMUSOK. Typotex. 1998.

[SZTOCHSZT] Tusnády, Gábor. Sztochasztikus számítástechnika. Kossuth Egyetemi Kiadó. 1996.

Robotok

[AI] Brooks, Rodney A.. Intelligence without representation. Artificial Intelligence. 47. 139-159. 1991.

[LEGO] Bagnall, Brian. Maximum Lego NXT: Building Robots with Java Brains. Variant Press. 2009.