Content extract
Debreceni Egyetem Természettudományi Kar DIPLOMAMUNKA WAP ALAPÚ ALKALMAZÁS FEJLESZTÉSE Témavezeto: dr. Fazekas Gábor dr. Paller Gábor – egyetemi docens – Nokia Magyarország KÉSZÍTETTE : SZEGEDI ZOLTÁN PROGRAMTERVEZO MATEMATIKUS Tartalomjegyzék I. WAP . 5 II. WBMP FORMÁTUM . 7 II1. A WBMP SZINTAXISA 7 II2. FEJLÉC FELÉPÍTÉSE8 III. EGY WBMP FORMÁTUM ISMERTETÉSE .10 IV. A WML NYELV .11 IV1. ENTITÁSOK . 11 IV2. CÍMKÉK (TAG-EK) . 11 IV3. ATTRIBÚTUMOK . 12 IV4. MEGJEGYZÉSEK . 12 IV5. NAGYBETU ÉRZÉKENYSÉG . 13 IV6. A WML DOKUMENTUM FELÉPÍTÉSE. 13 IV7. KÁRTYA ÉS LAPOK . 13 IV8. ESEMÉNYKEZELOK. 15 IV9. TASZKOK. 18 IV10. VÁLTOZÓK . 19 IV11. INTERAKTIVITÁS . 21 IV12. HIVATKOZÁSOK, KÉPEK ÉS IDOZÍTOK. 24 IV13. SZÖVEG FORMÁZÁSA . 25 V. A WMLS CRIPT NYELV .27 V1. A NYELV LEXIKAI FELÉPÍTÉSE. 27 V2. VÁLTOZÓK ÉS ADAT TÍPUSOK. 28 -2 - V3. MUVELETEK ÉS KIFEJEZÉSEK. 30 V4. FÜGGVÉNYEK . 34 V5.
UTASÍTÁSOK. 35 V6. KÖNYVTÁRAK . 38 V7. PRAGMÁK . 38 V8. AUTOMATIKUS TÍPUSKONVERZIÓS SZABÁLYOK . 40 V9. WMLSCRIPT KÖNYVTÁRAK . 41 V10. WMLSCRIPT PÉLDA 47 VI. WML TARTALOM GENERÁLÁSA MÁS NYELVEKKEL .49 VI1. A CGI HASZNÁLATA WML TARTALOM GENERÁLÁSÁRA. 49 VI2. A PHP HASZNÁLATA WML TARTALOM GENERÁLÁSÁRA . 50 VI3. AZ ASP HASZNÁLATA WML TARTALOM GENERÁLÁSÁRA . 51 VI4. A JSP NYELV . 51 VII. AZ ELKÉSZÍTETT JÁTÉK .55 VIII. A JÁTÉK DOKUMENTÁLÁSA .56 VIII1. WBMP .JAVA 60 VIII2. LABIRINT .JAVA 69 VIII3. LABIRINTGAME.JAVA 73 VIII4. BELEPTET.JAVA 79 VIII5. REGISZTRALAS.JAVA 86 VIII6. GAME.JAVA 91 VIII7. CREATE.JAVA 103 VIII8. KILEPES.JAVA 113 VIII9. FRISSITES.JAVA 117 VIII10. FIGHT.JAVA 119 VIII11. REKORDOK .JAVA 124 -3 - VIII12. CREATELABIRINT.JAVA 126 VIII13. UPDATE.JAVA 129 IX. X. VÉGSZÓ .130 FELHASZNÁLT IRODALOM .131 Diplomamunkámban célja az, hogy bemutassam a WAP 1.1 szabványt, és a WML,
WMLScript tartalmat A WML ismertetése elott röviden bemutatom a WBMP formátumot, mely egy olyan kép formátum, mely a mobil hálózatra lett optimalizálva. A WBMP formátum is része a WAP szabványnak A fo cél ezt követoen az, hogy megmutassam azt, hogy hogyan lehet alkalmazásokat fejleszteni mobil telefonra a WML nyelvet használva. Ezt egy saját fejlesztésu, mobiltelefonon használható (WAP-os) játék elkészítésén keresztül mutatom be. A játékot Java nyelven készítem el, szervletek formájában Programozási nyelvként azért a Java nyelvet választottam a PHP, CGI vagy ASP helyett (melyek WML oldal generálására szintén alkalmasak), mert a Java segítségével átláthatóbb módon lehetett a programot elkészíteni. A döntésem mellett szólt az is, hogy a fejlesztés során használt Jakarta-Tomcat webszerver Java-alapú alkalmazás. Szót ejtek még arról is, hogy a PHP, CGI és ASP segítségével hogyan lehet WML oldalakat generálni, valamint egy
nagyobb részben írok a JSP-rol is, mely felhasználásával szintén lehet készíteni WML oldalakat, és a nyelv használata nagyon hasonlít a Java szervletek használatához. Az egyes szervletek ismertetése között a Nokia Wap Toolkit 1.2-ben levo Nokia 6150-es telefon kijelzojén jelennek meg az egyes WML oldalak, demonstrálva a szervletek kimenetének eredményét. Ezek után következik mindig az adott szervlet forráskódja, melybol azonban a legfontosabb utasításokat, sorokat korábban majd elemezni, magyarázni fogom. A teljes forráskód után az egyes szervletek által elkészített WML oldalak forrásai is megjelennek, és – mint késobb kiderül majd – mivel a szervletek felépítése nagyon hasonlít a JSP oldalakhoz, ezért bemutatom az elkészített játék JSP forrását is. A JSP forrásnál azonban nem mutatom be részletesen minden egyes szervletnek megfelelo JSP oldalt, hanem csupán a leglényegesebbeket, a többi oldalnak csak a forrását mutatom meg.
Mind a WML és a JSP oldalak esetében a kulcsszavak kiemelve jelennek meg a jobb átláthatóság érdekében. A diplomamunka legvégén néhány mondatban összefoglalom az eredményeket és a lehetséges további fejlesztési lépéseket. -4 - WAP alapú alkalmazás fejlesztése WAP I. WAP A WAP két egyre gyorsabban fejlodo technológia határán helyezkedik el. Ez a két technológia az Internet és a mobil kommunikáció. A WAP (Wireless Application Protocoll – Vezetéknélküli Alkalmazási Protokoll) a WAP Forum azon törekvésének az eredménye melynek az a célja, hogy egy ipari szélességu szabványt hozzon létre, mely alkalmas vezetéknélküli hálózaton keresztüli alkalmazások fejlesztésére. A WAP Forum 1997 végén alakult, alapító tagjai a Nokia, Ericsson, Motorola és a Phone.Com (Unwired Planet) voltak Jelenleg több mint 100 tagot tömörít. Tagja többek között a Microsoft és az IBM is Az Internethez fejlesztett alkalmazások általában
valamilyen asztali számítógépeket, és gyors hozzáférést igényelnek. A tömegpiac – a kézi mobil eszközök – ezzel szemben sokkal kisebb kapacitású eszközöket használ. Ezen eszközök • Kisebb teljesítményu processzorral, • Kevesebb memóriával, • Kisebb megjelenítovel, • Más beviteli eszközzel rendelkeznek, mint az asztali eszközök. A vezetéknélküli hálózatok is sokkal kisebb teljesítményuek, mint a vezetékes hálózatok. Ezt mutatja a következo táblázat, mely összeveti a kétfajta hálózat különbségeit: • • • • Internet Asztali vagy nagyobb teljesítményu • számítógépek használják Közepesnél nagyobb sávszélesség (>33.6 • kbit/s) Megbízható hálózat (kicsi késleltetési ido, kevés • esély a csomag-vesztésre) • Könnyen kezelheto perifériák Mobil hálózat Kis teljesítményu processzor, kevés memória Kis sávszélesség (9.6 kbit/s – 144 kbit/s, 43.2 kbit/s) Megbízhatatlan hálózat
(nagyobb késleltetési ido, nagy az esély a csomagvesztésre) Nehézkesen kezelheto perifériák (telefonbillentyuzet) Egy WAP felhasználói eszköz (angolul: user agent, továbbiakban felhasználói eszköz vagy eszköz) nagyon hasonlít a böngészokhöz. A különbség az, hogy az eszköz a megfelelo URL-eket a mobil hálózaton keresztül tölti le. A digitális felhasználói eszközök – mint amilyenek a mobiltelefonok – egyre népszerubbek lettek. Egy mobiltelefon manapság már nem egy egyszeru telefon, hanem egy olyan kommunikációs eszköz, mely képes alkalmazásokat futtatni és más eszközökkel, alkalmazásokkal kommunikálni a vezetéknélküli hálózaton keresztül. Egy WAP alkalmazás tartalmaz egy szerver- és egy kliensalkalmazást. A kliensalkalmazást a WAP átjáró (WAP Gateway) letölti az alkalmazás szerverrol, és végrehajtás céljából átküldi az eszköz felé. Szükség van egy szabványos alkalmazáskörnyezetre azért, hogy az
alkalmazások a különbözo eszközökön ugyanúgy jelenjenek meg. A WAP biztosítja ezt a környezetet egy böngészo és egy script interpreter formájában. – A WAP böngészo hasonlít egy WEB böngészohöz és a WML tartalom kezelésére képes. – A script interpreter a WMLScriptben megírt scriptek kezelésére alkalmas. A WAP szabvány tartalmaz még beépített könyvtárat is a WMLScript számára. A WML és WMLScript tartalmak a vezetéknélküli kommunikációra lettek kifejlesztve, ezért binárisan kódolt formában történik azok továbbítása az eszköz felé. A mobil hálózat és az Internet más protokollt használ. A két protokoll közti konverzió megvalósítása a feladata a WAP Gateway-nek. -5 - WAP alapú alkalmazás fejlesztése WAP A WAP protokoll muködését szemlélteti a következo ábra: forrás: Nokia Wap Toolkit 2.1 UsersGuidepdf A WAP modell hasonlít a web modellhez, és a következoképpen muködik: 1. A felhasználó megnyom egy
gombot a telefonon, melyhez egy URL van rendelve 2. A felhasználói eszköz egy URL kérést küld a WAP Gateway felé a WAP protokollt használva 3. A Gateway a kapott kérésnek megfelelo HTTP kérést generál, melyet elküld a Web Server felé 4. A Web Server feldolgozza a kapott kérést. A kérés vonatkozhat egy statikus oldalra, valamint egy scriptre is. Ha egy statikus oldalra mutat, akkor azt beolvassa, vagy script esetén azt elindítja 5. A web server a beolvasott oldalt, vagy a szervlet kimenetét átküldi a Gateway felé 6. A Gateway ellenorzi a kapott forrást, és bináris formátumúvá alakítja át. Egy WAP választ generál, és elküldi azt az eszköz felé 7. Az eszköz fogadja a választ, és megjeleníti a kapott oldal elso kártyáját -6 - WAP alapú alkalmazás fejlesztése WBMP formátum II. WBMP FORMÁT UM A WBMP egy beágyazott adatformátum olyan értelemben, hogy a képen kívül sok más információt tartalmaz (pl. információt a
palettáról, a kép bit szintjérol stb) Egy WBMP formátum két részre bontható: 1. Az általános fejléc azokat az információkat tartalmazza, melyek minden típusú formátumban elofordulnak: ü Típus ü Szélesség és magasság ü WBMP verzióazonosító A típus azonosító jelöli a beágyazott kép formátumát. Jelenleg még csak a 0 típus van specifikálva 2. Típus specifikus formátumok leírása A WBMP formátum a következo tulajdonságokkal rendelkezik: Ø Tömör bináris kódolást alkalmaz Ø Skálázható, azaz lényegében fel van készítve a jövobeli összes képfelbontásra és típusra (szín mélység, animációk stb.) Ø A kliensen kevés számítást igényel A formátum lehetové teszi, hogy grafikus információ jusson el a mobil eszközhöz. Terminál független és csak a grafikus információt írja le. WBMP típusazonosító A WBMP formátum –, melyet a típusazonosító mezo azonosít (ld. TypeField mezo, késobb) – tartalmazza a képrol a
következo információkat: § Pixelszervezés és -kódolás § Palettaszervezés és -kódolás § Tömörítés § Animáció kódolása Minden egyes TypeField értéknek megfelelo kép a WAP dokumentáció részeként teljesen specifikálva van, azonban jelenleg csak egy egyszeru, tömör, fekete-fehér (monokróm) képformátum létezik. Képtípus azonosítója (több bájtos egész) 0 Képformátum leírása Fekete/fehér, tömörítetlen Amikor egy WAP szerver inicializál egy folyamatot, a felhasználói eszköz közli az általa támogatott WBMP típusokat. Ezeket egy szabványos Accept:, vagy Content-Type: WSP HTTP fejléccel közli: Accept: image/vnd.wapwbmp; level=0 vagy Content-Type: image/vnd.wapwbmp; level=0 A „level” paraméter a korábban említett típusazonosítóra utal. Jelenleg csak a level=0 van támogatva, melynek a leírása késobb következik. II1. A WBMP SZINTAXISA A következoben bemutatom a WBMP formátum BNF-szeru leírását. A leírásban a
„|” karakter az alternatívákat jelöli, a nagybetus szavak az egybájtos adatokat jelölik, melyeket késobb bovebben definiálunk. Tájékoztatásul: „(” és „)” az elemek csoportosítására valóak, az opcionális elemek „[” és „]” között vannak. Az elemeket megelozheti egy <N>* mely a következo elem N vagy többszöri ismétlést jelöli (N, ha nincsen megadva, akkor alapesetben 0). -7 - WAP alapú alkalmazás fejlesztése WBMP formátum W-Bitmap = Header Image-data Header = TypeField FixHeaderField [ ExtFields ] Width Height TypeField = ’a kép típusa, melyet korábban definiáltunk’ FixHeaderField = ’Octet lsd. Késobb’ ExtFields = *ExtFieldType00 | ExtFieldType00 | ExtFieldType10 | ExtFieldType11 ExtFieldType00 =’Octet lsd. Késobb’ ExtFieldType01 =’Octet lsd. Késobb’ ExtFieldType10 =’Octet lsd. Késobb’ ExtFieldType11 = ParameterHeader ParameterIdentifier ParameterValue ParameterHeader = ’Octet lsd. Késobb’
ParameterIdentifier = ’paraméter azonosító ( US-ASCII sztring), hossza (<= 8 bájt) a ParameterHeader-ben definiált’ ParameterValue = ’paraméter értéke (alfanumerikus sztring), hossza (<= 16 bájt) a ParameterHeader-ben definiált’ Width = ’A kép szélessége pixelben – több bájtos egész’ Height = ’A kép magassága pixelben – több bájtos egész’ Image-data = Main-image *Animated-image ; ’max 15 animált kép lehet’ Main-image = ’kép, mely struktúrája a TypeField mezoben definiált kép struktúrának felel meg’ Animated-image = ’kép, mely struktúrája késobb kerül definiálásra’ II2. FEJLÉC FELÉPÍTÉSE Több bájtos egész formátum (multi-byte integer) A WBMP képkódolás az egész számokat egy több bájtos egész formátummá alakítja át. Egy „több bájtos egész” oktetek (8 bit) sorozatából áll, ahol a legfontosabb bit a folytatásjelzo bit és a maradék 7 bit skalár értéket tartalmaz. Legfontosabb bit
alatt a következot kell érteni: például 10-es számrendszerben a 897-nél a legfontosabb szám a 8, azaz a legfontosabb bit a legnagyobb helyiértéken levo információt jelöli. A folytatásjelzo bit azt jelzi, hogy az oktet nem vége a több bájtos adatnak. Egy egész szám N darabból álló oktet sorozattá van kódolva. Az elso N-1 oktet folytatásjelzo bitje 1-re van állítva A sorozat utolsó oktetjében 0 ez a bit. A maradék 7 bit minden egyes oktetben úgy van kódolva, hogy a legfontosabb bit a legelso. Az összefuzött oktetek szintén az un bigendian sorrendnek megfeleloen követik egymást, azaz a legfontosabb oktet helyezkedik el legelöl. Fejléc formátum A fejléc mezo tartalmaz egy több bájtos típusazonosítót (TypeField), egy általános fejléc információt, mely 1 oktet hosszú (FixHeaderField), 0 vagy több darab un. kiegészített (toldalék) fejléc mezot (ExtField), egy szélesség és egy magasság mezot (Width, Height) mezo név TypeField
FixHeaderField ExtHeaderField Width Height hossz bitben (h,k,m és n tetsz. egész) 8.8*h 8 0.8*k 8.8*m 8.8*n A FixHeaderField mezo felépítése: Leírás toldalékfejléc jelzo bit toldalékfejléc típus 1. bit toldalékfejléc típus 2. bit fenntartva fenntartva fenntartva fenntartva fenntartva -8 - Bit 7 6 5 4 3 2 1 0 WAP alapú alkalmazás fejlesztése WBMP formátum Toldalék fejlécek lehetnek 00, 01, 10 vagy 11 típusúak, melyeket a FixHeaderField-ben levo 5. és 6. bit jelez Az egyes típusok a következot jelölik: • 00 típus: egy több bájtos bitmezot jelöl, melyet további fejléc információk megadására használnak. Az elso bit be van állítva 1-re, ha további toldalék fejlécek következnek; 0, ha az utolsó volt. • 01 típus: jelenleg nem használt • 10 típus: jelenleg nem használt • 11 típus: egy paraméter/érték pár sorozatot jelöl. Ezeket lehet használni optimalizálásnál és további információk jelölésénél, például
animált képformátum esetében. A „paraméter méret” mezo megadja a hosszát a paraméter névnek, a „paraméter érték” megadja a hosszát a paraméter értéknek. Az „összefuzés” jelzobit megmutatja, hogy következik-e további paraméter/érték pár. Az 11 típus toldalékfejléc mezojének leírása: leírás összefuzés jelzobit paraméter azonosító hossza bájtban 1. bit paraméter azonosító hossza bájtban 2. bit paraméter azonosító hossza bájtban 3. bit paraméter érték hossza bájtban 1. bit paraméter érték hossza bájtban 2. bit paraméter érték hossza bájtban 3. bit paraméter érték hossza bájtban 4. bit -9 - bit 7 6 5 4 3 2 1 0 WAP alapú alkalmazás fejlesztése Egy WBMP formátum ismertetése III. EGY WBMP FORMÁT UM ISMERTETÉSE A0 ü ü ü ü ü típusú WBMP kép a következo tulajdonságokkal rendelkezik: Nincs tömörítés alkalmazva Szín: 1 bites (fehér: 1; fekete: 0) Színmélység: 1 bit (monokróm) Minden egyes
bájt legmagasabb értéku bitje a bájt balra legszélsobb pixelét jelöli Az elso sor a kép legfelso sorát jelöli A fejléc mezok felépítése: adat típus TypeField (típus mezo) FixHeaderField (fix fejléc) ExtHeaderField (toldalék fejléc) Width (szélesség) Height (magasság) hossza bitekben ( h, k tetsz. egész ) 8 8 0 8.8*h 8.8*k A fix fejléc felépítése: leírás folytatás jelzo bit toldalékfejléc típus 1. bit toldalékfejléc típus 2. bit foglalt foglalt foglalt foglalt foglalt bit értéke 0 bármi bármi 0 0 0 0 0 Ennél a WBMP képformátumnál nincsen szükség toldalék fejlécekre. A WBMP kép pixel sorokba van szervezve, melyek oktetek sorozataként vannak reprezentálva. 1 bit 1 pixelt jelent, mely értéke 0 vagy 1 lehet. 0 esetében a pixel intenzitása fekete, 1 esetében pedig fehér Abban az esetben, amikor egy sor hossza nem osztható 8-cal, a következo sor kódolása a következo oktetnél kezdodik, a maradék bit 0 kell, hogy legyen. Egy
sor esetében a legelso bit jelöli a balszélso pixelt Az elso sor a kép legfelso sorát jelöli. - 10 - WAP alapú alkalmazás fejlesztése A WML nyelv IV. A WML N YE LV A WML (Wireless Markup Language) egy XML nyelv, mely örökölte annak karakterkészletét. Alapegysége a lap (card), mely egy egyszeru párbeszédet tesz lehetové a felhasználói eszköz és a felhasználó között. A WML nyelv a következo két szavakat használja: deck és card. A deck nem jelent mást, mint azon webszerveren levo állomány, melyet a szerver elküld a mobil eszközre. Lényegében egy statikus oldal, a HTML oldal megfeleloje. A card egy olyan fogalom, mely egy a mobil eszközön egyszerre megjeleno oldalt azonosít. Egy deck-en belül több card is lehet A továbbiakban a deck és a card szavak helyett helyenként a kártya és a lap szavakat használom. A lapokat a nyelv kártyákba (deck) szervezi. Amikor az eszköz fogad egy kártyát, akkor alapesetben megjeleníti annak elso
lapját, azonban a késobbiek során majd kiderül, hogy át lehet irányítani más lapra is a megjelenítést. A WML egy nagybetuérzékeny nyelv, azaz a Wml és a wml szavak különbözot jelentenek. A nyelv az egymást követo újsorokat, tabulátor jeleket, üres helyeket kicseréli egy sima üres helyre, azaz a forrás a jobb átláthatóság érdekében tetszolegesen átalakítható, a „szavak” közötti helyek nem befolyásolják a végeredményt. IV1. ENTITÁSOK A WML tartalmazhat számozott vagy nevesített entitásokat (egyedeket), melyek segítségével speciális karaktereket lehet beilleszteni a dokumentumba. Ezeket az egyedeket arra használjuk, hogy helyettesítsük azon karaktereket, melyeket nehéz beírni a szövegszerkesztoben, vagy melyeket „szöktetni” kell, mivel magukban más jelentéssel bírnak. Ilyen karakter például az & karakter, melyet a & entitással lehet megjeleníteni. IV2. CÍMKÉK (TAG-EK) A címkék a nyelv leíró eszközei.
Egy címke leír egy elemet és tartalmazza az elem típusának a nevét és egy egyedi azonosítót. Egy elem tartalmazhat attribútumokat is Minden egyes címkét a nyelvben be kell zárni kisebb-nagyobb jelek közé (< és >). <címke> </címke> <címke/> Ez egy elem kezdetét – „fejét” – jelzi. A fej tartalmazhat csak attribútumokat Az elem végét jelzi. Ez egy üres elemet jelez. Ilyen például a <br/>, mely az újsort jelzi Elemek Az elemek adják meg a WML kártya leíró és strukturális információit. Az elemek egy kezdo címkébol, egy tartalomból, és egy végcímkébol állnak. Egy elem tartalmazhat más elemeket is, tehát azok egymásba ágyazhatóak. A következo két alakjuk lehet: <elem> tartalom </elem> vagy <elem/> Egy üres elem, – mely <elem/> alakú – nem tartalmaz tartalmat. A következo táblázat leírja, hogy a WML dokumentum milyen elemeket tartalmazhat. Ezen elemeket a késobbiekben
bovebben bemutatom. Kategória WML elem lapok és kártyák wml card template head access meta - 11 - WAP alapú alkalmazás fejlesztése A WML nyelv események do ontimer onenterforward onenterbackward onpick onevent postfield go prev refresh noop setvar input select option optgroup fieldset a anchor img timer br p table tr td taszkok változók beviteli mezok linkek, képek, idozítok szöveg formázó elemek A WML elemeket egy lap különbözo komponenseinek a leírására lehet használni. Szükség lehet a lap használata során arra, hogy kapcsolatot teremtsünk két dokumentum között, vagy egy dokumentum két része között. A nyelvnek ezeket a komponenseit nevezzük linkeknek Az olyan eszközre is szükség lehet, mely segítségével egy feladatot lehet elvégeztetni. Ezeket a komponenseket taszkoknak nevezzük IV3. ATTRIBÚTUMOK Sok elem lehetové teszi, hogy különbözo paramétereket tartalmazzon. Az paraméterek az elem számára további információt
tartalmaznak. Paramétereket csak az elemek kezdo címkéje tartalmazhat, a következo szintaxist alkalmazva: <elem attributum1="ertek1" attributum2="ertek2" . > Az attribútumok értékeit idézojelek közé kell tenni. Fontos, hogy az attribútum neve minden esetben kisbetus legyen. Néhány elem esetében vannak kötelezo paraméterek, melyeket feltétlenül meg kell adni. Ilyen van például a <go> elemnél: <go href="http://www.destinationdes" > Más attribútumok opcionálisak, melyek megadása nem kötelezo. Ezen attribútumok általában alapértelmezett értékkel rendelkeznek. Ilyen például az align attribútum az img elemnél, mely alapértelmezett értéke bottom lesz. IV4. MEGJEGYZÉSEK A WML nyelv ugyanazt a megjegyzési formátumot alkalmazza, mint az XML. Ennek megfeleloen a megjegyzések alakja a következo: <!-- egy megjegyzés --> - 12 - WAP alapú alkalmazás fejlesztése A WML nyelv A megjegyzéseket
a WML oldal szerzoje írja be, és azokról a másik oldal – tipikusan valamilyen megjeleníto vagy felhasználói eszköz – nem szerez tudomást. A megjegyzések nem ágyazhatóak egymásba! IV5. NAGYBETU ÉRZÉKENYSÉG Az XML nyelv egy nagybetuérzékeny nyelv, azaz a kis és nagybetuket különbözonek tekinti. Ez érvényes mind az elemek esetében, mind pedig a paraméterek értékei között is, azaz: • • • id=”Card1” id=”card1” id=”CARD1” minden esetben különbözoek IV6. A WML DOKUMENTUM FELÉPÍTÉSE Mivel egy WML dokumentum egy érvényes XML dokumentum, így meg kell adni egy érvényes dokumentum-formátumdefíníciót (DTD – Document Type Definition) a következoképpen: <?xml version="1.0"?> <!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN" "http://www.wapforumorg/DTD/wml 11xml"> Az elozo 3 sorral kell kezdodnie minden egyes WML dokumentumnak! Egy WML kártya egy wml elemmel kezdodik és ér véget.
Az összes többi elem ezek között helyezkednek el. <wml> minden más elem </wml> IV7. KÁRTYA ÉS LAPOK A következo táblázat azon elemeket tartalmazza, melyek segítségével egy lapot lehet definiálni egy kártyán belül: elem leírás Egy kártyát definiál, mely körbefog minden más információt és lapot. A megjeleníto eszköz számára jelez általános információkat és tartalmaz minden más olyan információt, melyet a felhasználó az eszközön keresztül lát és kezelni képes, azaz egy lap definiálására alkalmas. Egy sablont definiál, mely érvényes minden egyes lapra, mely a kártyán belül helyezkedik el. A kártya fejlécét definiálja. Az egész kártyához rendel hozzá információt. Tartalmazza a hozzáférés vezérlo elemet (access) és a meta elemet is. Hozzáférés ellenorzést specifikál egy kártyához. Általános meta információt kapcsol a kártyához. wml card template head access meta card elem A card elem (lap)
a kártyán belüli navigáció alapegysége, valamint a felhasználó számára megjelenítendo információkat tartalmazza. Lehetoség van arra, hogy navigáljunk egyik lapról a másikra egy kártyán belül, vagy átmenjünk egy másik kártyára. A következo táblázat leírja, hogy milyen paramétereket tartalmazhat az elem: - 13 - WAP alapú alkalmazás fejlesztése A WML nyelv paraméter leírás Megadja a lap azonosítóját, mely segítségével lehet hivatkozni rá. Az azonosítónak egyedinek kell lennie egy kártyán belül Megadja a lap fejlécében megjelenítendo információt Ha ez az attribútum true-ra van állítva, akkor a böngészo újrainicializálja a környezetét. A böngészo környezete alatt értünk minden olyan információt, mely a böngészohöz tartozik: változók, elozmények listája és minden más implementációfüggo információ, mely a böngészohöz tartozik Jelzi a böngészonek, hogy a lap tartalma valamilyen formában szervezve
van A href által megadott helyre megy akkor, amikor a felhasználó egy kártyában navigál a go taszkot használva A href által megadott helyre megy akkor, amikor a felhasználó egy kártyában navigál a prev taszkot használva A href által megadott helyre megy, miután a timer elemben megadott ido letelik Megadja azt a formális vagy természetes nyelvet, melyben a dokumentum írva lett Felvesz egy vagy több elemet egy osztályba. id=”kartya neve” title=”felirat” newcontext=”false” ordered=boolean onenterforward=”href” onenterbackward=”href” ontimer=”href” xml:lang class Az argumentumok között felsorolt class és id attribútum elofordulhat minden egyes elem esetében. Ezek a nyelv „mag” argumentumai. A card • • • • elem a következo elemeket tartalmazhatja: onevent (0 vagy több) timer (maximum 1) do (0 vagy több) p (0 vagy több) Segítségével lehet formázott szöveget megjeleníteni. template elem A template elem lehetové
teszi, hogy megadjunk benne olyan taszkokat, melyeket minden egyes lap esetében figyelembe vesz. Ez a taszk minden esetben el lesz indítva, hacsak a lapban nem definiálunk egy ugyanolyan taszkot. Ekkor a lapban levo taszk felülírja a template-ben levo taszkot Egy do elem hatásköre az a wml elem, melyben definiálva lett. Ha ezt az elemet egy kártya template elemében definiáljuk, akkor a hatásköre az egész kártya. Ha egy lapban definiáljuk, akkor csak arra az egyedüli lapra vonatkozik. A template-ben a következo elemek szerepelhetnek: • do • onevent • onenterforward • onenterbackward • ontimer access elem Abban az esetben, amikor megadunk egy URL-t, megszerezzük a jogot arra, hogy használjuk azokat a változókat, melyeket az használ. A WML lehetové teszi, hogy valamennyire levédjük az oldalt az access elem használatával. Az access elemet a kártya fejlécében használhatjuk. Az elem használatát a következo példán keresztül mutatom be: - 14 -
WAP alapú alkalmazás fejlesztése A WML nyelv <wml> <head> <access domain="domain" path="path"/> </head> <card id="card1"> <p> tartalom </p> </card> </wml> A példa a következo elemeket és attribútumokat tartalmazza: elem vagy paraméter leírás A fejléc kezdetét jelzi. A head elem tartalmazhat access és meta elemeket Az access elem kezdetét jelzi. Ez egy tartalom nélküli elem, melynek nincsen végjelzo része. Azt az útvonalat definiálja a két attribútum, melyeken levo kártyák elérhetik ezt a kártyát. <head> <access> domain=”domain” path=”útvonal” például: legyen a két attribútum értéke a következo: domain=”acmecorp.com” path=”/pub” Ebben az esetben a következo kártyák számára engedélyezett a hozzáférés erre a kártyára: acmecorp.com/pub/stockscgi www.acmecorpcom/pub/demos/packagescgi A következo kártyák viszont nem
férhetnek hozzá: www.testnet/pub www.acmecorpcom/internal/foowml Az alapértelmezett hozzáférés vezérlés engedélyezi a kártyához való hozzáférést ugyanarról a domain-rol. A következo táblázat azon elemeket tartalmazza, melyek segítségével navigálni lehet a kártyák között, valamint azt, hogy milyen hozzáférés engedélyezést kell tartalmaznia a cél kártyának: elem hozzáférés engedélyezés Nem kell A megadott href alatt levo kártya domain és path attribútuma meg kell hogy egyezzen a hivatkozó kártya URL-jével prev go href=”href” IV8. ESEMÉNYKEZELOK Néhány WML elem eseményt generál, amikor a felhasználó használja azokat. Ezek az események állapotváltozást idéznek elo a felhasználói eszközben. Például össze lehet rendelni egy taszkot és egy eseményt, azaz amikor a megadott esemény fellép, akkor a taszk elindul. Különbözo taszkokat lehet megadni. Taszkok segítségével lehet akár egy megadott URL-re ugrani DO elem
A DO elem segítségével valamilyen tevékenységhez, eseményhez lehet a felhasználói eszköztol függoen valamilyen grafikus gombot, vagy funkcióbillentyut hozzárendelni. A DO elem type attribútuma arról ad információt a felhasználói eszköznek, hogy a szerzo a megadott elemet milyen kategóriába sorolta, és annak megfeleloen az eszköz másképpen jeleníti azt meg, esetleg más billentyuhöz rendeli. - 15 - WAP alapú alkalmazás fejlesztése A WML nyelv Az elem megjelenhet egyaránt kártya szinten, illetve lap szinten: • lap szinten: A DO elem megjelenhet a card elemen belül és a szövegben bárhol elhelyezheto • kártya szinten: A DO elem megjelenhet a template elemen belül, jelezve hogy ez egy kártya szintu DO elem. A kártya szintu elem hatással van minden lapra mely az adott kártyán belül helyezkedik el. A következok érvényesek a lap illetve kártya szintu DO elemre: Egy lap szintu DO elem „felülírja” a kártya szintu DO elemet, ha
ugyanaz a neve. Egy kártya érvényes DO elemei a kártyában definiált elemek, és azok a kártya szintu elemek, melyek nem lettek felülírva. Az érvénytelen, és azok az érvényes DO elemek, melyek a noop taszkkal lettek felülírva a felhasználó számára nem jelennek meg. A DO elem a következo elemeket tartalmazhatja: • go • prev • noop • refresh paraméter leírás Megadja az elem típusát. Ez a paraméter kötelezo A felhasználói eszközök elfogadnak bármilyen típust, de azokat, melyek nem szerepelnek a következo listában unknown típusként kezelik: • accept : pozitív megerosítés • prev : az elozményeken navigál visszafele • help : segítségkérés • reset : törli vagy újra beállítja az eszköz állapotát • options: környezetfüggo hozzáférés a beállításokhoz vagy további muveletekhez • delete: elem törlése vagy kiválasztása • unknown: általános DO elem. Azonos az üres sztringgel (type=””) type=”kartya
tipusa” Megadja, hogy milyen feliratként jelenjen meg az elem az eszközön. Ha egy elemet nem lehet dinamikusan feliratozni, akkor ezt figyelmen kívül hagyja az eszköz. Lehetoleg a felirat hossza ne legyen több mint 6 karakter. A DO eseménykezelo nevét adja meg. Ha két DO elemnek ugyanaz a neve, akkor ugyanarra a kezelot jelentik. Hiba az, ha egy lapon vagy egy template-en belül ketto vagy több elemnek ugyanaz a neve. A ”” név ekvivalens azzal, mintha nem lett volna megadva. Ha nincsen megadva a paraméter, akkor az alapértelmezett érték a type paraméter értéke. Ha értéke true, akkor az eszköz figyelmen kívül hagyhatja az elemet. label=”felirat” name=”neve” optional=boolean ontimer esemény Ez az elem megadható a következo elemeken belül: • card • template Akkor aktivizálódik ez az esemény, amikor egy számláló lejár. - 16 - WAP alapú alkalmazás fejlesztése A WML nyelv paraméter leírás Megadja, hogy az eszköz a
számláló lejárta után mely oldalra menjen. ontimer=href onenterforward esemény Akkor aktivizálódik ez az esemény, amikor a felhasználó belép a kártyára, például egy GO taszk után. A következo elemeken belül szerepelhet: • card • template Az esemény paraméterei: paraméter leírás Megadja, hogy az eszköz mely oldalra menjen, ha a felhasználó belép a lapra. onenterforward=href Eseménykezeloket kétféle úton lehet megadni egy WML oldalon belül: 1. Ha egy megadott esemény bekövetkezésekor egy megadott oldalra akarunk navigálni, akkor a legegyszerubb módszer az, ha card elem paramétereként definiáljuk az eseménykezelot. Ezt mutatja a példa: <card onenterforward="http://wapserver/first.wml"> <p> Szevasz </p> </card> Ez a forma ekvivalens egy GO taszk végrehajtásával. Az esemény bekövetkezésének feltételébol nyilvánvaló, hogy a ”Szevasz” szöveg nem jelenik meg akkor, amikor elorefele erre az
oldalra navigálunk, hanem csak akkor, ha visszafele (az elozményekbol kiszedve) navigálunk. 2. Az elozo módszer kiterjesztett változata a második, mely segítségével definiálni lehet egy eseménykezelot. Ez az onevent elem Az elozo példa a következoképpen néz ki: <card> <onevent type="onenterforward"> <go href="http://wapserver/first.wml"> </onevent> <p> Szevasz </p> </card> onenterbackward esemény Ez az esemény akkor következik be, amikor a prev taszk segítségével történik az oldal elohívása, azaz az oldalt az elozményekbol szedi ki az eszköz. A következo elemeken belül szerepelhet: • card • template Az esemény paraméterei: paraméter leírás Megadja, hogy az eszköz mely oldalra menjen, ha az oldal az elozményekbol töltodik vissza a prev taszk segítségével. onenterbackward=href onpick esemény Az onpick esemény akkor következik be, amikor a felhasználó kiválaszt egy elemet.
Ez az esemény csak az option elemen belül szerepelhet. Az esemény paraméterei: - 17 - WAP alapú alkalmazás fejlesztése A WML nyelv paraméter leírás Megadja, hogy az eszköz mely oldalra menjen, ha a felhasználó megjelöli az elemet, vagy a jelölést visszavonja róla. onpick=href <card id="card 1"> <p> Melyik a kedvenced: <select name="allatok"> <option value="1" onpick="cat.wml"> Macska </option> <option value="2" onpick="dog.wml"> Kutya </option> </select> </p> </card> onevent elem Az onevent elem hozzárendel egy taszkot egy megadott eseményhez. A következo elemeket tartalmazhatja: • go • prev • noop • refresh paraméter type=”esemény típusa” leírás Az esemény típusát jelöli. Kötelezo ez a paraméter postfield elem A postfield elem segítségével lehet megadni, hogy egy URL kérés során a szerver felé milyen
paraméter/érték párok (mezok) kerüljenek átvitelre. Az elem nem tartalmazhat több elemet. A postfield elem paraméterei: paraméter name=”parameter neve” value=”parameter erteke” <go method="post" <postfield <postfield <postfield </go> leírás megadja az átküldendo mezo nevét megadja az átküldendo mezo értékét href="http://host/servlet/bank"> name="penz" value="100"/> name="egyenleg" value="12345"/> name="muvelet" value="letet"/> IV9. TASZKOK A WML lehetové teszi, hogy egy esemény bekövetkezésekor egy taszk kerüljön elindításra. A nyelv négy taszk elemet tartalmaz: • go • prev • noop • refresh GO taszk A GO elem egy GO taszkot definiál, mely segítségével egy megadott URL-re lehet navigálni. Ha a megadott URL egy WML lap vagy kártya, akkor azt betölti az eszköz. A GO taszk a megadott oldalt felveszi az elozmények listájába.
A következo elemeket tartalmazhatja (nem kötelezo): • setvar • postfield - 18 - WAP alapú alkalmazás fejlesztése A WML nyelv Az elem fontosabb paraméterei: paraméter leírás A megjelenítendo oldalt azonosítja. Kötelezo ez a paraméter Ha ennek a paraméternek az értéke true, akkor a megjelenítendo oldal lekérése tartalmazni fogja annak az oldalnak a címét, mely tartalmazta a taszkot. Alapértelmezett értéke false A HTTP átvitel módját tartalmazza. Alapértelmezett érték a get. Megadja, hogy a szerver milyen karakterkészletu információt fogad el. Az alapértelmezett érték: unknown. href=href sendreferer=boolean method=(post|get) accept-charset=”karakterkeszlet” Egy GO elem tartalmazhat egy vagy több postfield elemet. Ezek arra valóak, hogy a szerver felé paramétert továbbítsanak az oldal lekérése során. prev taszk A prev elem egy prev taszkot definiál, jelezve a felhasználói eszköznek, hogy az elozményekbol kell kiszednie a
legutolsó oldalt. Ha az elozmények között nincsen oldal, akkor a taszknak nincsen hatása A taszk egy vagy több setvar elemet tartalmazhat, de nem kötelezoen. A taszk paraméterként csak a mag attribútumokat tartalmazza (id,class). Példa: <do type="accept" label="Vissza"> <prev/> <do> refresh taszk A refresh taszk segítségével lehetoség van a lap változóinak frissítésére, beállítására. Tartalmazhat egy vagy több setvar elemet. példa: <refresh> <setvar name="adat" value="12"/> </refresh> vagy <refresh/> noop taszk Ez a taszk jelzi, hogy nem kell semmilyen feladatot végrehajtani az adott esemény bekövetkezésekor. Hasznos lehet akkor, amikor egy eseményt akarunk felüldefiniálni, azaz például egy kártya szintu eseménykezelot akarunk érvényteleníteni az adott lapon. <do type="accept" label="Tovabb"> <noop/> </do> Ha egy olyan
eseményre alkalmazzuk a lapon ezt a taszkot, mely már kártya szinten le van kezelve, akkor a kártya szintu hatását veszti, és az adott lapra érvényes aktív eseménykezelok körébol kikerül a megadott eseménykezelo. IV10. VÁLTOZÓK Változók használatának alkalmazásával lehetoség van a tartalom sokkal dinamikusabb változtatására azáltal, hogy a szövegkörnyezetbe beillesztjük a változót. A változó kiértékelése „futási idoben” történik, azaz a változó értéke a szövegbe futási idoben helyettesítodik be. Egy változó értéke be van állítva akkor, ha az nem üres szöveg. Nincsen beállítva akkor, ha üres szöveg, vagy ismeretlen, vagy az aktuális böngészo tartalomban nincsen definiálva. - 19 - WAP alapú alkalmazás fejlesztése A WML nyelv setvar elem A setvar elem lehetové teszi, hogy egy taszk elindítása során egy változónak értéket adjunk. Az értékadás az aktuális böngészo környezetben történik. Az elem
kihagyásra kerül abban az esetben, amikor a name paraméter értékét nem lehet megfeleltetni egy érvényes változóhivatkozásnak. paraméter name=”valtozo neve” value=”ertek” leírás A változót azonosítja Megadja a változó értékét Változóhivatkozás A változó neve US-ASCII betuvel vagy aláhúzással kezdodhet, melyet további betuk, számjegyek vagy aláhúzásjel követhet. Minden más karakter használata érvénytelen és hibát eredményez A változóhivatkozás megkülönbözteti a kis és nagy karaktereket. A hivatkozásnál zárójelek alkalmazása szükséges abban az esetben, amikor az aktuális szövegkörnyezetbol nem derül ki a változó nevének vége. A változóhivatkozás általános formája: • $nev • $(nev) • $(nev:konverzio) A változóhivatkozás minden esetben $ karakterrel kezdodik. Általános szabály, hogy minden olyan helyen, ahol változóhivatkozás szerepelhet a változóhivatkozásnak nagyobb prioritása van az
általános szövegnél, azaz ahol $ karakter szerepel az alapértelmezettként változóhivatkozás kezdetét jelzi. Ha azt akarjuk, hogy a $ karakter a szövegben megjelenjen, azt $$ formában lehet megtenni. Változó beállítása Többfajta lehetoség van a változó értékének beállítására. A setvar elem lehetové teszi, hogy egy változónak értéket adjunk egy navigáció során. Ez a setvar elem a következo többi elemen belül fordulhat elo: • go • prev • refresh A változók a beviteli elemek használatakor is értéket kapnak a következo szabályoknak megfeleloen: – az input elem a begépelt szöveget adja a változónak – a select elem a kiválasztott option elemnél megadott value paraméter értékét adja a változónak Az értékadás csak abban az esetben történik meg, amikor a felhasználó a begépelt szöveget megerosíti. A változók értékének megváltoztatására lehetoség van WMLScripten keresztül is. Megjegyzés: A card elemnél
megadott newcontext=true paraméterrel az aktuális böngészo környezetben levo változók törlodnek. Változó kiértékelése Változóhivatkozás elhelyezheto bárhova, ahol formázott szöveg elofordulhat. Elofordulhat továbbá az elemek value paraméterének értékeként, továbbá a href attribútumnál is. A változó kiértékelése egy szöveghelyettesíto muvelet, mely nincsen hatással a megadott változó értékére. Konverzió megadásával lehet befolyásolni a változó kiértékelésének módszerét. A következo táblázat ezt mutatja be: változó hivatkozás leírás A nev által megadott változó behelyettesítése. A behelyettesítés során a szöveg URL konverziónak megfelelo átalakítása megtörténik. A nem alfanumerikus karaktereket átalakítja az URL konverziónak megfeleloen. A nem alfanumerikus karaktereket visszaalakítja az URL konverzióból A nem alfanumerikus karaktereket nem alakítja át $nev vagy $(nev) $(nev:e) vagy $(nev:escape)
$(nev:unesc) $(nev:N) vagy $(nev:noesc) - 20 - WAP alapú alkalmazás fejlesztése A WML nyelv A következo táblázat bemutatja az egyes konverziók eredményét: érték szoveg123 szoveg? szoveg%3F $(var) szoveg123 szoveg? szoveg%3F $(var:e) szoveg123 szoveg%3F szoveg%253F $(var:unesc) szoveg123 szoveg? szoveg? $(var:noesc) szoveg123 szoveg? szoveg%3F A példa magyarázata: Az elso oszlop tartalmazza egy megadott változó értékét, a többi pedig az adott konverzió eredményét. A második oszlopban látható hogy nincsen változás az eredeti értékhez képest. A harmadik oszlop már a nem alfanumerikus karaktereket átalakítja ( ? à %3F a második sorban, valamint a % à %25 a harmadik sorban). A negyedik oszlopban ezzel szemben fordított visszaalakítás történik, azaz %3F à ? lesz a harmadik sorban, és a nem URL konverziós karaktereket ( pl. a „?”) nem alakítja át, továbbá az utolsó oszlopban semmilyen változás sincsen az eredeti értékhez
képest. Ez megegyezik a $(var) hivatkozással is. A táblázatot a következo példa alapján mutattam be: <?xml version="1.0"?> <!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN" "http://wwwwapforumorg/DTD/wml 11xml"> <wml> <card id="Pelda" title="Pelda"> <p> Valtozo: <input type="text" name="var"/> 1. $(var) <br/> 2. $(var:e) <br/> 3. $(var:unesc) <br/> 4. $(var:noesc) <br/> </p> </card> </wml> IV11. INTERAKTIVITÁS A következokben azt mutatom be, hogy a WML-ben hogyan lehet a felhasználótól információt kérni. Input elem Az input elem egy szöveges beviteli objektumot definiál. Lehetoség van a beviheto információ típusának megadására az opcionális format paraméter segítségével. Ha a felhasználó a bevitel során olyan szöveget gépel be, mely formátuma nem felel meg a ”format”-ban megadottnak, akkor az
eszköznek biztosítania kell azt, hogy csak olyan érték kerüljön elfogadásra, mely a formátumnak megfelelo alakú. Ezt oly módon teheti meg, hogy visszautasítja a szöveget, és a felhasználótól bekér egy újat. Továbbá az eszköz nem inicializálhatja olyan értékkel a mezot, melynek formátuma nem egyezik meg a mezo formátumával. Ekkor a mezo nem kap kezdoértéket. Az elem a következo paramétereket tartalmazhatja: paraméter leírás Megadja azt a változót, mely felveszi a begépelt szöveget értékül. Kötelezo a megadása Az alapértelmezett értéket adja meg. Abban az esetben, amikor az elem megjelenik és a name paraméterben megadott változó még nincsen beállítva, akkor ezt az értéket kapja meg. Ha már a változónak van értéke, akkor figyelmen kívül hagyja ezt a paramétert az eszköz. A beviteli mezo típusát adhatjuk meg a segítségével. A két típus között alapvetoen az a különbség, hogy text típus esetében a felhasználó
számára minden egyes begépelt karakter megjelenik, míg password name=”nev” value=”ertek” type=(text|password) - 21 - WAP alapú alkalmazás fejlesztése A WML nyelv esetében a karakterek helyén *-ok jelennek meg. Ezt tipikusan valamilyen titkos információ például jelszó megadása esetén lehet alkalmazni. A beviteli mezo „maszkját” lehet itt megadni. A maszk csak abban az esetben érvényes, ha a következo formázó karaktereket tartalmazza, ellenkezo esetben az eszköz a maszkot figyelmen kívül hagyja: A az adott helyen nagybetut vagy írásjeleket fogad el a az adott helyen kisbetut vagy írásjeleket fogad el N számot fogad el X tetszoleges nagybetus karakter elfogadása x tetszoleges kisbetus karakter elfogadása M tetszoleges karakter elfogadása, azonban a kisbetus karaktereket nagybetussé alakítja m tetszoleges karakter elfogadása, azonban a nagybetus karaktereket kisbetussé alakítja *f tetszoleges számú karakter elfogadása, ahol f a
fenti formátumok egyike. Ez csak a szöveg legvégén egyszer szerepelhet nf n darab azonos formátumú karakter elfogadása, f a fenti formátumok egyike (*f nem lehet) c a beviteli mezoben megjeleníti a c karaktert. Ha true-ra van állítva, akkor az eszköz elfogad üres szöveget is. Az alapértelmezett érték: false A beviteli mezo karakterekben megadott szélessége A mezoben maximálisan megadható karakterek száma. Alapértelmezettként tetszoleges hosszú szöveg viheto be A beviteli mezo feliratának megadása Az input elem sorszámának megadása. A nagyobb sorszám hátrébb van a sorrendben. format=”formatum” emptyok=boolean size=szam maxlength=szam title=”felirat” tabindex=szam select elem A select elem egy olyan beviteli objektumot definiál, ahol egy listából lehet kiválasztani a legmegfelelobbet. A lista minden egyes eleme egy option elem segítségével van megadva. Lehetoség van alcsoportok létrehozására is az optgroup segítségével. A
következo elemeket tartalmazhatja: • option • optgroup paraméter leírás A paraméter segítségével lehet megadni azt, hogy a egyszerre többet lehet kiválasztani a listán belül. Annak a változónak a nevét adja meg, mely eltárolja multiple=boolean name=”nev” - 22 - WAP alapú alkalmazás fejlesztése A WML nyelv a kiválasztott elem értékét. A name paraméterben megadott változó alapértelmezett értékét adja meg. Ha a többszörös kijelölés engedélyezve van, akkor az alapértelmezett értékeket pontosvesszovel kell elválasztani. Annak a változónak a nevét tartalmazza, mely értéke egy index. Azt mondja meg, hogy mi az alapértelmezett index a listában. Ha értéke 0, akkor nincsen kiválasztva semmi. Azt definiálja, hogy melyik indexu listaelem van alapértelmezettként kiválasztva. Ha többszörös kijelölés engedélyezve van, akkor pontosvesszot kell az indexek közé tenni: például 1;2. Az iname által megadott változó értéke
erre az értékre lesz beállítva. Értékét csak abban az esetben veszi figyelembe a nyelv, ha az iname által hivatkozott változó nem tartalmaz értéket. A select elem feliratát adja meg. A select elem sorszámát adja meg. value=ertek iname="nev" ivalue=ertek title="felirat" tabindex=szam option elem Az option elem egy lehetoséget definiál a select elemen belül. Csak a onevent eseménykezelo elemet tartalmazhatja. paraméter leírás A paraméter segítségével lehet megadni azt, hogy a select elem változója milyen értéket kapjon, amikor kiválasztódik ez az option elem. Az option elem feliratának megadása Eseménykezelo, mely az elem megjelölésekor, vagy a jelölés megszunésekor aktivizálódik value=”ertek” title=”felirat” onpick=href optgroup elem Az optgroup lehetové teszi, hogy összefogjunk több option elemet. A következo elemekbol legalább egy kell, hogy legyen benne: • optgroup (beágyazható) • option
paraméter leírás Az elemet reprezentáló objektum felirata title=”felirat” fieldset elem A fieldset elem lehetové teszi azt, hogy az egymással összekapcsolódó mezoket (input, select) és szöveget összefogjuk egy csoportba. Lehetoség van az egymásba ágyazásra is A következo elemeket tartalmazhatja: • input • select • fieldset • a • img • tab • br • em | strong | b | i | u | big | small paraméter leírás Az elem feliratának megadása title=”felirat” - 23 - WAP alapú alkalmazás fejlesztése IV12. A WML nyelv HIVATKOZÁSOK , KÉPEK ÉS IDOZÍTOK Anchor elem Ez az elem egy linket definiál. Nem ágyazhatóak egymásba Bárhol elhelyezheto, ahol formázott szöveg lehet, kivéve az option elemben. Egy anchor elemnél meg kell adni egyet, a következo taszkot közül: • go • prev • refresh Nem lehet egynél több taszkot megadni. A következo elemeket tartalmazhatja: • go | prev | refresh • br • img paraméter leírás Az
elem feliratának megadása. Lehetoleg kerüljük a 6 karakternél hosszabb feliratokat. title=”felirat” a elem Az a elem az anchor elem go taszkkal (paraméterek nélküli go taszkkal) vett formájának egy rövidített megfeleloje. Ezt mutatja a következo példa: <anchor>link <go href="link.wml"/> </anchor> Ennek a következo felel meg: <a href="link.wml">link</a> A következo elemeket tartalmazhatja: • br • img paraméter leírás Az elem feliratának megadása A megjelenítendo oldal title=”felirat” Href img elem Kép elhelyezését teszi lehetové a formázott szövegben. paraméter leírás Egy alternatív szöveges információ megadása a megjelenítendo képrol. Az eszköz akkor veszi figyelembe ezt, amikor képet nem tud megjeleníteni, vagy nem találja a képet. Kötelezo paraméter Hivatkozás a képre. A böngészo letölti a megadott hivatkozáson levo képet, és beilleszti a szövegbe. Kötelezo.
Alternatív forrás megadása. Ha meg van adva ez a paraméter, akkor az src paraméter helyett innen töltodik be a kép. Meg lehet adni, hogy a böngészo a kép mellett balra és jobbra (hspace), illetve felette valamint alatta (vspace) mekkora helyet hagyjon ki. Alapérték: 0 Százalékban kifejezve az érték nem a kép méretétol függ, hanem a rendelkezésre álló szabad helytol a kép mellett illetve fölött. A kép igazítása: alt=”felirat” src=href Localsrc=”alternativ hivatkozas” vspace=length hspace=length align=top | middle | bottom - 24 - WAP alapú alkalmazás fejlesztése A WML nyelv bottom middle a kép alját igazítja az aktuális sorhoz a kép középpontját igazítja az aktuális sorhoz top a kép tetejét igazítja az aktuális sorhoz. A kép mérete. Az eszköznek lehetosége van arra, hogy a megadott szélességure (width) és magasságúra (height) alakítsa át a kapott képet, ha az nem akkora. Százalékban kifejezett érték nem a
kép méretétol függ, hanem a rendelkezésre álló szabad helytol. height=length width=length timer elem Segítségével egy idozítot lehet definiálni. Az idozíto a lap aktiválódásakor indul el, és akkor áll le, amikor a lapból kilépünk. Lap aktiválását jelenti például az oldal beolvasása Lapról való kilépés alatt bármilyen taszk elindítását kell érteni. Az idozíto értéke folyamatosan csökken a megadott kezdoértéktol, majd egy ontimer eseménykezelo aktivizálódik, amikor az értéke 0 lesz. Nem lehet egy lapon definiálni egynél több timer elemet. Az értéket 1/10 másodpercben kell érteni A 0 érték kikapcsolja az idozítot paraméter Leírás Azt a változót adja meg, mely megkapja értékül az idozíto értékét, illetve ahonnan veszi annak értékét. Az érték átadása megtörténik az oldal kilépésekor. Ha az idozíto lejár, akkor a változó a 0 értéket kapja. Az idozíto kezdoértéke. Ha a name paraméter által
hivatkozott változó nincsen még inicializálva, akkor beállítódik a változó erre az értékre, ha viszont már van értéke, akkor a value paraméter figyelmen kívül hagyódik és a változó értékével inicializálódik az idozíto. name=”valtozo” value=”ertek” IV13. SZÖVEG FORMÁZÁSA Kiemelo elemek A kiemelo elemek a szöveget kiemelik valamilyen formában a szövegkörnyezetbol: Elem leírás Kiemelés Eros kiemelés Dolt betutípus Kövér betutípus Aláhúzás Nagy betutípussal történik a kiíratás Kis betutípussal történik a kiíratás Em Strong I B U Big Small br elem A br elem egy új sor kezdetét jelzi. Ha az eszköz egy ilyet talál a szövegben, akkor a következo sorban kell kezdenie a szöveg kiíratását. p elem A p elem segítségével egy szöveg szakasz igazítását és sortörési módját lehet beállítani. Ha a szövegigazítás nincsen megadva, akkor az alapértelmezett igazítás balra történik (left). Ha a sortörési
mód nincsen megadva, akkor az elozo szakasz sortörését veszi alapul. Ha egy lap elso szakasza nem tartalmaz sortörési beállítást, akkor a lap beállítását veszi alapul az eszköz. Minden egyes szakasz kezdete elé a megjelenített szövegbe az eszköz egy sortörést szúr be. A WML kétfajta sortörési módot ismer: Ha a mode=”wrap”, akkor a sortörés be van kapcsolva, mode=”nowrap” esetben pedig nincsen automatikus sortörés. Ekkor lehetséges, hogy vízszintesen is görgetni kell a lapot, hogy mindent meg tudjon nézni a felhasználó, ami a lapon van. - 25 - WAP alapú alkalmazás fejlesztése A WML nyelv Sortörési pontnak tekint a WML minden egyes üres helyet a szövegben. Fontos, hogy az egymás utáni üres helyeket, egymás utáni sortöréseket (a forrásban) a nyelv kicseréli egyetlen egy üres helyre. A szövegbe sortörés beszúrására a br elem használható. Ha azt akarjuk jelezni az eszköz számára, hogy az üres hely két szó
között nem törheto, azaz a két szónak egy sorban kell lennie, akkor azt az segítségével tudathatjuk vele. Egy szakasz a következo elemeket tartalmazhatja: • a • anchor • br • do • em | strong | b | i | u | big | small • fieldset • img • input • select • table paraméter A szakasz igazítása vízszintesen Sortörési mód align=(left | right | center) mode = (wrap | nowrap) leírás (balra, jobbra, középre) table elem A table elemet a tr és td elemmel együtt kell alkalmazni. Segítségükkel egy táblázatot lehet definiálni Táblázatok egymásba ágyazására a WML-ben nincsen lehetoség! A cellákban az igazítás az align paraméternek megfeleloen történik. Az align paraméter értéke egy karaktersorozat, mely C, L, R (center, left, right) karaktereket tartalmazhat. Minden egyes karakter a megfelelo sorszámú oszlop igazítását adja meg. A columns paraméter segítségével lehet megadni az oszlopok számát. Ha egy sor
oszlopainak a száma nem egyezik meg a megadott értékkel, akkor az utolsó oszlopot kiegészíti a megfelelo szélességure, ha viszont több oszlop van megadva egy sorban, akkor a hátsó oszlopokat összevonja egy oszlopba, és minden egyes régi oszlop közé egy szóközt helyez el. A table elem csak a tr elemet tartalmazhatja. paraméter leírás A táblázat felirata Az oszlopok igazításának megadása Az oszlopok száma. Kötelezo title=”felirat” align=”igazitas” columns=szam tr elem Segítségével a táblázatban egy sort lehet definiálni. Egy táblázat sora lehet üres is Az üres sorokat nem szedi ki az eszköz a többi közül. Csak a td elemet tartalmazhatja. td elem Egy cellát definiál egy soron belül. Egy sor (tr) celláit a benne levo td elemek alkotják A következo elemeket tartalmazhatja: • a • anchor • br • em | strong | b | i | u | big | small • img - 26 - WAP alapú alkalmazás fejlesztése A WMLScript nyelv V. A WMLSCR IPT NYE
LV A WMLScript nyelv az ECMAScript-en alapul, azonban a mobil adatátvitelnél alkalmazott kisebb sávszélesség és a gyengébb teljesítményu kliensoldal miatt több-kevesebb módosítást tartalmaz. A WMLScript használható a WML-el együtt, azonban egyedül is lehet vele alkalmazásokat készíteni. A fo különbség az ECMAScript és a WMLScript között az, hogy a WMLScript-nek van egy bájtkódja. Az ECMAScript sok része nem lett átültetve a WMLScriptbe azért, hogy minél kisebb legyen, könnyebb legyen bájtkóddá alakítani, és könnyen tanulható legyen. A WMLScript egy procedurális nyelv és tartalmaz néhány beépített függvényt és eljárást is. A nyelvet azért fejlesztették ki, hogy a WAP architektúrát kiegészítsék dinamikus tartalommal, mivel egy WML oldal statikus, azaz nem tudja magát módosítani. Egy WML oldal a következo tulajdonságokkal nem rendelkezik: q A bevitt felhasználói szöveg helyességének valamilyen ellenorzése q A mobil
eszköz különbözo lehetoségeinek kihasználására, például hozzáférni a telefonkönyvhöz, hívást kezdeményezni, hívást fogadni, üzenetet küldeni, hozzáférni a SIM kártyához stb. q Hibaüzeneteket, figyelmezteto üzeneteket generálni q Engedélyezni a hozzáférést az eszköz szoftveréhez, és konfigurálni a telefont miután az már ki lett adva A WMLScriptet a hátrányok kiküszöbölésére fejlesztették ki. V1. A NYELV LEXIKAI FELÉPÍTÉSE A WMLScript nyelv egy szöveg-érzékeny nyelv. Minden egyes kulcsszót, változó és függvény nevet az eredeti formájában kell használni, azaz a kis és nagybetuket különbözonek tekinti. A space, tabulátor, újsor stb. karaktereket, melyek a szavak között jelennek meg a nyelv figyelmen kívül hagyja kivéve akkor, amikor ezek egy sztringen belül fordulnak elo. A pontosvesszo A következo utasításokban használható pontosvesszo: v üres utasítás v kifejezés v változó utasítás v Break utasítás v
Continue utasítás v Return utasítás Megjegyzés A nyelvben lehetoség van kétfajta megjegyzés használatára. Az egyik a sor hátralevo részét tekinti megjegyzésnek, a másik pedig több sort ( blokkot ) tekint annak. ü sor megjegyzés: // ü blokk megjegyzés: /* és / között Szövegkonstansok Egész konstans Egy egész konstans háromféle módon fordulhat elo a szövegben: decimális, oktális és hexadecimális alakban. Egy decimális konstans számjegyei 09, oktális konstans számjegyei 0.7, hexadecimális konstans számjegyei 0F közül lehetnek Egy oktális konstans 0-val kezdodik, egy hexadecimális konstans pedig 0x-el. Lebegopontos konstans Egy lebegopontos következoképpen: konstans tartalmaz - 27 - egy decimális pontot és egy kitevot, a WAP alapú alkalmazás fejlesztése A WMLScript nyelv Lebegopontos :: Egeszkonstans . [DecimalisJegyek] [KitevoRész] . DecimalisJegyek [Kitevorész] Egeszkonstans Kitevorész Kitevoresz :: KitevoJelzo
ElojelesEgesz KitevoJelzo :: e E ElojelesEgesz :: DecimalisJegyek + DecimalisJegyek – DecimalisJegyek DecimalisJegyek :: DecimalisSzamjegy DecimalisJegyek DecimalisSzamjegy DecimalisSzamjegy :: 0 1 2 3 4 5 6 7 8 9 közül egy EgeszKonstans :: 0 nemNullaJegy DecimalisJegyek nemNullaJegy :: 1 2 3 4 5 6 7 8 9 közül egy Szöveg konstans Egy szövegkonstans dupla (”) vagy szimpla (’) idézojelek közé zárt 0 vagy több karakterbol álló karaktersorozat. Mivel néhány karakter nem jelenítheto meg közvetlenül a szövegkonstansban, ezért ezekre a WMLScript speciális karaktersorozatot biztosít. Ezeket a karakter után kell beírni ( ’ ” \ f stb. ) Logikai konstans Az „igaz” érték a WMLScriptben egy logikai konstanssal van reprezentálva. Két logikai konstans van: true és false . Invalid konstans A WMLScript tartalmaz egy un. invalid konstanst annak jelölésére, hogy az érték érvénytelen. Azonosítók Az azonosítók segítségével a változókra,
függvényekre és pragmákra lehet hivatkozni, illetve nevesíteni azokat. Az azonosítók nem kezdodhetnek számmal, de kezdodhetnek aláhúzással ( ), valamint egy azonosító nem lehet a WMLScript beépített ill. foglalt szava (pl while, for, if) V2. VÁLTOZÓK ÉS ADAT TÍPUSOK A változó egy adatértékhez rendelt név. Arra való, hogy a program adatait tároljuk és kezeljük velük A WMLScript nyelv ismeri a lokális változókat. Ezeket a függvényeken belül lehet deklarálni, illetve paraméterként átadni. Változók deklarálása A nyelvben a változó deklarálása kötelezo. A deklarálás a var kulcsszóval kezdodik, melyet a változó neve követ. Egy változót deklarálni kell, mielott arra hivatkozunk A - 28 - WAP alapú alkalmazás fejlesztése A WMLScript nyelv változónak a deklarálás során adhatunk kezdoértéket is. Azon változók, melyek nem kapnak kezdoértéket alapértelmezettként az üressztring (””) értéket kapják. például: var
var var var x; price; x,y; size = 3; Hatáskör és élettartam A változó hatásköre a függvény azon része, mely a változó deklarálása után van. A változónak egyedinek kell lennie egy függvényen belül. A blokkutasítások nem befolyásolják a hatáskört. Egy változó élettartama az az ido, ami a deklarálása és a függvény véget érése között telik el. Hivatkozás Egy változóra csak abban a függvényben lehet hivatkozni, melyben deklarálva lett. A hivatkozás a változó nevével történik. például: var a = 12; var b = 23; var c = a + b; Változók típusa A WMLScript egy gyengén típusos nyelv. A változók nem típusosak, de a következo alaptípusokat ismeri a nyelv: boolean (logikai), integer (egész), floating-point (lebegopontos) és string (szöveg). Ezeken kívül a nyelvben még van egy invalid adattípus, melyet arra használ, hogy más típusoktól megkülönböztesse az érvénytelen adatokat (ilyen típust kapunk például a nullával
való osztás esetén). A programozónak sincsen lehetosége saját típus definiálására. Bármely változó tetszoleges típusú adatot tartalmazhat A nyelv a különbözo típusok közti szükséges konverziót automatikusan elvégzi. Bal-érték Néhány muveleti jelnél fontos, hogy a bal oldalán egy változó legyen és ne literál. Ilyen például a += operátor. Típus azonosság A nyelv többfajta muveletet támogat a különbözo adattípusokra. Minden egyes muveletnél meg van határozva, hogy milyen típusú adatokat fogad el argumentumként. A szükséges konverziókat a nyelv automatikusan elvégzi. Szám értékek A nyelv kétfajta szám értéket támogat: egész érték és lebegopontos érték. A változók inicializálhatóak egész értékkel vagy lebegopontos értékkel, és van néhány muveleti jel, mely módosítja az értéküket futási idoben. Egész szám mérete Az egész számokat a nyelv 32 biten ábrázolja kettes komplemensben. Ez azt jelenti, hogy a
támogatott legkisebb és legnagyobb egész szám a következo: -2147483648 és 2147483647. A Lang könyvtár tartalmaz két függvényt, melyek visszaadják ezen értékeket: Lang.maxInt() Lang.minInt() Lebegopontos szám mérete A WMLScript a 32 bites egyszeres pontosságú lebegopontos számokat támogatja. maximum érték: 3.40282347E+38 legkisebb pozitív nem nulla érték: 1.17549433E-38 A Float könyvtár is tartalmaz két függvényt ezen értékek lekérdezésére: Float.maxFloat() Float.minFloat() - 29 - WAP alapú alkalmazás fejlesztése A WMLScript nyelv Lebegopontos számokkal való muveletek esetében a következo szabályok érvényesek: • Ha egy lebegopontos számon végrehajtott muvelet eredménye nem esik bele az egyszeres pontosságú lebegopontos formátum keretei közé, akkor az eredmény invalid típusú lesz • Ha az eredmény alulcsordul, akkor 0.0 lesz az eredmény • A pozitív és a negatív nulla egyenlo és megkülönböztethetetlen Szöveg
érték A WMLScript támogatja a szöveg típusú adatokat, mely tartalmazhat betuket, számok, speciális karaktereket stb. A változók inicializálhatók szöveg literállal és a szöveg értékek módosíthatóak néhány operátor valamint a beépített String könyvtár függvényei segítségével. Logikai érték Logikai értéket kaphat egy változó, valamint a logikai kifejezések értéke is logikai értéku. V3. MUVELETEK ÉS KIFEJEZÉSEK Értékadás utasítás A nyelv többféle módon támogatja, hogy egy változónak értéket adjunk. A legegyszerubb az egyenloségjel (=) alkalmazása, de lehetoség van még értékadásra muveletvégzéssel együtt is: muvelei jel = muvelet értékadás növelés(szám)/ összefuzés(szöveg) és értékadás kivonás és értékadás szorzás és értékadás osztás és értékadás egész osztás és értékadás maradék képzés és értékadás bitenkénti balra tolás és értékadás bitenkénti jobbra tolás és
értékadás bitenkénti jobbra tolás 0-val való kiegészítés és értékadás bitenkénti é s és értékadás bitenkénti kizáró vagy és értékadás bitenkénti vagy és értékadás += -= *= /= div= %= <<= >>= >>>= &= ^= |= - 30 - WAP alapú alkalmazás fejlesztése A WMLScript nyelv Aritmetikai muveleti jelek Alapveto kétváltozós muveletek: muveleti jel + * / div muvelet összeadás/összefuzés kivonás szorzás osztás egész osztás muveleti jel % << muvelet maradékképzés balra tolás elojeles bitenkénti jobbra tolás bitenkénti jobbra tolás 0-val kiegészítve bitenkénti és bitenkénti vagy bitenkénti kizáróvagy Összetett muveletek: >> >>> & | ^ Egyváltozós muveletek: muveleti jel + -++ ~ muvelet összeadás kivonás elo vagy utó csökkentés elo vagy utó növelés bitenkénti tagadás muveleti jel && || ! muvelet logikai és logikai vagy logikai tagadás Logikai muveletek A
logikai muveletek kiértékelése: A logikai ÉS kiértékeli az elso operandust és teszteli az eredményt. Ha az eredmény false (hamis) akkor a logikai muvelet eredménye hamis lesz és a második operandus nem lesz kiértékelve. Ha az elso operandus értéke true (igaz) akkor az eredmény a második operandus értékétol függ. Ha az elso operandus kiértékelés után invalid értéku lesz, akkor második operandus nem lesz kiértékelve és az eredmény invalid lesz. Hasonlóan a logikai VAGY is az elso operandust kiértékeli és teszteli az eredményt. Ha az eredmény true (igaz) akkor a muvelet eredménye igaz lesz és a második operandus nem lesz kiértékelve. Ha az elso operandus értéke false (hamis), akkor a muvelet eredménye a második operandus értékétol függ. Ha az elso operandus invalid értéku, akkor az eredmény invalid lesz, és a második operandus nem lesz kiértékelve. A WMLScript-nél fontos hogy a logikai muveletek mindkét operandusa logikai
típusú legyen. Automatikus konverzióra lehetoség van a többi típus és a logikai típusok között oda-vissza. - 31 - WAP alapú alkalmazás fejlesztése A WMLScript nyelv Szöveg muveletek A WMLScript lehetoséget biztosít a szövegek összefuzésére. A + és += muveletek használhatók a szövegek összefuzésére. Továbbá használhatók még a String beépített könyvtárban levo beépített függvények is a szövegek módosítására. Hasonlító muveletek A következo összehasonlító muveleteket ismeri a nyelv: muveleti jel < <= == >= > != muvelet kisebb kisebb egyenlo egyenlo nagyobb egyenlo nagyobb nem egyenlo Összehasonlítás esetén a következo szabályok érvényesek: • logikai típusnál a true (igaz) nagyobb, mint a false (hamis) • egész típusnál az összehasonlítás a kapott egész értékeken alapul • lebegopontos számoknál az összehasonlítás a kapott lebegopontos értékeken alapul • szöveg típusnál az
összehasonlítás a szöveg karaktereinek kódja alapján történik. • invalid típusnál, ha az egyik operandus invalid, akkor az összehasonlítás eredménye invalid lesz. Tömb muveletek A WMLScript nyelv nem támogatja a tömb muveleteket, azonban a beépített String könyvtárban létezik egy ehhez hasonlítható függvény. Ebben az esetben a függvény paraméterként kap egy szöveget, egy indexet és egy elválasztó jelet, az eredmény pedig úgy alakul ki, hogy az elválasztójelet alapul véve az adott indexu karaktersorozatot adja vissza a kapott szövegbol. A következo példa ezt illusztrálja: function tomb pelda() { var str = "Ez egy szöveg amit tömbként kezelünk"; var word = String.elementAt(str,5," "); // Az eredmény az 5 szó ("tömbként") lesz!!! } A vesszo muveleti jel A nyelv támogatja a vesszo operátort, mely lehetové teszi, hogy egyszerre több kiértékelést helyezzünk el egyetlen egy utasításba. Ezen operátor
eredménye a második operandus eredménye. A vesszot azonban használja a nyelv a függvények paramétereinek elválasztására, valamint többszörös értékadásnál is. Így abban az esetben, amikor a vesszot, mint muveleti jelet akarjuk használni egy függvény paraméterei között, akkor azt zárójelek közé kell tenni. Ezt mutatja be a következo példa: var a=2; var b=3, c=(a,3); fuggvenyhivas("Nev",3*(ba,c)); // a függvény két paramétere: "Nev" és 9 Feltételes operátor A nyelv támogatja a feltételes (?:) operátort is, melynek 3 operandusa van. A muveleti jel az elso operandus logikai kiértékelésének eredményétol függoen adja vissza vagy a második vagy a harmadik operandus értékét. Ha az elso operandus értéke true (igaz) akkor az eredmény a második operandus lesz. Ha az elso operandus értéke false (hamis) vagy invalid akkor az eredmény a harmadik operandus lesz. typeof operátor Habár a WMLScript egy gyengén típusos
nyelv, mint már korábban errol szó volt, a következo beépített típusokat ismeri: boolean, integer, floating-point, string és invalid. A typeof operátor - 32 - WAP alapú alkalmazás fejlesztése A WMLScript nyelv visszaadja a paraméterül kapott kifejezés típusát egy egész számként a következo táblázat alapján: típus integer floating-point string boolean invalid érték 0 1 2 3 4 A typeof operátor nem próbál meg konvertálni egyik típusról a másikra, de a paraméterül kapott kifejezést kiértékeli, és annak típusát adja vissza. isvalid operátor Az isvalid operátor arra használható, hogy ellenorizzünk vele egy kifejezés típusának helyességét. Az operátor true (igaz) értéket ad vissza minden olyan esetben, amikor a kifejezés nem invalid, ellenkezo esetben false (hamis) értékkel tér vissza. Kifejezések A nyelv támogatja a más nyelvek által támogatott legtöbb kifejezéseket. A legegyszerubb kifejezés a konstans és a
változó, mely értéke a konstans illetve a változó értékének felel meg. Bonyolultabb kifejezések kaphatóak muveleti jelek, függvények használatával. Muveleti jelek A következo táblázat bemutatja a WMLScript által támogatott muveleti jeleket. A táblázat információt tartalmaz a muveleti jel precedenciájáról (a kiértékelés sorrendjérol), és a muveleti jel kötésérol (L: balról jobbra; R: jobbról balra) precedencia 1 1 1 1 1 1 1 1 2 2 2 2 3 3 4 4 4 5 5 6 6 7 8 9 10 11 12 13 13 13 kötés R R R R R R R R L L L L L L L L L L L L L L L L L L R R R R muveleti jel ++ -+ ~ ! typeof isvalid * / div % + << >> >>> <, <= >, >= == != & ^ | && || ?: = *=, -= /= - 33 - operandus típusa szám szám szám szám egész logikai bármi bármi szám szám egész egész szám szám v. szöveg szám szám szám szám v. szöveg szám v. szöveg szám v. szöveg szám v. szöveg egész egész egész logikai logikai logikai, bmi,
bmi változó, bmi változó, szám változó, szám eredmény típusa szám szám szám szám egész logikai egész logikai szám lebegopontos egész egész szám szám v. szöveg szám szám szám logikai logikai logikai logikai egész egész egész logikai logikai bmi bmi szám lebegopontos WAP alapú alkalmazás fejlesztése A WMLScript nyelv 13 13 R R %=, div= += 13 R 14 L <<=, >>=, >>>=, &=, ^=, |= , változó, egész változó, szám v. szöveg változó, egész egész szám v. szöveg bmi bmi egész V4. FÜGGVÉNYEK Függvények deklarálása Függvény deklarációja alatt azt értjük, amikor megadjuk a függvény nevét, paraméterlistáját és egy blokkutasítást, mely leírja, hogy a függvénynek mit kell tennie. Minden egyes függvény a következo tulajdonsággal rendelkezik: • • • • • • függvények nem ágyazhatóak egymásba fordítási egységen belül a függvények nevének egyedinek kell lennie a
függvények paramétereiket érték szerint kapják meg függvények meghívása pontosan ugyanannyi argumentummal kell, hogy történjen, mint amennyi argumentummal a függvény deklarálva lett a függvények paraméterei lokális változóként viselkednek, és a függvény teste (a blokk kezdete) elott inicializálva vannak a függvény mindig ad vissza értéket. Alapesetben üres szöveget (””), azonban a return utasítással megadható más visszatérési érték is A függvény a WMLScriptben nem egy adattípus, de a nyelv szintaktikai jellemzoje. Egy függvényt a következoképpen lehet deklarálni: FüggvényDeklaráció: [extern] function azonosító ([formális paraméterlista]) [Blokk;] formális paraméterlista: azonosító formális paraméterlista, azonosító Paraméterek: Az opcionális extern argumentum arra való, hogy jelezzük, hogy az adott függvény más fordítási egységbol is elérheto legyen, ne csak onnan, ahol azt deklaráltuk. Az azonosító a
függvény nevét adja meg. Az opcionális formális paraméterlista egy vesszovel elválasztott névlista. A Blokk a függvény „testét” tartalmazza, mely a függvény meghívásakor kerül elindításra és a paraméterek az átadott argumentumoknak megfelelo értékekkel lesznek inicializálva. példák: function penzvaltas(valuta, arany) { return valuta*arany; }; extern function atvalt () { var UDS = 10; var FIM = penzvaltas(USD,5.3); }; Függvények hívása A függvények meghívása attól függ, hogy a hívandó függvény hol van deklarálva. Ennek megfeleloen 3 fajta függvényhívási mód létezik: • lokális függvényhívás • külso függvényhívás • beépített függvény meghívása - 34 - WAP alapú alkalmazás fejlesztése A WMLScript nyelv Lokális függvényhívás A lokális függvényhívás használható abban az esetben, amikor a hívandó függvény ugyanabban a fordítási egységben helyezkedik el, mint ahonnan azt meghívjuk. Ebben az
esetben a hivatkozás a függvény nevével, és zárójelben a függvénynek átadni kívánt argumentumainak felsorolásával történik. Fontos, hogy a függvényt ugyanannyi argumentummal hívjuk meg, mint amennyivel azt deklaráltuk. Egy fordítási egységen belül a függvényekre hivatkozhatunk azelott mielott azt már deklaráltuk. Külso függvényhívás Külso függvényhívást abban az esetben kell használni, amikor a hívandó függvény más fordítási egységben helyezkedik el, mint amibol rá hivatkozunk. Azonban a függvényhívás csak akkor érvényes, ha a hívandó függvényt extern elotaggal deklaráltuk. A use url pragma segítségével definiálhatunk egy külso fordítási egységet, jelezve azt, hogy abból szeretnénk más függvényeket elérni. Ez megfeleltet egy nevet a külso fordítási egységnek mellyel hivatkozhatunk rá a függvényben. Ezt a nevet és a # szimbólumot kell a függvényhívás elotagjaként szerepeltetni. például: use url
MasScript "http://www.szerverhu/szkript"; function test(param) { return MasScript#test2(param+1); }; Beépített függvény meghívása Ezt a hívási módot kell alkalmazni abban az esetben, amikor olyan függvényre hivatkozunk, mely a WMLScript beépített könyvtáraiban szerepel. A függvényhívásnál a függvény nevét meg kell, hogy elozze a könyvtár neve és egy pont (.) szimbólum például: function test4(param) { return Float.sqrt(Langabs(param)+1); }; Alapértelmezett visszatérési érték A függvény alapértelmezett visszatérési értéke az üres szöveg (””). Más függvény visszatérési értékét nem veszi figyelembe ( pl. függvény hívás, mint kifejezés esetében ) például: function test() { test1(4); }; V5. UTASÍTÁSOK A WMLScript utasítások kifejezésekbol és kulcsszavakból állnak, az alkalmas szintaxisnak megfeleloen. Egy egyszeru utasítás több sorból is állhat, valamint több utasítás is lehet egy sorban. Üres
utasítás Üres utasítás az egy olyan utasítás, mely bárhol elofordulhat, ahol egy utasítás lehet, azonban semmilyen muveletet nem ír elo. alakja: ; például: while (!poll(device)) ; Kifejezés utasítás Kifejezés utasítások azok, melyekben egy változónak értéket adunk, matematikai muveleteket végzünk, függvényt hívunk meg, stb.: - 35 - WAP alapú alkalmazás fejlesztése A WMLScript nyelv alakja: kifejezés ; példa: str = "Szevasz " + Nev; val3 = elozoErtek + 4; szamlalo++; value3 = szamlalo, value4 = val3; alert("Nocsak!!"); retVal = 16*Lang.max(val3,szamlalo); Blokkutasítás A blokkutasítás nem más, mint több utasítás kapcsos zárójelek közé zárva. Bárhol használható blokkutasítás, ahol egy egyszeru utasítás használható. alakja: { [utasitaslista] } A blokk utasításhoz nem tartozik hozzá a bezáró zárójel utáni pontosvesszo! például: { var i= 0; var x=Lang.abs(b); popUp("Uzenet"); } Változó
utasítás Ez az utasítás deklarálja a változókat, és kezdoértéket ad nekik. A kezdoérték megadása nem kötelezo. Annak elhagyása esetén a változó az alapértelmezett kezdo értéket (üres szöveg) veszi fel. var valtozodeklaraciolista ; valtozodeklaraciolista : valtozodeklaracio valtozodeklaraciolista , valtozodeklaracio valtozodeklaracio: azonosito [inicializalas] inicializalas: = feltételeskifejezés paraméterek: az azonosító a változó nevét adja meg. Az azonosító csak érvényes karaktereket tartalmazhat. A feltételeskifejezés a változó kezdoértéke, mely csak érvényes kifejezés lehet. Ez a kifejezés minden esetben ki lesz értékelve, amikor a változó utasítás végrehajtódik. A változó azonosítójának a megfelelo függvényen belül egyedinek kell lennie. Feltételes utasítás (If) Ez az utasítás arra való, hogy egy megadott feltételtol függoen hajtsunk végre további utasításokat. Az utasítás egy feltételbol és egy vagy
ketto utasításrészbol áll Az elso utasítás akkor hajtódik végre, amikor a feltétel igaz. Ha a feltétel hamis, akkor a második utasítás – mely nem kötelezo – hajtódik végre. if ( feltétel ) utasitas else utasitas if ( feltetel ) utasitas paraméterek: a feltétel tetszoleges WMLScript kifejezés lehet. Ha a kiértékelt kifejezés igaz, akkor az elso utasítás hajtódik végre. Ha a kifejezés értéke hamis, vagy invalid, akkor a második utasítás hajtódik végre. Az utasítás lehet tetszoleges WMLScript utasítás, beleértve más feltételes utasítást is. Az else mindig a legközelebbi if-hez tartozik - 36 - WAP alapú alkalmazás fejlesztése A WMLScript nyelv While utasítás Ez az utasítás ciklusok szervezésére való. A ciklus végrehajtása egy kifejezés értékétol függ. Ha a kifejezés értéke igaz, akkor végrehajtódik az utasítás A ciklus mindaddig ismétlodik, amíg a feltétel igaz. while ( kifejezés ) utasitas paraméterek: a
kifejezés (feltétel ) tetszoleges WMLScript kifejezés lehet. A ciklusmag végrehajtása elott a feltétel minden esetben ki lesz értékelve. Ha az értéke igaz, akkor végrehajtódik az utasítás. Ha a feltétel hamis, vagy invalid, akkor a ciklust követo utasításra megy a végrehajtás. Az utasítás annyiszor lesz végrehajtva, ameddig a feltétel értéke igaz. For utasítás Szintén ciklusszervezo utasítás. Az utasítás 3 opcionális paraméterbol áll, melyeket pontosvesszovel kell elválasztani. for ([kif1]; [kif2]; [kif3] ) utasitas for (var valtozodeklaraziolista ; [kif2]; [kif3] ) utasitas paraméterek: Az elso kifejezést, vagy a var utasítást tipikusan kezdoérték megadásának használják. Az itt definiált változó hatásköre a függvény hátralevo része A második kifejezés (feltétel) bármilyen WMLScript kifejezés lehet, mely ki lesz értékelve. A feltétel minden egyes alkalommal ki lesz értékelve. Ha ez a feltétel igaz, akkor végrehajtódik
az utasítás. Ez a kifejezés opcionális Ha nincsen megadva, akkor alapértelmezettként mindig igaz lesz. A harmadik kifejezés (növelo kifejezés) általában arra való, hogy növelje a számláló változót. Az utasítás egészen addig hajtódik végre, amíg a második feltétel igaz Break utasítás Ez az utasítás használható a while vagy for utasítás megszakítására. Ezt követoen a következo utasítás a ciklust követo utasítás lesz. Hiba van akkor, amikor a break utasítást cikluson (while vagy for) kívül használjuk. break ; Continue utasítás Ez az utasítás használható while vagy for ciklus utasításának megszakítására, és a ciklus végrehajtásának folytatására. Az utasítás nem szakítja meg a ciklust • while ciklus esetében a feltételhez ugrik vissza • for ciklus esetében a harmadik kifejezéshez ugrik vissza Hiba van akkor, amikor a continue utasítást cikluson kívül használjuk. continue ; Return utasítás Ez az utasítás
használható függvény belsejében. Megadja a függvény visszatérési értékét Ha nincsen visszatérési érték definiálva, akkor üres szöveggel tér vissza a függvény. return [kifejezes] ; - 37 - WAP alapú alkalmazás fejlesztése A WMLScript nyelv V6. KÖNYVTÁRAK A WMLScript támogatja könyvtárak használatát. A könyvtárak logikailag összetartozó függvények gyujteménye. Ezeket a függvényeket a következoképpen hívhatjuk meg: könyvtár neve.függvény neve([parameterlista]) például: var i = String.elementAt(str,3," "); V7. PRAGMÁK A WMLScript támogatja a pragmák használatát, melyek a fordítási egység számára tartalmaznak információt. A pragmákat a fordítási egységben a függvény deklarációkat megelozoen kell definiálni. Minden pragma a use kulcsszóval kezdodik, és a pragmának megfelelo argumentumokkal folytatódik. szintaxis: fordításiegység: [pragmák] függvénydeklarációk pragmák: pragma pragmák pragma
pragma: use pragmedeklaráció pragmadeklaráció: külsofordításiegység pragma accesscontrol pragma meta pragma Külso fordítási egység WMLScript fordítási egységek elérhetoek URL megadásával is. Azaz minden WMLScript függvény elérheto az ot tartalmazó forrás URL-jének és a függvény nevének megadásával. Egy use url pragmát kell használni, amikor külso fordítási egységre hivatkozunk. szintaxis: külsofordításiegység pragma: url azonosító szövegliterál A use url pragma a külso fordítási egység helyét adja meg egy URL segítségével., és a megadott URL-nek egy nevet ad, melyet az azonosítóval adunk meg. Ezt a nevet kell használni, amikor egy külso fordítási egységben levo függvényre hivatkozunk. példa: use url szkript "http://www.hostcom/app/script"; function test(par1, par2 ) { return szkript#check(par1-par2); }; A use url pragmának saját egyedi neve van, ezáltal a megfelelo fordítási egységen belül egyedinek
névvel kell rendelkeznie! Access Control (Hozzáférés ellenorzés) A WMLScript fordítási egység tartalma levédheto az Access Control pragma használatával. A hozzáférés ellenorzés végre van hajtva a külso függvények hívása elott. Egy fordítási egység csak egy access control pragmát tartalmazhat. - 38 - WAP alapú alkalmazás fejlesztése A WMLScript nyelv szintaxis: AccessControl pragma: access hozzáférésmód hozzáférésmód: domain szöveg path szöveg domain szöveg path szöveg Minden egyes alkalommal a külso függvény egy hozzáférés ellenorzést hajt végre, és megvizsgálja, hogy a hívó fél számára engedélyezve van-e a hozzáférés. Ha a fordítási egységnek megvan adva a domain vagy path attribútuma, akkor a hívó fordítási egység URL-je meg kell hogy egyezzen azzal. Az egyezés a következot jelenti: access domain esetében utótag ellenorzés van a hivatkozó fordítási egység URL-jében szereplo domain-el, access path
esetében pedig elotag ellenorzés van a hivatkozó fordítási egység URL-jében szereplo útvonallal. A domain esetében az utótag ellenorzés a következot jelenti: a név ellenorzés minden egyes al-domain esetében a teljes névazonosságot vizsgálja, és minden egyes résznek pontosan meg kell egyeznie (például: www.wapforumorg azonos a wapforumorg-al, de nem azonos a forum.org-al ) Az ellenorzés itt hátulról elorefele haladva történik A path esetében az elotag ellenorzés a következot jelenti: az egyezésnek minden egyes rész útvonal esetében meg kell lennie, pontosan meg kell, hogy egyezzenek (például /X/Y megegyezik a /X-el, de nem egyezik meg a /XZ-vel). Az alapértelmezett domain az aktuális fordítási egység domain-je, az alapértelmezett path, pedig ”/”. példa: egy fordítási egység a következo pragmát tartalmazza: use access domain "wapforum.org" path "/finnance"; A következo URL-ek alatt levo fordítási egységek
érhetik el ennek a fordítási egységnek a függvényeit: http://wapforum.org/finance/moneycgi https://www.wapforumorg/finance/marketscgi http://www.wapforumorg/finance/demos/packagescgi?x=123&y=456 A következo URL-ekrol nem engedélyezett a hozzáférés: http://www.testnet/finance http://www.wapforumorg/internal/foowml Alapértelmezettként a hozzáférés ellenorzés nincsen megadva. - 39 - WAP alapú alkalmazás fejlesztése A WMLScript nyelv Meta információk A pragmák használhatók arra, hogy megadjunk a fordítási egységnek meta információkat. A meta információk egy tulajdonság névbol és egy értékbol állnak. szintaxis: Meta pragma: meta metaspecifikálás metaspecifikálás: metanév metaHttpEquiv metaUserAgent metanév: name MetaBody metaHttpEquiv: http equiv MetaBody metaUserAgent: user agent MetaBody MetaBody: paraméternév metatartalom [metaséma] A meta pragmáknak 3 attribútumuk van: paraméternév, tartalom (a paraméter értéke) és egy
opcionális metaséma. Az attribútum értékek szöveg literálok Name use meta name ”Created” ”18-March-1998”; HTTP Equiv use meta http equiv ”Keywords” ”Script,Language”; User Agent use meta user agent ”Type” ”Test”; V8. AUTOMATIKUS TÍPUSKONVERZIÓS SZABÁLYOK Néhány esetben a WMLScript operátorok eloírják, hogy milyen argumentumokra van szükségük. A nyelv támogatja az automatikus típuskonverziót a típusok között. Általános konverziós szabályok A WMLScript egy gyengén típusos nyelv és a változó deklarációk nem írják elo a változók típusait, azonban a nyelv a következo típusokat kezeli: • Logikai (boolean) : értéke true vagy false lehet • Egész (integer): értéke egy egész szám • Lebegopontos (floating-point) : értéke egy lebegopontos szám • Szöveg (string) : karaktersorozatot reprezentál • Hibás (invalid) : értéke csak invalid lehet, a hibás adatot jelzi. Ilyen például a nullával való osztás
eredménye. Egy változó bármely pillanatban a típusok értékei közül tartalmazhat egyet. A nyelvben van egy typeof operátort, mely segítségével le lehet kérdezni egy kifejezés vagy egy változó értékének a típusát. Minden egyes operátor a számára elore megadott típusú operandusokat fogadja el. Ha nem a megfelelo típusú adatokat kapja, akkor lép érvényre az automatikus típuskonverzió. Automatikus típuskonverzió A következo táblázat bemutatja az egyes típusok közötti automatikus típuskonverziót. - 40 - WAP alapú alkalmazás fejlesztése Honnan Hova logikai igaz logikai hamis egész 0 bármely más egész A WMLScript nyelv logikai false egész 1 true - lebegopontos 1.0 0.0 0.0 a szám lebegopontos alakja - lebegopontos 0 false hibás - true hibás - false hibás egész értéke a szövegnek , vagy hibás hibás hibás bármely más lebegopontos üres szöveg nem üres szöveg true invalid hibás szöveg ”true”
”false” az egész szám szöveg alakja implementáció függo reprezentációja , például: ”0.0” implementáció függo reprezentációja a lebegopontos számnak - lebegopontos értéke a szövegnek, vagy hibás - hibás hibás V9. WMLS CRIPT KÖNYVTÁRAK A következoben néhány fontosabb WMLScript könyvtárban levo függvényeket ismertetek. Lang könyvtár Olyan függvényeket tartalmaz, melyek közel állnak a WMLScript nyelv "magjához". • • abs(ertek) A megadott szám abszolút értékével tér vissza. Ha a szám egész, akkor egész, ha lebegopontos, akkor lebegopontos számot ad vissza. min(ertek1,ertek2) A megadott két érték közül a kisebbel tér vissza. Ha a két érték egyenlo, akkor az elsot adja vissza például: var var var var var • max(ertek1,ertek2) A megadott két érték közül a nagyobbikkal tér vissza. Ha a két érték egyenlo, akkor az elsovel tér vissza. példák: var var var var var • a=-3; b=Lang.abs(a);
c=Lang.min(a,b); // c=-3 d=Lang.min(45, 763); // d=45 (egész) e=Lang.min(45, 450); // e=45 (egész) a=-3; b=Lang.abs(a); c=Lang.max(a,b); // c=3 d=Lang.max(455, 76); // d=76 (egész) e=Lang.max(450, 45); // e=450 (lebegopontos) parseInt(ertek) A megadott sztring érték egész számmá konvertált alakját adja vissza. példák: var i=Lang.parseInt("1234"); // i=1234 var j=Lang.parseInt("100 m/s"); // j=100 • parseFloat(ertek) A megadott sztring érték lebegopontos alakját adja vissza. példák: var a=Lang.parseFloat("1237"); // a=1237 - 41 - WAP alapú alkalmazás fejlesztése var var var var var var var • • • • • • • • a=Lang.isInt("-123"); // true b=Lang.isInt("12333); // true c=Lang.isInt("string"); // false d=Lang.isInt("#123"); // false e=Lang.isInt(invalid); // invalid isFloat(ertek) True értékkel tér vissza abban az esetben, ha a ParseFloat() függvény segítségével
lebegopontos számmá konvertálható a megadott érték, ellenkezo esetben false értékkel. Ha a rendszer nem támogatja a lebegopontos muveleteket, akkor invalid értékkel tér vissza. példák: var var var var var • b=Lang.parseFloat("+734e2 Hz"); // b=734e2 c=Lang.parseFloat("70e-2 F"); // c=700e-2 d=Lang.parseFloat("-1 C"); // d=-01 e=Lang.parseFloat(" 100 "); // e=1000 f=Lang.parseFloat("Number:55"); // f=invalid g=Lang.parseFloat("73e meters); // g=invalid h=Lang.parseFloat("73e- m/s); // h=invalid isInt(ertek) True értékkel tér vissza abban az esetben, ha a ParseInt() függvény segítségével egész számmá konvertálható a megadott érték, ellenkezo esetben false értékkel. példák: var var var var var • A WMLScript nyelv a=Lang.isFloat("-123"); // true b=Lang.isFloat("12333"); // true c=Lang.isFloat("string"); // false d=Lang.isFloat("#12333");// false
e=Lang.isFloat(invalid); // invalid maxInt() A legnagyobb egész számot adja vissza, mely: 2147483647 minInt() A legkisebb egész számot adja vissza, mely: –2147483647 float() True értéket ad vissza abban az esetben, amikor a lebegopontos muveletek támogatva vannak. Ellenkezo esetben false értékkel tér vissza. exit(ertek) Félbeszakítja az aktuális WMLScript bájtkód végrehajtását, és a WMLScript interpretert meghívó eszköznek adja vissza a vezérlést a megadott értékkel. Nincsen visszatérési értéke, félbeszakítja a futtatást. A függvénybol való normális kilépés esetében használják abort(hibaleiras) Félbeszakítja az aktuális WMLScript bájtkód végrehajtását, és a WMLScript interpretert meghívó eszköznek adja vissza a vezérlést a megadott hibaleirassal. Nincsen visszatérési értéke, félbeszakítja a futtatást. A függvénybol való abnormális kilépés esetében használják random(ertek) 0 és A megadott érték közötti
véletlen egész számmal tér vissza. Ha az érték 0, akkor nullával tér vissza. seed(ertek) Inicializálja a megadott értékkel a véletlenszám generátort, és üres sztringgel tér vissza. characterSet() A WMLScript interpreter által támogatott karakterkészlet típusának megfelelo egész számot adja vissza. Float könyvtár Lebegopontos muveletek elvégzéséhez szükséges néhány függvényt tartalmaz. • int(ertek) A megadott érték egész részével tér vissza. például: var a=3.14; var b=Float.int(a); // b=3 var c=Float.int(-28); // c=-2 • floor(ertek) A megadott értékhez legközelebbi, de nem nagyobb egész számot adja vissza. például: var a=3.14; var b=Float.floor(a); // b=3 - 42 - WAP alapú alkalmazás fejlesztése A WMLScript nyelv var c=Float.floor(-28); // c=-3 • ceil(ertek) A megadott értékhez legközelebbi, de nem kisebb egész számot adja vissza. például: var a=3.14; var b=Float.ceil(a); // b=4 var c=Float.ceil(-28); // c=-2
• pow(ertek1,ertek2) Az ertek1 számot az ertek2.-dik hatványra emeli Ha ertek1 negatív, akkor ertek2 egész szám kell, hogy legyen. Invalid értéked ad akkor, amikor ertek1 = 0, vagy ertek2 < 0, valamint ertek1<0 és ertek2 nem egész szám. például: var a=3; var b=Float.pow(a,2); // b=9 • round(ertek) A megadott értékhez legközelebbi egész számmal tér vissza. Ha két szám ugyanolyan közel van hozzá, akkor a nagyobbat adja vissza. példa: var var var var • • • a=Float.round(35); // a=4 b=Float.round(-35); // b=-3 c=Float.round(05); // c=1 d=Float.round(-05); // d=0 sqrt(ertek) A megadott érték négyzetgyökével tér vissza. Invalid a visszatérési érték negatív szám esetében maxFloat() A legnagyobb lebegopontos számot adja vissza, mely: 3.40282347E+38 minFloat() A legkisebb nem negatív lebegopontos számot adja vissza, mely: 1.17549435E-38 String könyvtár Karaktersorozatokon végrehajtható függvényeket tartalmaz. A sztringet olyan
tömbként kezeli, ahol minden egyes karaktert a pozíciója alapján el lehet érni. Minden karakterhez tartozik egy index Az elso karakter indexe: 0. A sztring hossza a tömbben levo karakterek száma Lehetoség van szeparátor megadásával, mely segítségével a sztringet fel lehet darabolni, és hozzá lehet férni a szeparátor által szétválasztott elemekhez. Az elso elem indexe szintén 0 • • • • • • length(sztring) A megadott sztring hosszát adja vissza. isEmpty(sztring) True értékkel tér vissza akkor, amikor a megadott sztring üres, ellenkezo esetben false értékkel. charAt(sztring,index) A megadott sztringben levo index.-edik karaktert adja vissza Ha az index nagyobb, mint a sztring hossza, akkor üres sztringet ad vissza. subString(sztring,startIndex,length) A megadott sztring startIndex pozíciójától kezdodo length hosszú részét adja vissza. Ha a stringIndex kisebb mint 0, akkor 0-nak veszi. Ha a length nagyobb, mint a hátra levo karakterek
száma, akkor a hátra levo karakterek számát veszi length-nek. find(sztring1,sztring2) A sztring2 sztring1ben levo elso elofordulásának pozíciójával tér vissza. -1-et ad vissza akkor, ha sztring1 nem tartalmazza sehol sztring2-t. replace(sztring,regi,uj) A sztringben levo összes regi karaktersorozatot ujra cseréli ki. példák: var a="Szevasz Joe. Mi a helyzet Joe?"; var newName="Don"; var oldName="Joe"; var c=String.replace(a, oldName, newName); // c="Szevasz Don. Mi a helyzet Don?" var d=String.replace(a, newName, oldName); // d="Szevasz Joe. Mi a helyzet Joe?" • elements(sztring,szeparator) A szeparátor által elkülönített elemek számát adja vissza. Az üres sztring érvényes elem! - 43 - WAP alapú alkalmazás fejlesztése A WMLScript nyelv példák: var var var var var var var • a="Az en nevem Joe; Kor: 50;"; b=String.elements(a, " ");// b=6 c=String.elements(a, ";");//
c=3 d=String.elements("", ";"); // d=1 e=String.elements("a", ";"); // e=1 f=String.elements(";",";"); // f=2 g=String.elements(";;,;",";"); // g=4 szeparátor=; elementAt(sztring,index,szeparator) A szeparátor által elkülönített index.-edik elemet adja vissza Invalid értékkel tér vissza akkor, amikor a szeparátor üres. Ha az index nagyobb, mint az elemek száma, akkor az utolsó elemet adja meg. Ha a sztring üres, akkor egy üres sztringet ad vissza például: var a="Az en nevem Joe; Kor: 50;"; var b=String.elementAt(a, 0, " "); // b="Az" var c=String.elementAt(a, 14, ";"); // c="" ar d=String.elementAt(a, 1, ";"); // d=" Kor: 50" • removeAt(sztring,index,szeparator) A szeparátor által elkülönített index.-edik elemet kitörli Invalid értékkel tér vissza akkor, amikor a szeparátor üres. Ha az index nagyobb, mint
az elemek száma, akkor az utolsót törli ki Ha a sztring üres, akkor egy üres sztringet ad vissza. például: var var var var var • a="A A; B C D"; s=" "; b=String.removeAt(a, 1, s); // b="A B C D" c=String.removeAt(a, 0, ";"); // c=" B C D" d=String.removeAt(a, 14, ";"); // d="A A" replaceAt(sztring,elem,index,szeparator) A szeparátor által elkülönített index.-edik elemet kicseréli az "elem"-re Invalid értékkel tér vissza akkor, amikor a szeparátor üres. Ha az index nagyobb, mint az elemek száma, akkor az utolsót cseréli ki. Ha a sztring üres, akkor egy új sztringet ad vissza a megadott elemmel például: var var var var a="B C; E"; s=" "; b=String.replaceAt(a, "A", 0, s); // b="A C; E" c=String.replaceAt(a, "F", 5, ";"); // c="B C;F" insertAt(sztring,elem,index,szeparator) A szeparátor által elkülönített
elemek közé az index.-edik pozícióba beszúrja az elemet Invalid értékkel tér vissza akkor, amikor a szeparátor üres. Ha az index nagyobb, mint az elemek száma, akkor a sztring végére szúrja be az elemet. Ha a sztring üres, akkor egy új sztringet ad vissza a megadott elemmel. • például: var var var var var var • • • • a="B C; E"; s=" "; b=String.insertAt(a, c=String.insertAt(a, d=String.insertAt(a, e=String.insertAt(a, "A", "X", "D", "F", 0, 3, 1, 5, s); // b="A B C; E" s); // c="B C; E X" ";"); // d="B C;D; E" ";"); // e="B C; E;F" squeeze(sztring) A megadott sztringben levo egymás melletti több üres karaktereket egyetlen egyre cseréli ki minden helyen. trim(sztring) A megadott sztring elejérol és a végérol kitörli az üres karaktereket, és az új sztringet adja vissza. compare(sztring1,sztring2) A megadott két sztring
lexikografikus sorrendjével tér vissza a következok szerint: -1 : sztring1 kisebb mint sztring2 0 : sztring1 egyenlo sztring2-vel 1 : sztring1 nagyobb mint sztring2 toString(value) A megadott értéket karaktersorozattá konvertálva adja vissza. példák: var a=String.toString(12); // a="12" var b=String.toString(true); // b="true" • format(formatum,ertek) A megadott értéket a megadott formátumú sztringre formázva adja vissza. A formázó szöveg a - 44 - WAP alapú alkalmazás fejlesztése A WMLScript nyelv következo formátum leírókat tartalmazhatja (csak egy formátum leírót tartalmazhat egy formátum, ha több van, akkor a legelso formátumot tekinti érvényesnek, és a maradék formátumleírókat üres sztringgel helyettesíti): % [szélesség] [.pontosság] típus típus lehet: d (decimális), f (lebegopontos), s (sztring) Az eredményben a % karaktert %%-ként lehet megjeleníttetni. példák: var var var var var var var var var var
var var var var var a=45; b=-45; c="now"; d=1.2345678; e=String.format("e: %6d", a); // e="e: 45" f=String.format("%6d", b); // f=" -45" g=String.format("%64d", a); // g=" 0045" h=String.format("%64d", b); // h=" -0045" i=String.format("Do it %s", c); // i="Do it now" j=String.format("%3f", d); // j="1234567" k=String.format("%102f%%", d); // k=" 123%" l=String.format("%3f %2f", d); // l="1234567 " m=String.format("%0d", 0); // m="" n=String.format("%7d", "Int"); // n=invalid o=String.format("%s", true); // o="true" URL könyvtár Abszolút vagy relatív URL-eket kezelo függvényeket tartalmaz. Egy url általános felépítése: <séma>://<host>:<port>/<path>;<paraméterek>?<lekérdezés>#<fragment> • •
isValid(url) True értékkel tér vissza, ha a megadott URL szintaktikailag helyes, egyébként false értéked ad. getScheme(url) A megadott url sémáját adja vissza. pl.: var a=URLgetScheme("http://xyz/abc;1;2?x=1&y=2"); //a = "http" var b=URL.getScheme("xyz/abc#fragment"); //b = "" • getHost(url) A megadott url-ben levo host-ot adja vissza. pl.: var a=URLgetHost("http://xyz/abc;1;2?x=1&y=2"); //a = "xyz" • getPort(url) A megadott url-ben levo portot adja vissza. pl.: var a=URLgetPort("http://xyz:71/abc;1;2?x=1&y=2"); //a = "71" • petPath(url) A megadott url-ben levo elérési utat adja vissza. pl.: var a=URLgetPath("http://xyz/abc;1;2?x=1&y=2"); //a = "http://xyz/abc" getParameters(url) A megadott url paramétereit adja vissza. pl.: var a=URLgetParameters("http://xyz/abc;1;2?x=1&y=2"); //a = "1;2" getQuery(url) A megadott url-hez
tartozó lekérdezést adja vissza pl.: var a=URLgetQuery("http://xyz/abc;1;2?x=1&y=2"); //a = "x=1&y=3" getFragment(url) A megadott url-hez tartozó fragmentet adja vissza. pl.: var a=URLgetFragment("http://xyz/abc#fragment"); //a = "fragment" getBase () Az aktuális fordítási egységet azonosító abszolút URL címet adja vissza. getReferer() Az aktuális fordítási egységet meghívó eroforráshoz tartozó legkisebb relatív URL-t adja vissza. resolve(baseUrl,embeddedUrl) Egy abszolút URL-t ad vissza a megadott kezdo URL és a beágyazott URL összefuzéseként. Ha a beágyazott URL már egy abszolút URL, akkor változtatás nélkül visszaadja azt. var b=URL.getHost("abc#fragment"); //b = "" var b=URL.getPort("http://xyz/abc;1;2?x=1&y=2"); //b = "" • • • • • • - 45 - WAP alapú alkalmazás fejlesztése • • • A WMLScript nyelv escapeString(sztring) A
sztringben megadott speciális karaktereket kicseréli a nekik megfelelo hexadecimális escape szekvenciákra. Ezek a karakterek a következok: – space – ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" | "$" | "," – "{" | "}" | "|" | "" | "^" | "[" | "]" | "`" – "<" | ">" | "#" | "%" | <"> unescapeString(sztring) A sztringben megadott hexadecimális escape szekvenciáknak megfelelo karaktersorozatokat kicseréli a nekik megfelelo karakterekre, és az új sztringet adja vissza. Az escapeString() függvénnyel ellenkezo hatást vált ki. loadString(url,contentType) Visszatérési értékül az url és contentType által megadott tartalmat adja meg. Csak egy contentType adható meg paraméterként. A tartalom típusa text kell hogy legyen, de az
altípus bármi lehet. Hatása a következo: Betölti az url és a contentType által hivatkozott tartalmat. Ha a betöltés sikeres volt, és a visszaadott tartalom típus megegyezik a megadott contentType értékkel, akkor a betöltött tartalmat sztring formátumúvá konvertálja, és azt adja vissza. Ha a betöltés sikertelen, akkor a sémának megfelelo hibakóddal tér vissza WMLBrowser könyvtár Olyan függvényeket tartalmaz, melyek a WML környezet hozzáférésére alkalmasak. A függvények invalid értéket adnak vissza akkor, ha a rendszer a WML böngészot nem támogatja. • • • • • • • getVar(name) A böngészo környezetében levo "name" nevu változó értékét adja vissza. Ha nincsen olyan nevu változó, akkor üres sztringgel tér vissza. Invalid a visszatérési érték akkor, amikor a "name" szintaxisa nem megfelelo. setVar(name,value) True értéket ad vissza abban az esetben, amikor sikerült a böngészo
környezetében levo "name" nevu változó értékét a "value" értékre módosítani. Egyébként false értékkel tár vissza Invalid értékkel tér vissza akkor, amikor a változó neve, vagy az értéke hibás. go(url) A megadott url alatti kártyát betölti. Hatása megegyezik a WML-ben levo GO taszk hatásával Ha az url "" (üres sztring), akkor nem tölt be semmit. A go() és a prev() felülírják egymást Üres sztringet ad vissza. prev() Jelzi a böngészonek, hogy menjen vissza az elozo WML kártyához. A kártyát csak abban az esetben tölti be a böngészo, miután a WMLScript interpreter befejezte a feladatát. A go() és a prev() felülírják egymást. Csak a legutolsó hívásnak van hatása a böngészo állapotára Üres sztringet ad vissza. newContext() Kitörli a böngészo környezetét, és üres sztringgel tér vissza. Hatása megegyezik a WML-ben levo NEWCONTEXT paraméter hatásával. getCurrentCard() Visszaadja a WML
böngészoben levo kártyához tartozó legkisebb relatív URL-t. Abszolút URL-t ad vissza abban az esetben, amikor az aktuális fordítási egység és a böngészoben levo kártya URLjének a kiindulási pontja nem ugyanaz. refresh () Frissíti a böngészo környezetét és üres sztringet ad vissza. Hatása megegyezi a WML-ben levo REFRESH taszk elindításával. pl.: WMLBrowser.setVar("name","Valaki"); WMLBrowser.refresh(); Dialogs könyvtár A felhasználói felületen "manipuláló" függvényeket tartalmaz. • prompt(uzenet,defaultInput) Megjeleníti az üzenetet, és egy beviteli mezot, és vár a felhasználóra, hogy beírjon valamit. A defaultInput mezo a beviteli mezo kezdoértékét tartalmazza. - 46 - WAP alapú alkalmazás fejlesztése • • A WMLScript nyelv confirm(uzenet,ok,cancel) Megjeleníti az üzenetet és a két választási lehetoséget (ok, cancel). Ezt követoen arra vár, hogy a két lehetoség közül válasszon
a felhasználó. True értéket ad vissza akkor, amikor a felhasználó az ok-t, false értéket ad vissza ha a cancel-t válassza. pl.: return Dialogsconfirm("Biztos benne?","Igen","Nem"); Visszatérési érték: Igen választása esetén à true Nem választása esetén à false alert(uzenet) Az üzenetet megjeleníti, és megerosítést vár a felhasználótól, majd üres sztringgel tér vissza. V10. WMLS CRIPT PÉLDA Végül következzen egy rövid WMLScript példa, mely segítségével bemutatom azt, hogy hogyan lehet a WML és a WMLScript oldalakat összekapcsolni. A példa egy egyszeru számológép, mely a 4 alapmuveletet tudja használni. A számítási muveleteket WMLScripten keresztül végzi a program. Az oldal tartalmaz 2 beviteli mezot a két operandus bevitelére, valamint egy listát a muveleti jel kiválasztására. A számítás elvégzése után az eredmény az elso operandusba kerül, és a második értéke nullázódik. A WML
oldal: <?xml version="1.0"?> <!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN" "http://wwwwapforumorg/DTD/wml 11xml"> <wml> A WML kártya definiálása. A kártya felirata Szamologep lesz <card id="Szamologep" title="Szamologep"> Egy eseménykezelo definiálása, melynek a feladata az, hogy minden egyes alkalommal, amikor az oldalt meghívják, az operandusok értékét lenullázza, és a muvindex változó értékét 1-re állítsa. A muvindex mutatja azt meg, hogy melyik muveleti jel legyen az alapértelmezett. <onevent type="onenterforward"> <refresh> <setvar name="muvindex" value="1"/> <setvar name="elso" value=""/> <setvar name="masodik" value=""/> </refresh> </onevent> <p> A két operandus bevitelére alkalmas mezok definiálása 1.: <input type="text" name="elso"
format="*N"/> 2.: <input type="text" name="masodik" format="*N"/> Muvelet: A muveleti jel kiválasztását megadó lista definiálása. A name paraméter adja meg, hogy a kiválasztott muveleti jel értéke hova kerül. Az iname paraméter adja meg, hogy a kiválasztott muveleti jel indexe hova kerül. Az ivalue paraméter adja meg az alapértelmezett indexet. Mivel azonban korábban az iname változóban megadott muvindex változó értéke már be lett 1-re állítva, így hatása figyelmen kívül lesz hagyva. Ezt csupán a szemléltetés kedvéért raktam bele a programba A multiple paraméter azt adja meg, hogy egyszerre csak egy muveleti jelet lehet kiválasztani. A title paraméter pedig a select elem feliratát adja meg. <select name="muvelet" iname="muvindex" ivalue="2" multiple="false" title="Muveleti jel"> <option value="+" >+</option> <option
value="-" >-</option> <option value="*" ></option> <option value="/" >/</option> </select> </p> Az eredmény kiszámítására egy opció gombot definiálok <do type="accept" label="Kiszamol"> Az opció gomb hatására elindítja a szamol.wmls WMLScript eredmeny nevu függvényt <go href="szamol.wmls#eredmeny()"/> </do> </card> </wml> - 47 - WAP alapú alkalmazás fejlesztése A WMLScript nyelv Most következzen a WMLScript állomány ismertetése: A WMLScript állomány neve: szamol.wmls A számítást az eredmény függvény végzi el. A számítás paramétereit a böngészo környezetében levo elso, masodik és a muvindex nevu változókból veszi, majd az eredményt is az elso változóba rakja vissza. extern function eredmeny() { Ha a muvindex értéke 1, akkor összeadásról van szó if (WMLBrowser.getVar("muvindex") == 1) {
Az elso változóba berakja az elso és a masodik összegét WMLBrowser.setVar("elso",WMLBrowsergetVar("elso")+WMLBrowsergetVar("masodik")); } Ha a muvindex értéke 2, akkor kivonásról van szó if (WMLBrowser.getVar("muvindex") == 2) { Az elso változóba berakja az elso és a masodik különbségét WMLBrowser.setVar("elso",WMLBrowsergetVar("elso")-WMLBrowsergetVar("masodik")); } Ha a muvindex értéke 3, akkor szorzásról van szó if (WMLBrowser.getVar("muvindex") == 3) { Az elso változóba berakja az elso és a masodik szorzatát WMLBrowser.setVar("elso",WMLBrowsergetVar("elso")*WMLBrowser.getVar("masodik")); } Ha a muvindex értéke 4, akkor osztásról van szó if (WMLBrowser.getVar("muvindex") == 4) { Az elso változóba berakja az elso és a masodik hányadosát
WMLBrowser.setVar("elso",WMLBrowsergetVar("elso")/WMLBrowsergetVar("masodik")); } Kitörli a masodik változó tartalmát WMLBrowser.setVar("masodik",""); A böngészo környezetét frissíti WMLBrowser.refresh(); } A WML oldal kimenete Nokia 6150-es telefonon a következo: A fooldal A muveleti jelek kiválasztása - 48 - Az options gomb alatt van a Kiszamol gomb elhelyezve WAP alapú alkalmazás fejlesztése WML tartalom generálása más nyelvekkel VI. WML TART ALOM GENER ÁLÁS A M ÁS NYE LVE KKE L A következoben néhány elterjedt nyelveken mutatom be, hogy hogyan lehet egy egyszeru WML oldalt generáltatni. Jelen esetben nem az a célom, hogy az egyes nyelveket bemutassam, hanem az, hogy egy példán keresztül illusztráljam annak használatát WML tartalom generálására. Az egyes nyelvek esetében ugyanazt a példát használom. Van két oldal (question* és answer.*). A question oldal bekér egy nevet, melyet
elküld az answer oldalnak, és az visszaírja azt a nevet. A példák bemutatásánál látható majd, hogy nem a teljes nyelv bemutatására törekedtem, hanem a fontosabb utasítások bemutatására, melyek segítségével már lehet egy dinamikus WML oldalt készíteni. VI1. A CGI HASZNÁLATA WML TARTALOM GENERÁLÁSÁRA A CGI esetében a Perl nyelvet használva mutatom be, hogy hogyan lehet ezt az egyszeru wml oldalt legeneráltatni. question.cgi #!/usr/local/bin/perl print "Content-type: text/wnd.wapwml "; print "<?xml version="1.0"?>"; print "<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN" "http://www.wapforumorg/DTD/wml 11xml">"; print "<wml>"; print "<card id="main" title="Teszt">"; print " <p align="center">"; print " Udvozollek"; print " <br/>"; print " A neved:<input
type="text" name="name"/>"; print " <anchor>Elkuld"; print " <go href="/cgi-bin/answer.cgi">"; print " <postfield name="neved" value="$(name)"/>"; print " </go>"; print " </anchor>"; print "</p>"; print "</card>"; print "</wml>"; answer.cgi #!/usr/local/bin/perl print "Content-type: text/vnd.wapwml "; require cgi-lib.pl &ReadParse(*input); print "<?xml version="1.0"?>"; print "<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN""http://wwwwapforumorg/DTD/wml 11xml">"; print "<wml>"; print "<card id="valasz" title="Udvozollek">"; print "<p align="center">"; print " Szevasz <br/>" .$input("neved"); print
"</p>"; print "<do type="prev" label="Vissza">"; print " <prev/>"; print "</do>"; print "</card>"; print "</wml>"; A CGI szkript elso sora tartalmazza, hogy a szervernek milyen programot kell elindítania, ha valaki hivatkozik rá. Jelen esetben ez a szkript Unix alatt muködik, és a /usr/local/bin/Perl Perl fordítót indítja el A második sor tartalmazza a tartalom típusát. A szerver egy szkript elindítása után annak kimenetének sorai közül egészen az elso üres sorig tartozó sorokat az elküldento tartalom fejlécének tekinti. Ide kell például beírni a szöveg típusát (Content Type) is. Az elso fájl nem csinál mást, mint print utasításokat használva a standard kimenetre kiír egy wml tartlmat. Ebben nincsen semmilyen más utasítás használva. A második már sokkal több Perl utasítást tartalmaz. A require ‘cgi-lib.pl’ sor eloírja a
fordító számára, hogy fordítsa be a cgi-libpl Perl könyvtár eljárásait, tegye lehetové az azokhoz való hozzáférést. - 49 - WAP alapú alkalmazás fejlesztése WML tartalom generálása más nyelvekkel A cgi-lib.pl könyvtár tartalmazza ugyanis a ReadParse eljárást, mely lehetové teszi, hogy a szkript számára elküldött név/érték párokat egy asszociatív tömbben eltárolja. Ezt követoen ebbol a tömbbol már egyszeruen le tudjuk kérdezni az egyes paraméter értékét. A függvények meghívására az & karaktert használva van lehetoség. Szövegek kiiratására a print utasítás való. Az asszociatív tömbben levo elem értékének kiiratása a következoképpen történik. Egy $ jelet követoen le kell írni a tömb azonosítóját, majd zárójelbe meg kell adni a paraméter nevét, mely a szkript számára elküldött paraméter/érték pár közül az azonosító (“neved”). Jelen esetben ez: $input(“neved”) Mint a példa is mutatja,
szövegek összefuzésére a . karakter használható VI2. A PHP HASZNÁLATA WML TARTALOM GENERÁLÁSÁRA question.php <?php Header("Content-Type: text/vnd.wapwml"); $fp=fopen("question.wml","r"); fpassthru($fp); ?> question.wml <?xml version="1.0"?> <!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN" "http://wwwwapforumorg/DTD/wml 11xml"> <wml> <card id="main" title="Teszt"> <p align="center"> Udvozollek <br/> A neved:<input type="text" name="name"/> <anchor>Elkuld <go href="answer.php"> <postfield name="neved" value="$(name)"/> </go> </anchor> </p> </card> </wml> answer.php <?php Header("Content-Type: text/vnd.wapwml"); echo "<?xml version="1.0"?>"; echo "<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML
1.1//EN""http://wwwwapforumorg/DTD/wml 11xml">"; echo "<wml>"; echo "<card id="valasz" title="Udvozollek">"; echo "<p align="center">"; echo " Szevasz <br/>"; echo $neved; echo "</p>"; echo "<do type="prev" label="Vissza">"; echo " <prev/>"; echo "</do>"; echo "</card>"; echo "</wml>"; ?> Egy PHP oldal <?php és ?> karaktersorozatok között helyezkedik el. Minden egyes PHP utasítást ; kell hogy lezárjon. Mivel a WML oldalak nem text/html típusúak, így azt, hogy milyen típusú oldalt küld el a szerver közölni kell vele. Ezt a Header("Content-Type: text/vndwapwml"); PHP utasítás hajtja végre A PHP esetében az echo utasítással lehet szöveget elküldeni a fogadóhoz. WML oldal generálására kétfajta módot mutattam be az
elozo példánál. Az egyik esetében egy már kész wml oldalt olvas be a php állomány A másik esetében pedig echo utasítás használatával kerülnek kiíratásra a WML sorok. - 50 - WAP alapú alkalmazás fejlesztése WML tartalom generálása más nyelvekkel Elso esetben a $fp=fopen("question.wml","r"); utasítás megnyitja a questionwml állományt olvasásra, és az fpassthru($fp); utasítás azt elküldi a fogadónak. A php oldalnak elküldött argumentumok kezelésére a PHP lehetové teszi azt, hogy a kapott paraméterekre a nevükkel hivatkozzunk, azaz jelen esetben az answer.php-t a neved=valami paraméterrel meghívva a $neved változó visszaadja a “valami” szöveget, melyet aztán az echo utasítással kiíratunk. VI3. AZ ASP HASZNÁLATA WML TARTALOM GENERÁLÁSÁRA question.asp <% Response.ContentType = "text/vndwapwml" %> <?xml version="1.0"?> <!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML
1.1//EN" "http://www.wapforumorg/DTD/wml 11xml" > <wml> <card id="main" title="Teszt"> <p align="center"> Udvozollek <br/> A neved:<input type="text" name="name"/> <anchor>Elkuld <go href="answer.asp"> <postfield name="neved" value="$(name)"/> </go> </anchor> </p> </card> </wml> answer.asp <% Response.ContentType = "text/vndwapwml" %> <?xml version="1.0"?> <!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN" "http://wwwwapforumorg/DTD/wml 11xml"> <wml> <card id="valasz" title="Udvozollek"> <p align="center"> Szevasz <% Response.write RequestQueryString("neved") %> </p> <do type="prev" label="Vissza"> <prev/> </do> </card> </wml> Az ASP
utasítások <% és %> karaktersorozatok között helyezkednek el. Látható, hogy mivel a wml oldalak típusa nem text/html, így ezt a szerverrel közöltetni kell, melyet a Response.ContentType = ”text/vndwapwml” ASP utasítással lehet megtenni Ezután már következhet egy normál WML oldal. Az answer.asp tartalmaz egy példát még arra, hogy hogyan lehet egy paraméter értékét – melyet az oldal megkap – lekérdezni. Ezt a RequestQueryString() ASP utasítás teszi lehetové Lehetoség van egy szöveg kiíratására ASP kód segítségével a Response.write utasítással, melyet kell, hogy kövessen a kiíratandó szöveg. VI4. A JSP NYELV A JSP nyelv bemutatásánál nem törekszem a teljes leírásra, hanem csupán a lényeges, fontosabb szintaxisok, lehetoségek ismertetésére. A JSP-t azért mutatom be, mivel szinte majdnem ugyanolyan módon használható WML oldalak generálására mint a szervletek, csak annyiban tér el, hogy itt egy „statikus WML”
oldalban szerepelhetnek Java utasítások, míg szervletek esetében egy Java osztály írja ki a kimenetre a statikus WML oldalt! - 51 - WAP alapú alkalmazás fejlesztése WML tartalom generálása más nyelvekkel A JavaServer Pages (JSP) a Java szervletekhez hasonlóan egy klienstol érkezo kérés alapján valamilyen szöveges, leggyakrabban HTML vagy XML formátumú dokumentum dinamikus, szerveroldali eloállítására szolgáló technológia, a Java 2 Enterprise Edition (J2EE) része. A JSP oldalak lényegében nem mások, mint „kifordított szervlet”-ek: szervletek esetében a Java kódban elrejtve szerepelnek a szöveget a kimenetre író utasítások, azonban a JSP esetében a rögzített szöveg között szerepelnek az oldal tartalmát dinamikusan módosító utasítások. A JSP oldalak elonyei elsosorban az olyan oldalaknál mutatkoznak, amelyek relatíve sok fix szöveget, és kevés kódot tartalmaznak. A JSP muködése könnyen megértheto a következo
példán, mely bemutatja, hogy mi történik egy JSP oldal lekérésekor a webkiszolgálóról: 0. Tekintsünk egy olyan állományt, mely csak egyetlen egy sort tartalmaz: „Hello World!” Ezt helyezzük el a webszerver gyökérkönyvtárába hello.jsp néven 1. A kliens elküldi a kérését a szervernek 2. A webszerver a jsp kiterjesztés alapján felismeri, hogy egy JSP állományra vonatkozik a kérés, így továbbítja azt a JSP containernek, ami lehet a webkiszolgáló része, vagy külön plug-in. 3. Mivel ez volt az adott dokumentumra vonatkozó elso kérés, a JSP fordító a jsp forrásból sorról-sorra haladva eloállítja a neki megfelelo java szervlet forrását. 4. A java kódot a javac fordítóval lefordítja egy class állományba 5. Inicializálja a szervletet, majd a szervlet a kérést megkapva eloállítja az oldal végleges szövegét 6. Ami aztán eljut a klienshez A muködés lényege tehát annyi, hogy a JSP egyszerubb, szövegvezérelt formátumából egy
specializált fordító szervlet kódot készít, és ez szolgálja ki a kérést. Azonban nyilvánvaló, hogy a plusz fordítási ido – mely a legelso kéréskor történik meg, és a forrás minden egyes módosításakor elvégzodik – lassabb válaszolási idot jelent, de csak az elso kérésnél, a további kérések már a szervlethez továbbítódnak! A JSP oldalak szövegébe helyezett Java kódrészlet változatlanul kerül bele a szervlet forrásszövegébe, így a JSP is megorzi a szervletek egyik nagy elonyét: tetszoleges Java API (pl. a JDBC) vagy saját Java osztály meghívható. A JSP elemei Egy JSP oldalban tetszoleges számban és tetszoleges helyen elofordulhatnak JSP elemek, melyek lehetnek: direktívák, script-elemek és akcióelemek. Minden olyan literál, amit a JSP fordító nem ismer fel, a whitespaceket is megorizve egy az egyben bekerül az eloállított oldal szövegébe. A JSP saját elemeinek egy része XML szeru tag, egy része viszont a könnyebb
gépelhetoség kedvéért az XML konverziótól eltéro, egyszerubb jelölést használ. A JSP nyelvi elemeire is igaz, hogy a kis- és a nagybetuk különbözonek számítanak. Fontos azonban, hogy a JSP-nek saját megjegyzési formátuma van: <%-- ez egy megjegyzés --%> Direktívák A direktívák a JSP containernek szóló utasítások, közös jellemzojük, hogy <%@ direktiva-nev attr1=”ertek1” attr2=”ertek2” %> alakúak, és nem módosítják az eloállított oldal szövegét. A page direktíva Segítségével az egész oldalra vonatkozó jellemzoket lehet beállítani. A fordítási egységben (ami nem más, mint az adott oldal és az include direktívával beillesztett oldalak egésze) akárhányszor és akárhol elofordulhat, de az import kivételével minden attribútumnak csak egyszer adhatunk értéket. Néhány fontos attribútum: • language: A script-részletekben, kifejezésekben, és deklarációkban használt programozási nyelv neve. Az 11-es
specifikáció a JSP containerek számára csak a java érték elfogadását teszi kötelezové és ez az alapértelmezés is. • extends: Megadja, hogy a JSP oldalból készült osztály melyik osztálynak legyen a leszármazottja. • import: Ezzel az attribútummal az oldalból készülo szervlet import listáját egészíthetjük ki, aminek a specifikáció szerint eleve tartalmaznia kell a java.lang*, javax.servlet*, javax.servletjsp* és a javax.servlethttp* csomagokat. • isThreadSafe: Megadhatjuk, hogy oldalunk fel van-e készítve arra, hogy egyszerre több kérést szolgáljon ki párhuzamosan, vagy sem. Az alapértelmezett true esetén a - 52 - WAP alapú alkalmazás fejlesztése • • • • WML tartalom generálása más nyelvekkel JSP container egyszerre több kérést is átadhat az oldalnak, míg false esetében a kérések sorbaállítódnak. (A gyakorlatban ez a javaxservletSingleThreadModel interface implementálásával zajlik.) info: Ennek
segítségével adhatjuk meg az oldal rövid leírását, a Servlet.getServletInfo megfeleloje. errorPage: annak a JSP oldalnak az URL-je, amelyikhez az oldalban esetleg fellépo java.langThrowable osztályú kivételt továbbítani szeretnénk (A kivételkezelo oldal a kivételt a ServletRequest objektum javax.servletjspjspException nevu paramétereként kapja meg. isErrorPage: A kivételkezelo oldal esetén állítsuk az értékét true-ra, és akkor a megkapott kivétel elérhetové válik az implicit exception változón keresztül. contentType: Megadja az oldal MIME típusát és karakterkódolását ”TYPE” vagy ”TYPE;charset=CHARSET” formátumban. Az alapértelmezés: ”text/html;charset=ISO8859-1” Az include direktíva Adott file fordítás elotti beillesztésére szolgál. A beillesztés statikus, a megadott file bájtról bájtra másolódik be. Egyetlen attribútuma a file, értéke egy fájlra mutató relatív URL Script elemek Háromféle script-elem
lehetséges: deklaráció, script-részlet és kifejezés. Mivel mindhárom az oldal scriptnyelvén alapul, ezért ezek pontos jelentése függ a használt nyelvtol is. A továbbiakban csak a Java esetérol lesz szó. A script-elemek szintaxisa: <%! deklaráció %> <% script részlet %> <%= kifejezés %> Deklarációk A deklaráció elnevezés kissé megtéveszto, mert változókat deklarálni sciptrészletek belsejében is lehet, metódusokat viszont nem. Ennek magyarázata az, hogy míg a script részleteket a JSP fordító a készülo szervlet jspService metódusába, az aktuális helyre teszi, addig a deklarációk a szervlet metódusain kívülre másolódnak, tehát osztály szintu változókat, illetve metódusokat hoznak létre. Deklaráció révén van lehetoségünk a szervlet init, illetve destroy metódusának átdefiniálására. Ehhez deklarálnunk kell a jspInit illetve jspDesptroy metódusokat. Más szervlet metódust nem definiálhatunk át,
továbbá foglaltak a jsp, jsp, jspx és jspx kezdetu metódusnevek is. Script-részletek A script-részletek egy az egyben bekerülnek a jspService metódus forrásába, mégpedig a JSP oldalban elfoglalt helyüknek megfelelo helyre. A script-részletek tetszolegesen keveredhetnek az oldal szövegével, de egybeolvasva oket az adott nyelven értelmes kódot kell hogy alkossanak! Kifejezések A kifejezések olyan script elemek, melyeket a fordító String típusra hozhat, és közvetlenül a kimenetre írhat. Akció elemek <jsp:useBean> akció Többféle funkciót egyesít. Lényege, hogy megpróbálja megkeresni a megadott névtérben (scope) megadott néven (id) szereplo objektumot, és az oldal script nyelve számára szintén id néven elérhetové tenni, type típusra kényszerítve. Használható ugyanakkor objektumok illetve JavaBeanek példányosítására is, ugyanis ha a keresés nem járt sikerrel, akkor a class vagy beanName attribútumok alapján megkísérli
példányosítani az adott osztályt, elhelyezi a kapott objektumot a scope névtérben és az id értékeként megadott néven a scriptnyelv számára is elérhetové teszi az új objektumot. Kötelezo értéket adni az id attribútumnak, valamint a type és a class attribútumok közül legalább az egyiknek. A scope a következo értékeket kaphatja: - 53 - WAP alapú alkalmazás fejlesztése WML tartalom generálása más nyelvekkel page: A nevezett objektumot az oldal javax.servletjspPageContext objektumában keresi, illetve az új objektumot ott tárolja. Az ilyen objektumok élettartama az oldal egyetlen lefutásának ideje request: Az objektumot a kérés javax.servletServletRequest objektumában keresi, illetve tárolja el. Élettartama a kérés kiszolgálásának befejezéséig tart session: Az objektumot a felhasználóhoz kötodo javax.servlethttpHttpSession objektumban keresi, illetve az új objektumot ott tárolja el. application: Az objektumot az egész
web-alkalmazáshoz tartozó javax.servletServletContext objektumban keresi, illetve tárolja el <jsp:setProperty> akció A jsp:useBean akcióval, vagy script-elemmel létrehozott beanek tulajdonságainak beállítását szolgálja. Két kötelezo attribútuma a name és a property A value paraméter megadásával tetszoleges, akár futási idoben számolt értéket is adhatunk az adott tulajdonságnak. <jsp:getProperty> akció A jsp:useBean akcióval, vagy valamilyen script-elemmel létrehozott bean valamely tulajdonságának a lekérdezésére szolgál. A name attribútum értékeként megadott névvel rendelkezo bean property nevu tulajdonságát kérdezi le, és írja ki megfelelo konverzió után a JSP oldal szabványos kimenetére. <jsp:include> akció Az oldal adott pontján beilleszthetjük egy másik szervlet vagy JSP oldal futásának eredményét. Az include direktívához hasonlóan a jsp:include akcióval is lehetséges statikus eroforrások beszúrása,
azonban az akcióval beszúrt statikus fájl a kérés kiszolgálásakor, utólag illesztodik bele a készülo oldal szövegébe. A page attribútumnak kell értékül adni a beillesztendo eroforrás URL-jét, ami lehet kifejezés futásideju eredménye is, a szintén kötelezo flush attribútum értéke minden esetben true kell hogy legyen. Az elem törzsében lehetnek jsp:param akciók, ekkor a kérés kiegészül az ezekben megadott paraméterekkel, mielott a kívánt eroforrásnak átadódna, <jsp:include page="url" flush="true"/> vagy <jsp:include page="url" flush="true"> <jsp:param name="nev" value="ertek"/> </jsp:include> <jsp:forward> akció Segítségével a kérést továbbíthatjuk egy másik statikus eroforrásnak, szervletnek, vagy JSP oldalnak. Egyetlen paramétere a page, aminek az eroforrás relatív URLjét kell értékül adni Az elem törzsében lehetnek jsp:param akciók is
<jsp:forward page="url"/> vagy <jsp:forward page="url"> <jsp:param name="nev" value="ertek"/> </jsp:forward> <jsp:param> akció A korábbi akciók törzsében szerepelhet, célja kulcs-érték párok egymáshoz rendelése, az akciók paraméterezése. Két kötelezo attribútuma a name és a value. - 54 - WAP alapú alkalmazás fejlesztése Az elkészített játék VII. AZ E LKÉSZÍTETT JÁTÉ K Az elkészített játékot egyszerre többen játszhatják. A történet egy labirintusban játszódik, mely a lehetoségekhez képest 3D-s formában jelenik meg a játékosok elott. A játékosok látják egymást a labirintusban, valamint egy térkép segíti a tájékozódást. A játék célja, hogy minél több pontot szerezzenek össze a játékosok a labirintusban történo harcolás során. A játékosok egymás ellen harcolhatnak Minden egyes játékos két tulajdonsággal rendelkezik: harci ero és
védelmi szint. A tulajdonságok értékét a játékosok növelhetik, ha a labirintusban felszednek különbözo tárgyakat. El van rejtve 200-200 tárgy, melyek növelik a megfelelo tulajdonság értékét, azonban a játékosok a térképen csak a tárgyak jelenlétét látják. Azt nem, hogy mely tulajdonságot növelik Ha egy tárgyat felvesz egy játékos – melyet csak akkor tehet meg, ha az adott tulajdonsága nem 100%-os –, akkor az eltunik a többi játékos elol is, és egészen addig nem jelenik meg, amíg minden egyes tárgyat – mind a 400-at – fel nem szedték, így a játék vége felé egyre nehezebb lesz a harc. Ha az összes tárgyat már felszedték, akkor jelenik meg ismét az összes A harc kimenetele a támadó erejétol függ. Minden egyes támadás esetén a harci ero 10%-ának megfelelo értékkel csökken a támadónak az ereje, valamint a támadott játékos védelme. Természetesen egy játékos egyszerre csak egy játékost támadhat, azonban egy
játékost többen is támadhatnak. Abban az esetben, amikor valamely játékos támad egy másikat, akkor pontszáma annak megfeleloen no, hogy mekkora volt az ütés, azaz mekkora értékkel csökkent a másik védelmi szintje. Ha a szenvedo alany védelmi szintje 0 lesz, akkor kilépteti a rendszer ot a játékból, és újból be kell majd lépnie a játékba a játékosnak. Ekkor a támadó pontja 20-al növekszik. Minden egyes alkalommal, ha egy játékos be akar szállni a játékba meg kell adnia egy azonosítót és egy jelszót, mely segítségével a program kikeresi a játékos adatait egy adatbázisból. Ha a játékos még nincsen az adatbázisban, akkor eloször regisztrálnia kell magát Sikeres belépés esetében a játékos ott folytatja a játékot, ahol korábban kilépett, illetve ha valaki megölte ot, akkor egy véletlen helyre kerül. Ekkor a védelmi szintje és a támadó ereje egyaránt a minimális 10 lesz A játékos a labirintusban egyszerre csak
kétfalnyira lát elore maximum. A térkép is csak a 3x3-as környezetét mutatja a játékosnak. Az irányítás a következoképpen történik: A játékos vagy egy helyben áll, vagy fut. Ha egyhelyben áll, akkor lehetoség van, hogy körbe forogjon, ha viszont megy, akkor az elfordulás után a megfelelo irányba megy tovább. A játék egy generált labirintusban zajlik, melynek olyan a felépítése, hogy egy útnak maximum csak 3 szomszédja van. Nincsen tehát négyes keresztezodés benne Ezáltal a labirintus elég könnyen generálható egy egyszeru algoritmussal. Az algoritmust a játék ismertetése után mutatom be - 55 - WAP alapú alkalmazás fejlesztése VIII. A játék dokumentálása A JÁTÉ K DO KUMENT ÁLÁSA A játékot Java nyelven készítettem el szervletek, valamint JSP oldalak formájában Windows 98 környezet alatt. A játékot egy labirintuswar nevu állomány tartalmazza Az állomány egy JAR állomány, melyet a muködtetéséhez a
tomcat/webapps könyvtárba kell másolni, majd a Tomcat elindítása után annak tartalma automatikusan kitömörítodik egy Labirintus könyvtárba. A játékosok adatait tartalmazó adatbázis egy Microsoft Access adatbázis, melyhez a hozzáférés Microsoft ODBC meghajtón keresztül történik. (Az adatbázis neve: DATA.MDB, eredetileg a database könyvtárban van) A labirintus egy bináris állomány mely egy 100x100-as méretben sorfolytonosan tartalmazza a labirintus kétdimenziós térképét. A falak jelenlétét 1-es értéku bájt, az utakat pedig 2-es értéku bájt jelzi. Az állomány elején van egy 2 bájtos fejléc, mely a labirintus méretét (hossza és szélessége 1-1 bájtban) tartalmazza. A DATA.MDB adatbázis a következo szerkezettel rendelkezik: 3 db táblát tartalmaz: fegyver A támadóero növelését elvégzo tárgyak pozícióját tartalmazza jatekosok A játékosok adatai pancel A védelmi szint növelését elvégzo tárgyak pozícióját
tartalmazza Az egyes táblák szerkezete: (a kiemelt mezok az elsodleges kulcsot jelölik) fegyver id x y bentvan szám szám szám logikai jatekosok azonosito nev password palya bentvan poziciox pozicioy nezet mehet terkep ero vedelem pont frissites halott szám szöveg szöveg szám logikai szám szám szám logikai szám szám szám szám szám logikai pancel id x y bentvan szám szám szám logikai A mezok feladata: fegyver id x,y bentvan azonosít fegyver helye a fegyver bentvan-e jatekosok pancel azonosito nev azonosít játékos neve id x,y password jelszava bentvan palya bentvan poziciox pozicioy nezet mehet terkep ero melyik pályán tart a játékos bentvan-e a játékos helye a játékos helye merre néz fut-e a játékos van-e térképe harci szintje - 56 - azonosít pancel helye a páncél bentvan-e WAP alapú alkalmazás fejlesztése A játék dokumentálása vedelem pont frissites halott védelmi szintje pontszáma milyen gyorsan frissít
meghalt-e ODBC meghajtó hozzárendelése az adatbázishoz: A DATA.MDB állományt be kell másolni egy könyvtárba, el kell indítani a Windows 32bit ODBC programját a Vezérlopultból. Itt létre kell hozni egy User DSN-t, a következo adatokkal: a meghajtó: Microsoft Access Driver (*.mdb) Select gombot megnyomva ki kell választani a DATA.MDB állományt a Data Source Name: mezobe kell beírni az adatbázisra való hivatkozási nevet. Ugyanerre a névre kell kicserélni az ODBC paraméterének értékét a web.xml állományban (Az adatbázis Access 97-el lett létrehozva, így a gépen fent kell lennie a megfelelo meghajtónak, hogy az állományt kezelni tudja az operációs rendszer.) A játék Jakarta-Tomcat webszerver alatt lett tesztelve. A szervletek megfelelo muködéséhez szükséges hogy az alkalmazást tartalmazó labirintus.war állományt a Tomcat tomcatwebapps könyvtárába másoljuk, ahol a tomcat a JakartaTomcat webszerver helyét jelöli. A war állományt
eredetileg a következo paranccsal hoztam létre: jar cvf labirintus.war -C labirintus Az állomány felépítése: 1 Java Source A szervlet forrását tartalmazza 1 wbmp A szervlet számára tartalmazza a game.wbmp állományt 1 WEB-INF Tartalmazza a web.xml állományt, valamint a classes könyvtár a lefordított szervleteket, valamint labirint.class és wbmpclass osztályokat Ide kell még másolni a JSP oldalak által használt lab.class és jspwbmpclass osztályok 1 update Tartalmazza azokat az alkalmazásokat, melyek segítségével új labirintust lehet generáltatni, valamint az adatbázis adatait módosítani. 1 database Tartalmazza a DATA.MDB állományt 1 data Tartalmazza a level1.dat és az enemy2pic állományokat 1 WMLSample Tartalmazza a WML nyelv és a WMLScript nyelv bemutatása után elkészített számológép alkalmazást. (szamologepwml és szamolwmls) q JSP oldalak A web.xml állomány A web.xml állományra azért van szükség, mert itt lehet megadni, hogy
milyen paraméterei legyenek egy alkalmazásnak, illetve a szervleteknek. Itt adom meg, hogy milyen ODBC névvel hivatkozunk az adatbázisra, valamint azt a könyvtárat, ahonnan a szervletek és a JSP oldalak vehetik a labirintust tartalmazó állományt. <web-app> <context-param> <param-name>application</param-name> <param-value>labirintus</param-value> </context-param> <context-param> <param-name>ODBC</param-name> <param-value>database</param-value> </context-param> <context-param> <param-name>wbmpdir</param-name> <param-value>/labirintus/wbmp</param-value> - 57 - WAP alapú alkalmazás fejlesztése A játék dokumentálása </context-param> </web-app> A web.xml állomány tartalmazza a szervletek paramétereit XML szeru leírási módban Az egyes címkék jelentése: web-app elem Ez az elem tartalmazza a web alkalmazások (szervletek) számára szükséges
információkat. context-param Megadható az alkalmazás számára szükséges paraméterek. Tartalmaz: – param-name – param-value servlet elem Ez különíti el az egyes szervletek paramétereit. tartalmazhat: – servlet-name – servlet-class – init-param elemeket servlet-name elem Itt lehet megadni a szervlet nevét servlet-class Itt kell megadni a szervletet tartalmazó class állományt init-param Itt kell megadni az egyes iniciális paramétereket a szervlet számára. Tartalmaznia kell egy paramname és egy param-value elemet param-name: megadja a paraméter azonosítóját param-value: megadja a paraméter értékét Az egyes szervleteknek a következo paraméterekre van szükségük: game ODBC database application labirintus create regisztralas fight ODBC database ODBC database ODBC database application labirintus application labirintus labirintgame wbmpdir /labirintus/wbmp application labirintus application beleptet ODBC database application labirintus frissites
labirintus ODBC ODBC application kilepes database labirintus rekordok databasse Mivel a JSP oldalak számára is szükségesek ezek a paraméterek, ezért a paramétereket nem a szervletekhez rendeltem hozzá a servlet részekben, hanem a context-param részbe raktam be oket. A wbmpdir egy webhelyet azonosít, mely azt mondja meg, hogy hol található a game.wbmp állomány, mely a játék kezdoképernyojén levo képet tartalmazza. A /labirintus/wbmp a tomcatwebappslabirintuswbmp könyvtárra hivatkozik, ahol a tomcatwebapps a webszerver alkalmazásainak gyökérkönyvtárát jelöli. Itt található többek között a ROOT és az admin könyvtár is, valamint ide kell másolni a labirintus.war állományt. A Tomcat elindítása után a szerver maga kitömöríti a labirintuswar állományt, és létrehozza a labirintus könyvtárat! A szervletek a következo utasítások segítségével férhetnek hozzá a paraméterekhez: (A szervlet init metódusába helyeztem el ezeket a
lekérdezo utasításokat) ServletContext context= getServletContext(); - 58 - WAP alapú alkalmazás fejlesztése A játék dokumentálása String ODBC String appl String wbmp = context.getInitParameter("ODBC"); = context.getInitParameter("application"); = context.getInitParameter("wbmpdir"); String directory = context.getRealPath( "/data" ); A context változó egy ServletContext típusú változó, mely segítségével információkat lehet lekérdezni a szervletrol. Létezik neki két fontos metódusa Az egyik a getInitParameter(""), a másik pedig a getRealPath(""). Mindkét metódus paraméterként egy String-et vár, és egy String-et ad vissza A getInitParameter("") segítségével lehet lekérdezni az alkalmazás iniciális paramétereit. Ezeket a paramétereket a Tomcat esetében a web.xml <context-param> szekciójában kell elhelyezni A getRealPath() segítségével a paraméterként
megadott relatív elérési út abszolút elérési útját adja vissza. Tehát ha például getRealPath("/data") visszatérési értéke lehet: c: omcatwebappslabirintusdata A directory paraméter mutatja meg a szervletek számára, hogy a labirintust tartalmazó level1.dat állomány, valamint az enemy2.pic állomány hol helyezkedik el. A szervletekben alkalmazott context.getRealPath("/data") függvény visszaadja a tomcat-be kitömörített labirintuswar-ban levo data könyvtár valódi elérési útját. Ezáltal az iniciális paraméterek közé nem kell felvenni ezt a könyvtárat Fontos, hogy létezzen a labirintus könyvtárban a data könyvtár. A JSP oldalak esetében a context változó helyett a "beépített" ServletContext típusú application változó használható, mely tartalmazza ezeket a metódusokat. Az "application" nevu iniciális paraméter azt mondja meg, hogy a játék milyen relatív elérési út segítségével
érheto el. Az alapesetben labirintus értéku, mivel a Tomcat a következoképpen muködik: Ha a tomcat/webapps könyvtárban talál egy .war kiterjesztésu állományt, akkor egy ugyan olyan nevu könyvtárba tömöríti ki, – mely jelen esetben labirintus, – és a szerver relatív elérési útjai közé ugyanilyen néven felveszi. A könyvtár tartalmát tehát a http://host/labirintus teljes, vagy a /labirintus relatív hivatkozással lehet elérni. A játék elindítása a http://host/labirintus/servlet/labirintgame hivatkozással történhet, ahol a host annak a gépnek az azonosítója, ahol a játék fel van telepítve. A játék a következo Java állományokat tartalmazza: labirintgame.java beleptet.java create.java fight.java frissites.java game.java kilepes.java labirint.java regisztralas.java wbmp.java rekordok.java A játék kezdo lapjait generálja le. (szervlet à WML) A játékos beléptetését végzi el. Itt történik a név és jelszó ellenorzése (szervlet
à WML). A kimenete egy WBMP kép. Itt történik a 3D-s labirintus és a térkép kirajzolása A harc adminisztrálása. (szervlet à WML) A frissítés adminisztrálását végzi el (szervlet à WML). A játékot tartalmazó kártyát készíti el (szervlet à WML). A kilépés adminisztrálása (szervlet à WML) Egy adatszerkezet a labirintus kezelésére A játékos regisztrálásának adminisztrálása (szervlet à WML) A WBMP adatszerkezet létrehozásához szükséges eljárásokat tartalmazza. A játék legjobb 10 játékosát tartalmazó kártyát készíti el. - 59 - WAP alapú alkalmazás fejlesztése A játék dokumentálása A szervletek és programok egymáshoz kapcsolódása: labirintgame.java beleptet.java hivatkozik rá (URL-ként): rekordok.java regisztralas.java game.java create.java labirint.java kilepes.java tartalmazza: frissites.java wbmp.java fight.java VIII1. WBMP.JAVA A következo adatszerkezete van: A 3D-s labirintust valamint a térképet
tartalmazza (96x41-es) Minden egyes int data[][] pozíció egy-egy pixele a képnek int enemydata[][] Az ellenség képét tartalmazza. Ebbe rakja be az enemy2pic állományt int length A generált kép szélessége int width A generált kép magassága labirint labirintus A labirintus adatai a falak kirajzolásához int level Melyik szintet kell kirajzolni int nez Merre néz a játékos A WBMP osztály a következo metódusokat tartalmazza: clearpoint(x,y) Az x,y pozíción a pixel színét háttérszínure állítja a data[][]-ban getpoint(x,y) Lekérdezi az x,y pozíción levo pixel színét a data[][]-ból clear() Kitörli a teljes data[][] kép tartalmát circle(mx,my,r) Egy kört rajzol a data[][]-ba Egy length hosszú vízszintes vonal rajzolása az x,y kezdoponttól a HorLine(x,y,length) data[][]-ba HorLine2(x,y,length) Egy length hosszú szaggatott vízszintes vonal rajzolása. VertLine(x,y,length) Egy length hosszú függoleges vonal rajzolása x,y kezdoponttól
VertLine2(x,y,length) Egy length hosszú szaggatott függoleges vonal rajzolása line(x1,y1,x2,y2) Az x1,y1 és x2,y2 pixelek közé egy egyenes vonal rajzolása Besatírozza a labirintus baloldali falainak oldalát. Az x1,y1 a besatírozandó rész kezdopontja, az x2,y2 az x1,y1 pont szomszédja, filllines1(x1,y1,x2,y2,length) mely megadja, hogy milyen magas legyen a kitöltés. A kitöltés folyamatosan csökkeno méretu vonalakkal történik a VertLine2 metódust használva. Besatírozza a labirintus jobboldali falainak oldalát. Az x1,y1 a besatírozandó rész kezdopontja, az x2,y2 az x1,y1 pont szomszédja, filllines2(x1,y1,x2,y2,length) mely megadja, hogy milyen magas legyen a kitöltés. A kitöltés folyamatosan növekvo méretu vonalakkal történik a VertLine2 metódust használva. A két csúcspont közé (a,b és c,d) egy téglalap rajzolása a HorLine rectangle(a,b,c,d) illetve VertLine metódus használatával. A két csúcspont közé (a,b és c,d) egy téglalap
rajzolása a HorLine2 rectangle2(a,b,c,d) illetve VertLine2 metódus használatával. - 60 - WAP alapú alkalmazás fejlesztése flush(out) save(name) putforwall() putforwall2() putwall(x,y) getenemy(name) putenemy(x,y) A játék dokumentálása Az out által megadott kimenetre írja a kép tartalmát. A kép tartalmát menti ki a name nevu állományba, mely WBMP formátumú lesz. A 3D-s labirintusban egy fal kirajzolása akkor, ha a játékos nem mehet elore, mert közvetlenül elotte fal van. A 3D-s labirintusban egy fal kirajzolása akkor, ha a játékos még elore mehet, de utána már nem, mert 2-vel elotte fal van. A baloldali illetve jobboldali falak megrajzolása annak megfeleloen, hogy a játékos merre néz. Használja a filllines1 és filllines2 metódusokat. Az ellenség képét tartalmazó állomány (enemy2.pic jelen esetben) beolvasása az enemydata mátrixba. Az ellenség kirajzolása az x,y pozícióba, ahol x,y a kirajzolandó kép bal felso sarkát jelenti. A
kirajzolás a data[][] mátrixba történik A következo konstruktorokat tartalmazza az osztály: A directory helyen található level1.dat betöltése a labirint adattagba wbmp(directory) A kép 96x41-es méretre állítása. level=1 és nez=1 lesz wbmp() Nem tölt be labirintust, csak egy 96x41-es képet inicializál A directory-ban levo ”level”+level+”.dat” (level=1 esetén level1dat) wbmp(directory,level,nez) betöltése a labirint-ba és a nézetet, illetve a level-t a megfelelo értékre állítja Az osztályt általában a harmadik konstruktorral inicializálom. A 96x41-es méretu játékban megjeleno kép a következoképpen néz ki: A játékos pozícióját, és azt jelzi, hogy merre néz A labirintusban levo tárgyak illetve a többi játékos így jelenik meg a térképen A támadó ero és a védelmi szint nagysága falak utak A labirintus 3D-s megjelenítése. A besatírozott rész a falakat jelzik. A játékos ezen a helyen áll. Ha elotte áll egy ellenség,
akkor megjelenik annak a képe itt. A képe csak akkor jelenik meg, ha közvetlenül elotte áll, ha azonos pozícióban vannak, akkor nem! az ellenség képe A térkép és az ero illetve védelmi szintek kirajzolását nem ez az osztály végzi, hanem a create.java, mely azonban ezt az osztályt használja a WBMP kimenetének eloállítására. Ez a Nokia WapToolkit 1.2-ben Nokia 6150-es telefonon a következoképpen néz ki: Az ellenséggel pedig: - 61 - WAP alapú alkalmazás fejlesztése A játék dokumentálása Az egyes csúcspontok pozíciója a következo: 0,0 61,0 10,10 64,0 89,0 64,25 89,25 51,9 16,16 44,16 16,24 10,31 0,40 44,24 70,29 90,32 51,31 61,40 90,37 70,34 Ezeknek a koordinátáknak a segítségével történik meg az egyes eljárások meghívása. (A térkép és a szintek kirajzolása nem itt történik meg, azonban a késobbiek miatt az oda szükséges koordinátákat is itt tüntettem fel.) Az osztály forráskódja: import java.io*;
import java.math*; import java.lang*; import java.util*; public class wbmp { int data[][]; int enemydata[][]; int length; int width; labirint labirintus; int level; int nez; wbmp(String directory) { data=new int[96][41]; length=96; width=41;level =1; nez=1; labirintus = new labirint(directory+"/level1.dat"); } wbmp() { data = new int[96][41]; length = 96; width = 41; level = 1; nez = 1; labirintus=null; } wbmp(String directory, int level , int nez ) { data=new int[96][41]; length=96; width=41; level=level ; nez=nez ; labirintus = new labirint(directory+"/level"+level +".dat"); } void setPoint(int x, int y) { data[x][y] = 0; } void clearPoint(int x,int y) { data[x][y] = 1;} int getPoint(int x,int y){ return data[x][y];} void clear() { for(int i= 0;i<length;i++) for(int j = 0;j<width;j++) data[i][j]=1; } void circle(int mx,int my,int r) { double pi=3.14159; double i=0;double xx;double yy; while (i<2*pi) { xx=mx+r*Math.cos(i); yy=my+r*Math.sin(i);
setPoint((int)xx,(int)yy); i=i+0.1; } } - 62 - WAP alapú alkalmazás fejlesztése void void void void A játék dokumentálása HorLine(int x,int y,int length) { for (int i =0;i<length+1;i++) setPoint(x+i,y);} HorLine2(int x,int y,int length) { for (int i=0;i<length;i=i+2) setPoint(x+i,y); } VertLine(int x,int y,int length) { for (int i=0;i<length;i++) setPoint(x,y+i); } VertLine2(int x,int y,int length) { for (int i=0;i<length;i=i+2) setPoint(x,y+i); } void line(int x1,int y1,int x2,int y2) { double sinalpha=(y2-y1)/(x2-x1);double b; double a=x1; while (a<x2) { b=(a-x1)*sinalpha+y1; setPoint((int)a,(int)b); a=a+1; } } void filllines1(int x1,int y1,int x2,int y2,int length) { int b1; int b2; int i; i=0; while (i<length) { b1=y1+i;; VertLine2(x1+i,b1,y2-y1-2*i);i=i+2; } } void filllines2(int x1,int y1,int x2,int y2,int length) { int b1; int b2; int i; i=0; while (i<length) { b1=y1-i;; VertLine2(x1+i,b1,y2-y1+2*i);i=i+2; } } void rectangle(int a,int b,int
c,int d) { int t; if (a>c) { t=a;a=c;c=t;} if (b>d) { t=b;b=d;d=t;} int length=c-a; int height=d-b; HorLine(a,b,length); HorLine(a,d,length); VertLine(a,b,height); VertLine(c,b,height); } void rectangle2(int a,int b,int c,int d) { int t; if (a>c) { t=a;a=c;c=t;} if (b>d) { t=b;b=d;d=t;} int length=c-a; int height=d-b; HorLine2(a,b,length); HorLine2(a,d,length); VertLine2(a,b,height); VertLine2(c,b,height); } void flush(ByteArrayOutputStream out) { int x;int y;int i;int j;int c;int b; c=0; try { out.write(0); out.write(0); out.write(length); out.write(width); y = 0; x = 0; while (y < width) { b = 0; for (i=1;i<9;i++) { b = b * 2 + data[x][y]; x = x + 1; } if (x >= length + c) { x = 0; y = y + 1; - 63 - WAP alapú alkalmazás fejlesztése A játék dokumentálása } out.write(b); } } catch (Exception e) { } } void save(String name) { int x;int y;int i;int j;int c;int b; c=0; OutputStream output =null; try { output=new FileOutputStream(name); } catch
(IOException e) { } try { output.write(0); output.write(0); output.write(length); output.write(width); y = 0; x = 0; while (y < width) { b = 0; for (i=1;i<9;i++) { b = b * 2 + data[x][y]; x = x + 1; } if (x >= length + c) { x = 0; y = y + 1; } output.write(b); } } catch (Exception e) { } try { output.close(); } catch (Exception e) {} } void putforwall() {int a=10; int b=10; int i=0; while (b<30) {HorLine2(a+i,b,40);b=b+2;} void putforwall2(){ int a=17; int b=17; while (b<24){HorLine2(a,b,28);b=b+2;} } void putwall(int x,int y) { if (nez==1) { if (labirintus.getxy(x+1,y) ==1) filllines1( 0, 0, 0,40,9); if (labirintus.getxy(x+1,y+1)==1) filllines1(10,10,10,31,7); if (labirintus.getxy(x-1,y) ==1) filllines2(51, 9,51,31,9); if (labirintus.getxy(x-1,y+1)==1) filllines2(44,16,44,24,7); } if (nez==2) { if (labirintus.getxy(x,y-1) ==1) filllines1( 0, 0, 0,40,9); if (labirintus.getxy(x+1,y-1)==1) filllines1(10,10,10,31,7); if (labirintus.getxy(x,y+1) ==1) filllines2(51,
9,51,31,9); if (labirintus.getxy(x+1,y+1)==1) filllines2(44,16,44,24,7); } if (nez==3) { if (labirintus.getxy(x-1,y) ==1) filllines1( 0, 0, 0,40,9); if (labirintus.getxy(x-1,y-1)==1) filllines1(10,10,10,31,7); if (labirintus.getxy(x+1,y) ==1) filllines2(51, 9,51,31,9); if (labirintus.getxy(x+1,y-1)==1) filllines2(44,16,44,24,7); } if (nez==4) { if (labirintus.getxy(x,y+1) ==1) filllines1( 0, 0,0 ,40,9); if (labirintus.getxy(x-1,y+1)==1) filllines1(10,10,10,31,7); if (labirintus.getxy(x,y-1) ==1) filllines2(51, 9,51,31,9); if (labirintus.getxy(x-1,y-1)==1) filllines2(44,16,44,24,7); } } void getenemy(String name) { enemydata=new int[17][28]; int height = 28; int width=17; int x,y; int c; - 64 - } WAP alapú alkalmazás fejlesztése A játék dokumentálása InputStream input =null; try { input=new FileInputStream(name); } catch (IOException e) {} try { y = 0; x = 0; while ((c=input.read())!=-1) { if (x>width-1) {x=0;y++;} enemydata[x][y]=c; x++; } } catch (Exception e) { }
try {input.close(); } catch (Exception e) {} } void putenemy (int x,int y) { int height = 28; int width=17; int posx,posy; for (int i=0;i<width;i++) { posx=x+i; for (int j=0;j<height;j++) { posy=y+j; if (enemydata[i][j]==48) {setPoint(posx,posy);} else if (enemydata[i][j]==50) {clearPoint(posx,posy);} } } } void putwindow( int x, int y) { int x ,y ,y ,x ; rectangle(0,0,60,40); x =x; y =y; x =x ; y =y; if (nez==1) { x =x ; y =y+1 ; x =x ; y =y+2;} if (nez==2) { x =x+1 ; y =y ; x =x+2 ; y =y;} if (nez==3) { x =x ; y =y-1 ; x =x ; y =y-2;} if (nez==4) { x =x-1 ; y =y ; x =x-2 ; y =y;} rectangle(10,10,50,30); if (labirintus.getxy(x ,y )==1) { putforwall(); } else { if (y<labirintus.width-1 && labirintusgetxy(x ,y )==1) putforwall2(); rectangle(16,16,44,24); } if (labirintus.getxy(x ,y )!=1) { line(9,9,16,16); line(44,16,51,9); line(44,24,51,31); line(9,31,16,24); } line(0,0,10,10); line(51,9,60,0); line(51,31,60,40); line(0,40,10,30); } } A következo
program a szervletnek megfelelo jspwbmp osztály, melyet a JSP oldalak bean-ként használnak. Az osztály tartalmaz az elozoeken kívül egy setwbmp metódust, – mely argumentumként megkapja a labirintust tartalmazó „level1.dat” állomány elérési útvonalát – valamint további metódusokat az adattagokhoz való hozzáféréshez (getxxx néven). import import import import java.io*; java.math*; java.lang*; java.util*; public class jspwbmp { private int data[][]; private int enemydata[][]; private int length; private int width; - 65 - WAP alapú alkalmazás fejlesztése A játék dokumentálása private Lab labirintus; private int level; private int nez; public int getdata(int i,int j) { return data[i][j]; } public int getenemydata(int i,int j) { return enemydata[i][j]; } public int getlength() { return length; } public int getwidth() { return width; } public int getlevel() { return level; } public int getnez() { return nez; } public Lab getlabirintus() { return
labirintus; } public void setwbmp(String files) { data=new int[96][41]; length=96; width=41;level =1; nez=1; labirintus = new Lab(); labirintus.setlabirint(files); } public jspwbmp() { data = new int[96][41]; length = 96; width = 41; level = 1; nez = 1; labirintus=null; } public void setwbmp(String files, int level , int nez ) { data=new int[96][41]; length=96; width=41; level=level ; nez=nez ; labirintus = new Lab(); labirintus.setlabirint(files); } public void setPoint(int x, int y) { data[x][y] = 0; } public void clearPoint(int x,int y) { data[x][y] = 1;} public int getPoint(int x,int y){ return data[x][y];} public void clear() { for(int i= 0;i<length;i++) for(int j = 0;j<width;j++) data[i][j]=1; } public void circle(int mx,int my,int r) { double pi=3.14159; double i=0;double xx;double yy; while (i<2*pi) { xx=mx+r*Math.cos(i); yy=my+r*Math.sin(i); setPoint((int)xx,(int)yy); i=i+0.1; } } public public public public void void void void HorLine(int x,int y,int length) {for
(int i=0;i<length+1;i++) setPoint(x+i,y);} HorLine2(int x,int y,int length) {for(int i=0;i<length;i=i+2) setPoint(x+i,y);} VertLine(int x,int y,int length) {for (int i=0;i<length;i++) setPoint(x,y+i);} VertLine2(int x,int y,int length) {for(int i=0;i<length;i=i+2)setPoint(x,y+i);} public void line(int x1,int y1,int x2,int y2) { double sinalpha=(y2-y1)/(x2-x1);double b; double a=x1; while (a<x2) { b=(a-x1)*sinalpha+y1; setPoint((int)a,(int)b); a=a+1; } } public void filllines1(int x1,int y1,int x2,int y2,int length) { int b1; int b2; int i; i=0; while (i<length) { b1=y1+i;; VertLine2(x1+i,b1,y2-y1-2*i);i=i+2; } - 66 - WAP alapú alkalmazás fejlesztése A játék dokumentálása } public void filllines2(int x1,int y1,int x2,int y2,int length) { int b1; int b2; int i; i=0; while (i<length) { b1=y1-i;; VertLine2(x1+i,b1,y2-y1+2*i);i=i+2; } } public void rectangle(int a,int b,int c,int d) { int t; if (a>c) { t=a;a=c;c=t;} if (b>d) { t=b;b=d;d=t;} int
length=c-a; int height=d-b; HorLine(a,b,length); HorLine(a,d,length); VertLine(a,b,height); VertLine(c,b,height); } public void rectangle2(int a,int b,int c,int d) { int t; if (a>c) { t=a;a=c;c=t;} if (b>d) { t=b;b=d;d=t;} int length=c-a; int height=d-b; HorLine2(a,b,length); HorLine2(a,d,length); VertLine2(a,b,height); VertLine2(c,b,height); } public void flush(ByteArrayOutputStream out) { int x;int y;int i;int j;int c;int b; c=0; try { out.write(0); out.write(0); out.write(length); out.write(width); y = 0; x = 0; while (y < width) { b = 0; for (i=1;i<9;i++) { b = b * 2 + data[x][y]; x = x + 1; } if (x >= length + c) { x = 0; y = y + 1; } out.write(b); } } catch (Exception e) { } } public void save(String name) { int x;int y;int i;int j;int c;int b; c=0; OutputStream output =null; try { output=new FileOutputStream(name); } catch (IOException e) { } try { output.write(0); output.write(0); output.write(length); output.write(width); y = 0; x = 0; while (y < width) { b =
0; - 67 - WAP alapú alkalmazás fejlesztése A játék dokumentálása for (i=1;i<9;i++) { b = b * 2 + data[x][y]; x = x + 1; } if (x >= length + c) { x = 0; y = y + 1; } output.write(b); } } catch (Exception e) { } try { output.close(); } catch (Exception e) {} } public void putforwall() {int a=10;int b=10;int i=0;while (b<30) { HorLine2(a+i,b,40);b=b+2;}} public void putforwall2(){ int a=17; int b=17; public void putwall(int x,int y) { while (b<24){HorLine2(a,b,28);b=b+2;} } if (nez==1) { if (labirintus.getxy(x+1,y) ==1) filllines1( 0, 0, 0,40,9); if (labirintus.getxy(x+1,y+1)==1) filllines1(10,10,10,31,7); if (labirintus.getxy(x-1,y) ==1) filllines2(51, 9,51,31,9); if (labirintus.getxy(x-1,y+1)==1) filllines2(44,16,44,24,7); } if (nez==2) { if (labirintus.getxy(x,y-1) ==1) filllines1( 0, 0, 0,40,9); if (labirintus.getxy(x+1,y-1)==1) filllines1(10,10,10,31,7); if (labirintus.getxy(x,y+1) ==1) filllines2(51, 9,51,31,9); if (labirintus.getxy(x+1,y+1)==1)
filllines2(44,16,44,24,7); } if (nez==3) { if (labirintus.getxy(x-1,y) ==1) filllines1( 0, 0, 0,40,9); if (labirintus.getxy(x-1,y-1)==1) filllines1(10,10,10,31,7); if (labirintus.getxy(x+1,y) ==1) filllines2(51, 9,51,31,9); if (labirintus.getxy(x+1,y-1)==1) filllines2(44,16,44,24,7); } if (nez==4) { if (labirintus.getxy(x,y+1) ==1) filllines1( 0, 0,0 ,40,9); if (labirintus.getxy(x-1,y+1)==1) filllines1(10,10,10,31,7); if (labirintus.getxy(x,y-1) ==1) filllines2(51, 9,51,31,9); if (labirintus.getxy(x-1,y-1)==1) filllines2(44,16,44,24,7); } } public void getenemy(String name) { enemydata=new int[17][28]; int height = 28; int width=17; int x,y; int c; InputStream input =null; try { input=new FileInputStream(name); } catch (IOException e) {} try { y = 0; x = 0; while ((c=input.read())!=-1) { if (x>width-1) {x=0;y++;} enemydata[x][y]=c; x++; } } catch (Exception e) { } try {input.close(); } catch (Exception e) {} } public void putenemy (int x,int y) { int height = 28; int width=17; int
posx,posy; for (int i=0;i<width;i++) { posx=x+i; for (int j=0;j<height;j++) { posy=y+j; - 68 - WAP alapú alkalmazás fejlesztése A játék dokumentálása if (enemydata[i][j]==48) {setPoint(posx,posy);} else if (enemydata[i][j]==50) {clearPoint(posx,posy);} } } } public void putwindow( int x, int y) { int x ,y ,y ,x ; rectangle(0,0,60,40); x =x; y =y; x =x ; y =y; if (nez==1) { x =x ; y =y+1 ; x =x ; y =y+2;} if (nez==2) { x =x+1 ; y =y ; x =x+2 ; y =y;} if (nez==3) { x =x ; y =y-1 ; x =x ; y =y-2;} if (nez==4) { x =x-1 ; y =y ; x =x-2 ; y =y;} rectangle(10,10,50,30); if (labirintus.getxy(x ,y )==1) { putforwall(); } else { if (y<labirintus.getwidth()-1 && labirintusgetxy(x ,y )==1) putforwall2(); rectangle(16,16,44,24); } if (labirintus.getxy(x ,y )!=1) { line(9,9,16,16); line(44,16,51,9); line(44,24,51,31); line(9,31,16,24); } line(0,0,10,10); line(51,9,60,0); line(51,31,60,40); line(0,40,10,30); } } VIII2. LABIRINT.JAVA A labirint.java
osztály tartalmazza a labirintus adatait, azaz a 100x100-as méretu pályát A következo adatszerkezete van: A labirintust tartalmazó mátrix. A következo lehet a cellák tartalma: int data[][] data[i][j]=1 à fal data[i][j]=2 à út szerepel az adott pozícióban Az utak koordinátáit tartalmazza. Erre azért van szükség, mert a játékosok int uresx[] elhelyezése a regisztrálás után – valamint ha meghalnak, akkor azután – e tömb int uresy[] adatai alapján történik. Az uresx[i] és az uresy[i] adja meg az i út koordinátáját int uresek Az utak száma int length, int width A labirintus dimenziója A pálya vége, ezen a helyen lehet a következo pályára átmenni. Jelenleg ezt nem int endx, int endy használja a program, a késobbi fejlesztésekre van fenntartva. Értékét a labirintust tartalmazó állományból veszi a program. A játékos kezdopozíciója. Jelenleg nem használja a program, mivel az elején a int startx, int starty játékos egy véletlen
helyre kerül a labirintusba. Értékét a labirintust tartalmazó állományból veszi a program. A labirint.java osztály a következo metódusokat tartalmazza: int getxy(x,y) A labirintus x,y pozíciójának lekérdezése int getrandomx(sorsz) A sorsz.-adik út x koordinátáját adja vissza int getrandomy(sorsz) A sorsz.-adik út x koordinátáját adja vissza - 69 - WAP alapú alkalmazás fejlesztése A játék dokumentálása A következo konstruktorokat tartalmazza az osztály: Beolvassa a name változó által tartalmazott adatfájlt, mely tartalmazza a labirintus adatait. Az elso két bájt tartalmazza a labirintus méretét (length = 1 bájt, width = 1 bájt), a többi bájt pedig sorfolytonosan tartalmazza a labirintust. Az olvasott bájtok jelentése: 1: fal labirint(name) 2: út 3: kezdo pozíció (startx, starty beállítása) 4: cél pozíció (endx,endy beállítása) A labirintus jelentleg nem tartalmaz ilyen mezot. A késobbiekben használható a labirintusból
való kijárat megtalálására. labirint.java forráskódja: import java.io*; import java.math*; import java.lang*; import java.util*; public class labirint { int data[][]; int uresx[]; int uresy[]; int uresek; int length; int width; int endx; int endy; int startx; int starty; public int getxy(int x,int y) { if (x<0 || x>=length || y<0 || y>=width) return 1; else return data[x][y]; } labirint(String name) { int x;int y;int c; InputStream input =null; try {input=new FileInputStream(name);} catch (IOException e) { System.outprintln(e);} try { y = 0; x = 0; length=input.read(); width=input.read(); data=new int[length][width]; uresek=0; while ((c=input.read())!=-1) { if (x>length-1) {x=0;y++;} if (c==3) { startx=x; starty=y; c=2;} if (c==4) { endx=x; endy=y; c=4;} data[x][y]=c; if (c==2) {uresek=uresek+1;} x++; } uresx = new int[uresek]; uresy = new int[uresek]; int uresek2=0; for (int i=0;i<length;i++) { for (int j=0;j<width;j++) { if (data[i][j]==2) {
uresx[uresek2]=i; uresy[uresek2]=j; uresek2++; } }} } catch (Exception e) {} try { input.close(); } catch (Exception e) {} } public int getrandomx(int sorsz) { return uresx[sorsz]; } public int getrandomy(int sorsz) { return uresy[sorsz]; } } - 70 - WAP alapú alkalmazás fejlesztése A játék dokumentálása Ennek az osztálynak a JSP források között egy Lab.java osztály felel meg, melyre az egyes JSP oldalak hivatkoznak, illetve bean-ként használják. Ebben az osztályban ugyan azok a metódusok szerepelnek, azonban még tartalmazza az adattagok eléréséhez szükséges metódusokat is (getxxx néven): import java.io*; import java.util*; public class Lab { private int data[][]; private int uresx[]; private int uresy[]; private int uresek; private int length; private int width; private int endx; private int endy; private int startx; private int starty; public public public public public public public public public public int int int int int int int int int int
getdata(int i, int j) { return data[i][j]; } geturesx(int i) { return uresx[i]; } geturesy(int i) { return uresy[i]; } geturesek() { return uresek; } getlength() { return length; } getwidth() { return width; } getendx() { return endx; } getendy() { return endy; } getstartx() { return startx; } getstarty() { return starty; } public Lab() {} public int getxy(int x,int y) { if (x<0 || x>=length || y<0 || y>=width) return 1; else return data[x][y]; } public void setlabirint(String name) { int x;int y;int c; InputStream input =null; try {input=new FileInputStream(name);} catch (IOException e) { System.outprintln(e);} try { y = 0; x = 0; length=input.read(); width=input.read(); data=new int[length][width]; uresek=0; while ((c=input.read())!=-1) { if (x>length-1) {x=0;y++;} if (c==3) { startx=x; starty=y; c=2;} if (c==4) { endx=x; endy=y; c=4;} data[x][y]=c; if (c==2) {uresek=uresek+1;} x++; } uresx = new int[uresek]; uresy = new int[uresek]; int uresek2=0; for (int
i=0;i<length;i++) { for (int j=0;j<width;j++) { if (data[i][j]==2) { uresx[uresek2]=i; uresy[uresek2]=j; uresek2++; } }} } catch (Exception e) {} try { input.close(); } catch (Exception e) {} } public int getrandomx(int sorsz) { return uresx[sorsz]; } - 71 - WAP alapú alkalmazás fejlesztése A játék dokumentálása public int getrandomy(int sorsz) { return uresy[sorsz]; } } A labirint.java és a jspwbmpjava osztályokat a JSP oldalak a következo utasítás segítségével használják: <%@ page import="java.sql*,Lab,java.lang*,java.util*" contentType="text/vnd.wapwml"%> <jsp:useBean id="labirintus" scope="session" class="Lab"/> Ezek után a labirintus nevu változón keresztül hozzá lehet férni a Lab osztály egy példányához. A create.jsp használja a jspwbmp osztályt a következoképpen: <%@ page import="java.sql*,jspwbmp,java.io*" contentType="image/vnd.wapwbmp"%> .
<jsp:useBean id="picture" scope="session" class="jspwbmp"/> Ezek után a JSP oldalban már a picture nevu változón keresztül hozzá lehet férni az osztály egy példányához. FONTOS, hogy a Lab.class és a jspwbmpclass osztályok az alkalmazás WEB-INFclasses könyvtárában legyenek! Ugyanott, ahol a lefordított szervletek is vannak! Most következik a szervletek ismertetése. - 72 - WAP alapú alkalmazás fejlesztése A játék dokumentálása VIII3. LABIRINTGAME.JAVA A labirintgame.java szervlet feladata a játék kezdo oldalának eloállítása A szervlet kimenetül egy WML oldalt ad. A kimeneteket a Nokia Wap Toolkit 1.2-ben levo Nokia 6150-es telefonon megjeleno képeken keresztül fogom majd megmutatni. A kezdo képernyo tartalmaz egy képet, melyet a web-rol tölt le game.wbmp névvel Ennek a képnek a helyét meg kell adni a szervlet inicializáló paraméterei között (a web.xml-ben Tomcat szerver esetében) Ez az oldal
továbbá tartalmaz még 4 darab linket, melyek a következok: • Belépés • Regisztrálás • Játékszabályok • Rekordok Mind a Regisztrálás, mind a Belépés esetében meg kell adni egy nevet és egy jelszót, melyet a program a DATA.MDB adatbázisból vesz, illetve regisztrálás esetében oda ment el FONTOS, hogy nem lehet két azonos nevu játékos az adatbázisban. A Rekordok menü megjeleníti a legjobb 10 játékost. A kezdooldal így néz ki: A kezdooldalt tartalmazó WML oldal további 3 kártyát tartalmaz. Az elso kártya tartalmazza a kezdo oldalt, a többi pedig az egyes linkek aktiválása után jelenik meg. A 4 link aktiválása után már egy másik szervlet – rekordok.class – hívódik meg Belepes Regisztralas Rekordok - 73 - Jatekszabaly WAP alapú alkalmazás fejlesztése A játék dokumentálása A contentType változó tartalmazza, hogy milyen típusú a szervlet kimenete. Ezt a HttpServletResponse setContentType(contentType)
metódusával lehet beállítani. Egy szervlet általános deklarációja a következoképpen néz ki: import javax.servlet*; import javax.servlethttp*; public class labirintgame extends HttpServlet{ String head ="<?xml version="1.0"?> <!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 11//EN" "http://www.wapforumorg/DTD/wml 11xml">"; String contentType = "text/vnd.wapwml"; HttpServletResponse response; ByteArrayOutputStream bytes; String encoding; OutputStreamWriter w; PrintWriter out; String directory; String appl; void init(HttpServletResponse resp) throws ServletException, IOException { response = resp; response.setContentType(contentType); response.setHeader("Cache-Control","no-cache"); ServletContext context = getServletContext(); encoding = response.getCharacterEncoding (); bytes = new ByteArrayOutputStream (8192); w = new OutputStreamWriter (bytes, encoding); out = new PrintWriter (w); directory =
context.getInitParameter( "wbmpdir" ); appl = context.getInitParameter( "application" ); } void close() throws ServletException, IOException{ out.flush (); response.setContentLength (bytessize ()); try {bytes.writeTo (responsegetOutputStream ());} catch (Exception e) {e.printStackTrace ();} } public void doGet ( HttpServletRequest request, HttpServletResponse resp ) throws ServletException, IOException { init(resp); close(); } } } Az init(resp) metódus feladata a HTTP szervlet inicializálása, azaz a kimenet típusának megfelelore állítása. A szervlet a következo változókat tartalmazza: bytes A WML kimenet fejléce A kimeno tartalom típusa: WML esetében: text/vnd.wapwml WBMP esetében: image/wnd.wapwbmp A HTTP szervlet kimenete A kimenetre küldendo információt tartalmazza (maximum 8192 bájt) encoding A HTTP átvitel kódolási mechanizmusát tartalmazza w A bytes és encoding változó segítségével egy kimeneti adatfolyamot definiál out A
kimeneti adatfolyam számára egy olyan adatszerkezet, melyre a szokásos print és println metódusokkal lehet szöveget írni. head contentType response bytes=new ByteArrayOutputStream(8192); encoding=response.getCharacterEncoding(); w=new OutputStreemWriter(bytes,encoding); out=new PrintWriter(w); - 74 - WAP alapú alkalmazás fejlesztése A játék dokumentálása A close() metódus végzi a kimenet átküldését a szerverrol. Ezt két lépésben végzi el Eloször az out-ban levo adatfolyamot átküldi a w változóba az out.flush() metódussal, majd a megfelelo karakterkódolással közvetlenül a bytes változó tartalmát átküldi a HTTP kérést azonosító adatfolyamhoz a bytes.writeTo(responsegetOutputStream()) metódus segítségével A doGet() metódus az, mely a szervlethez érkezo kérés kiszolgálásakor indul el. Ennek a feladata a válasz elküldése a kérelmezo felé. Két fontos eljárást hív meg: az elején az init(resp)-et és az eljárás végén
a close()-t. Ezen két eljárás meghívása között lehet a kimenetre írni az outprint() illetve outprintln() metódusok segítségével. Mivel az init nem tartalmazza a head változó tartalmának kiíratását, így eloször azt kell kiíratni az out.println(head) utasítással! Az init-ben levo response.setHeader() nem tesz mást, mint hogy a kikapcsolja az oldal elozmények közé való felvételét az eszközön, mivel a Cache-Control=”no-cache” üzenet ezt jelzi az eszköz számára. Ez a metódus végzi még el a szervletek iniciális paramétereinek lekérdezését, melyeket a web.xml állományba írtunk be. Ezt a parameter=getInitParameter(”parameternev”) utasítással lehet elvégezni Ez a szervlet 2 iniciális paraméterrel rendelkezik, az application és a wbmpdir. labirintgame.java forráskódja: import import import import java.io*; java.util*; javax.servlet*; javax.servlethttp*; public class labirintgame extends HttpServlet{ String head ="<?xml
version="1.0"?> <!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN" "http://wwwwapforumorg/DTD/wml 11xml">"; String contentType = "text/vnd.wapwml"; HttpServletResponse response; ByteArrayOutputStream bytes; String encoding; OutputStreamWriter w; PrintWriter out; String directory; String appl; void init(HttpServletResponse resp) throws ServletException, IOException { response = resp; response.setContentType(contentType); response.setHeader("Cache-Control","no-cache"); ServletContext context = getServletContext(); encoding = response.getCharacterEncoding (); bytes = new ByteArrayOutputStream (8192); w = new OutputStreamWriter (bytes, encoding); out = new PrintWriter (w); directory = context.getInitParameter( "wbmpdir" ); appl = context.getInitParameter( "application" ); } void close() throws ServletException, IOException{ out.flush (); response.setContentLength (bytessize ()); try
{bytes.writeTo (responsegetOutputStream ());} catch (Exception e) {e.printStackTrace ();} } public void doPost ( HttpServletRequest HttpServletResponse request, resp) throws ServletException, IOException {} public void doGet ( HttpServletRequest request, HttpServletResponse resp ) throws ServletException, IOException { init(resp); out.println(head); out.println("<wml>"); - 75 - WAP alapú alkalmazás fejlesztése A játék dokumentálása out.println("<card id="Main" title="Labirintus">"); out.println("<p align="center">"); out.println("<img alt="labirintgame" src=""+directory+"/gamewbmp" align="bottom" /><br/>"); out.println("<anchor>Belepes<br/>"); out.println(" <go href="#Belepes">"); out.println(" </go>"); out.println("</anchor><br/>");
out.println("<anchor>Regisztralas<br/>"); out.println(" <go href="#Regisztralas">"); out.println(" </go>"); out.println("</anchor><br/>"); out.println("<anchor>Jatekszabaly<br/>"); out.println(" <go href="#instr">"); out.println(" </go>"); out.println("</anchor>"); out.println("<anchor>Rekordok<br/>"); out.println(" <go href="/"+appl+"/servlet/rekordok">"); out.println(" </go>"); out.println("</anchor>"); out.println("</p>"); out.println("</card>"); out.print("<card id="Belepes" title="Belepes a jatekba">"); out.println("<p align="center">"); out.println("Azonositoja:<input type="text" name="nev"/>");
out.println("Jelszava:<input type="password" name="pswd"/>"); out.println("<anchor>Belep<br/>"); out.println("<go href="/"+appl+"/servlet/beleptet" sendreferer="false" method="get ">"); out.println("<postfield name="nev" value="$(nev)"/>"); out.println("<postfield name="password" value="$(pswd)"/>"); out.println("</go>"); out.println("</anchor><br/>"); out.println("<anchor>Megsem<br/>"); out.println("<go href="#Main" sendreferer="false" >"); out.println("</go>"); out.println("</anchor><br/>"); out.println("</p>"); out.println("</card>"); out.print("<card id="Regisztralas" title="Regisztralas">");
out.println("<p align="center">"); out.println("Azonositoja:<input type="text" name="nev"/>"); out.println("Jelszava:<input type="password" name="pswd"/>"); out.println("<anchor>Regisztral<br/>"); out.println("<go href="/"+appl+"/servlet/regisztralas" sendreferer="false" method= "get">"); out.println("<postfield name="nev" value="$(nev)"/>"); out.println("<postfield name="password" value="$(pswd)"/>"); out.println("</go>"); out.println("</anchor><br/>"); out.println("<anchor>Megsem<br/>"); out.println("<go href="#Main" >"); out.println("</go>"); out.println("</anchor><br/>"); out.println("</p>");
out.println("</card>"); out.print("<card id="instr" title="A labirintus">"); out.println("<p align="center">"); out.println("<small>A jatek egy 3D-s labirintusban jatszodik Celja minel tobb pontot osszeszerezni "); out.println("a labirintusban a harcok soran!"); out.println("Miutan regisztralta valaki magat, megjelenik a labirintus es lehet benne - 76 - WAP alapú alkalmazás fejlesztése A játék dokumentálása harcolni."); out.println("A jatekosoknak van ero és vedelem szintjuk, melyek kezdetben 10%-10%-on"); out.println("vannak Ezeket novelni lehet, ha targyakat vesz fel A targyakat a"); out.println("terkepen kis pontok jelzik A pontok jelzik tovabba az ellenfeleket is"); out.println("A targyak felvetele automatikus"); out.println("Osszesen 200-200 targy van "); out.println("Egy targy felszedese utan az
eltunik, es addig nem jelenik meg, "); out.println("amig az osszeset fel nem szedtek "); out.println("Harcolas: a tamadas erejet a tamado ereje adja: annak 10%-a vonodik le"); out.println("a vedekezo vedelmebol, valamint a tamado erejebol a pontozas: a tamado annyi pontot kap,"); out.println("amennyi pontot levont a vedekezo vedelmebol, ha megolte, akkor +20 pontot kap."); out.println("A "frissites" lehetoseget ad arra, hogy a jatekos beallitsa azt"); out.println("hogy milyen gyorsan frissitodjon a kepen"); out.println("a jatek aktualis allasa </small>"); out.println("</p>"); out.println("<do type="prev" label="Vissza">"); out.println("<prev/>"); out.println("</do>"); out.println("</card>"); out.println("</wml>"); close(); } } A szervlet által eloállított WML oldal: <?xml
version="1.0"?> <!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN" "http://wwwwapforumorg/DTD/wml 11xml"> <wml> <card id="Main" title="Labirintus"> <p align="center"> <img alt="labirintgame" src="/wbmp/game.wbmp" align="bottom"/> <br/> <anchor> Belepes <br/> <go href="#Belepes"/> </anchor> <br/> <anchor> Regisztralas <br/> <go href="#Regisztralas"/> </anchor> <br/> <anchor> Jatekszabaly <br/> <go href="#instr"/> </anchor> <anchor> Rekordok <br/> <go href="/labirintus/servlet/rekordok"/> </anchor> </p> </card> <card id="Belepes" title="Belepes a jatekba"> <p align="center"> Azonositoja: <input type="text" name="nev"/> Jelszava:
<input type="password" name="pswd"/> <anchor>Belep<br/> <go href="/labirintus/servlet/beleptet" sendreferer="false" method="get"> <postfield name="nev" value="$(nev:noesc)"/> <postfield name="password" value="$(pswd:noesc)"/> </go></anchor> <br/> - 77 - WAP alapú alkalmazás fejlesztése A játék dokumentálása <anchor>Megsem<br/><go href="#Main" sendreferer="false"/></anchor> <br/> </p> </card> <card id="Regisztralas" title="Regisztralas"> <p align="center"> Azonositoja: <input type="text" name="nev"/> Jelszava: <input type="password" name="pswd"/> <anchor>Regisztral<br/> <go href="/labirintus/servlet/regisztralas" sendreferer="false"
method="get"> <postfield name="nev" value="$(nev:noesc)"/> <postfield name="password" value="$(pswd:noesc)"/> </go></anchor> <br/> <anchor>Megsem<br/><go href="#Main"/></anchor> <br/> </p> </card> <card id="instr" title="A labirintus"> <p align="center"> <small>A jatek egy 3D-s labirintusban jatszodik. Celja minel tobb pontot osszeszerezni a labirintusban a harcok soran! Miutan regisztralta valaki magat, megjelenik a labirintus es lehet benne harcolni. A jatekosoknak van ero es vedelem szintjuk, melyek kezdetben 10%-10%-on vannak. Ezeket novelni lehet, ha targyakat vesz fel A targyakat a terkepen kis pontok jelzik. A pontok jelzik tovabba az ellenfeleket is. A targyak felvetele automatikus Osszesen 200-200 targy van Egy targy felszedese utan az eltunik, es addig nem jelenik meg, amig az osszeset fel nem
szedtek. Harcolas: a tamadas erejet a tamado ereje adja: annak 10%-a vonodik le a vedekezo vedelmebol, valamint a tamado erejebol. a pontozas: a tamado annyi pontot kap, amennyi pontot levont a vedekezo vedelmebol, ha megolte, akkor +20 pontot kap. A "frissites" lehetoseget ad arra, hogy a jatekos beallitsa azt hogy milyen gyorsan frissitodjon a kepen a jatek aktualis allasa. </small> </p> <do type="prev" label="Vissza"> <prev/> </do> </card> </wml> A szervletnek megfelelo JSP oldal: <%@ page contentType="text/vnd.wapwml;charset=ISO-8859-1" %><% String head ="<?xml version="1.0"?> <!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN" "http://wwwwapforumorg/DTD/wml 11xml">"; out.println(head); %> <wml> <card id="Main" title="Labirintus"> <p align="center"> <img
alt="labirintgame" src="game.wbmp" align="bottom"/><br/> <anchor>Belepes<br/> <go href="#Belepes"> </go> </anchor><br/> <anchor>Regisztralas<br/> <go href="#Regisztralas"> </go> </anchor><br/> <anchor>Jatekszabaly<br/> <go href="#instr"> </go> </anchor> <anchor>Rekordok<br/> <go href="rekordok.jsp"> </go> </anchor> </p> </card> - 78 - WAP alapú alkalmazás fejlesztése A játék dokumentálása <card id="Belepes" title="Belepes a jatekba"> <p align="center"> Azonositoja: <input type="text" name="nev"/><br/> Jelszava: <input type="password" name="pswd"/><br/> <anchor>Belep<br/> <go href="beleptet.jsp"
sendreferer="false" method="get"> <postfield name="nev" value="$(nev)"/> <postfield name="password" value="$(pswd)"/> </go> </anchor><br/> <anchor>Megsem<br/> <go href="#Main" sendreferer="false" > </go> </anchor> </p> </card> <card id="Regisztralas" title="Regisztralas"> <p align="center"> Azonositoja: <input type="text" name="nev"/><br/> Jelszava: <input type="password" name="pswd"/><br/> <anchor>Regisztral<br/> <go href="regisztralas.jsp" sendreferer="false" method="get"> <postfield name="nev" value="$(nev)"/> <postfield name="password" value="$(pswd)"/> </go> </anchor><br/>
<anchor>Megsem<br/> <go href="#Main" > </go> </anchor><br/> </p> </card> <card id="instr" title="A labirintus"> <p align="center"> <small>A jatek egy 3D-s labirintusban jatszodik. Celja minel tobb pontot osszeszerezni a labirintusban a harcok soran! Miutan regisztralta valaki magat, megjelenik a labirintus es lehet benne harcolni. A jatekosoknak van ero es vedelem szintjuk, melyek kezdetben 10%-10%-on vannak. Ezeket novelni lehet, ha targyakat vesz fel A targyakat a terkepen kis pontok jelzik. A pontok jelzik tovabba az ellenfeleket is A targyak felvetele automatikus. Osszesen 200-200 targy van Egy targy felszedese utan az eltunik, es addig nem jelenik meg, amig az osszeset fel nem szedtek. Harcolas: a tamadas erejet a tamado ereje adja: annak 10%-a vonodik le a vedekezo vedelmebol, valamint a tamado erejebol. a pontozas: a tamado annyi pontot kap,amennyi pontot levont a vedekezo
vedelmebol, ha megolte, akkor +20 pontot kap. A "frissites" lehetoseget ad arra, hogy a jatekos beallitsa azt hogy milyen gyorsan frissitodjon a kepen a jatek aktualis allasa. </small> </p> <do type="prev" label="Vissza"> <prev/> </do> </card> </wml> VIII4. BELEPTET .JAVA A beleptet.java végzi el a játékosok beléptetésének engedélyezését a DATAMDB adatbázisban levo információk segítségével. Az adatbázis használata Java nyelven JDBC ODBC meghajtóprogram segítségével történik. Eloször a programban az adatbázishoz hozzá kell rendelni egy meghajtóprogramot. Ezt a következo utasítások végzik el: Class.forName("sunjdbcodbcJdbcOdbcDriver"); - 79 - WAP alapú alkalmazás fejlesztése Connection con A játék dokumentálása = DriverManager.getConnection("jdbc:odbc:"+database); A JDBC használathoz importálni kell a java.sql osztályt: import java.sql*; A
database változó tartalmazza az adatbázis ODBC hivatkozási nevét, melyet az alkalmazás iniciális paramétereként kérdezhetünk le. A paraméter lekérdezésére a context.getInitParameter(”parameternev”) eljárás szolgál, ahol a context egy ServletContext objektum, és a getServletContext() metódussal inicializáljuk. Miután létrejött a kapcsolat a JDBC és az adatbázis között lehetoség van az adatbázison lekérdezo és módosító SQL utasítások végrehajtására. Attól függoen, hogy lekérdezni vagy módosítani akarjuk az adatbázist, más adatszerkezetet kell használni. A lekérdezésre a Statement adatszerkezet, a módosításra pedig a PreparedStatement adatszerkezet szolgál. Statement stmt = con.createStatement(); PreparedStatement pstmt = con.prepareStatement(); A lekérdezés eredményét a ResultSet adatszerkezet segítségével tudjuk megvizsgálni a következoképpen: A ResultSet rs = stmt.executeQuery(""); utasítás egy SQL
lekérdezo utasítást indít el A paramétere egy SQL utasítás – általában SELECT –. Az utasítás végrehajtása után az rs adatszerkezet next() metódusa lekérdezi, hogy van-e eredménye a lekérdezésnek. Ha értéke false, akkor a lekérdezés sikertelen volt. Ha van eredménye, akkor az elso eredményre ugrik – mivel a lekérdezés adhat több sort is eredményül –. Ezután a lekérdezett oszlopokhoz az rs adatszerkezet getInt(sorszam), getString(sorszam) vagy getBoolean(sorszam) metódusaival férhetünk hozzá, ahol a sorszám az SELECT eredményeként kapott oszlop megfelelo sorszáma. például: ResultSet rs = stmt.executeQuery(”SELECT nev FROM jatekosok WHERE azonosito=4”); rs.next(); String nev=rs.getString(1); stmt.close(); out.println(nev); Ez a példa a jatekosok táblából lekérdezi annak a játékosnak a nevét, melynek az azonosítója 4, és azt belerakja a nev változóba. A close() metódus megszünteti a kapcsolatot az adatszerkezet és a
meghajtóprogram között. Az adatbázis módosításához a PreparedStatement adatszerkezetet kell használni a következoképpen: PreparedStatement pstmt = con.prepareStatement(""); pstmt.executeUpdate(); pstmt.close(); A prepareStatement metódus paraméterül szintén egy sztringet kaphat, mely valamilyen SQL DML utasítás (pl. UPDATE vagy DELETE) Ez elokészíti az adatbázist a módosítás végrehajtására, melyet az executeUpdate() metódus elindításakor végez el. A close() megszünteti a kapcsolatot az adatszerkezet és a meghajtóprogram között. Ezt érdemes minden egyes módosítás vagy lekérdezés esetében végrehajtani. Az adatbázishoz való hozzáférés megszüntetését a Connection adatszerkezet close() metódusa végzi el. Ez leválasztja az adatszerkezetrol az adatbázist. Ez a szervlet csak egy lekérdezést alkalmaz, mely segítségével le lehet ellenorizni, hogy a játékos által megadott név és jelszó szerepel-e már az adatbázisban.
Azonban még azt is ellenorizni kell, hogy a játékos már be van-e lépve. Ha már szerepel és nincsen belépve, akkor lehetoséget kap a játékos, hogy elkezdje a játékot, ha be van lépve, akkor pedig arra, hogy kilépjen az elozo állásból. Ha nem megfelelo a név és a jelszó, akkor egy figyelmezteto üzenetet kap, hogy regisztrálja magát eloször. Ez a következoképpen történik: A szervlet az ODBCdatabase paraméteren kívül kap még egy nev és egy password nevu paramétert is, melyek a belépni akaró játékos nevét és jelszavát tartalmazzák. Ezeket a szervlet elhelyezi a nev és password változóba: - 80 - WAP alapú alkalmazás fejlesztése A játék dokumentálása String nev = request.getParameter("nev"); String password = request.getParameter("password"); A belépés ellenorzését a következo programrészlet végzi: ResultSet rs = stmt.executeQuery("SELECT password, palya, poziciox, pozicioy, nezet, terkep, mehet,
azonosito,bentvan FROM jatekosok WHERE nev="+nev+""); if (rs.next()) { if (rs.getString(1)equals(password)) { boolean bentvan = rs.getBoolean(9); if (bentvan==false) { MEGFELELO A NÉV ÉS A JELSZÓ ÉS A JÁTÉKOS NINCSEN BELÉPVE } else { MEGFELELO A NÉV ÉS A JELSZÓ, DE MÁR BE VAN LÉPVE } } else { HIBÁS A JELSZÓ } } else { A NÉV NEM SZEREPEL AZ ADATBÁZISBAN } A következoképpen néz ki a generált oldal Nokia 6150-esen a WapToolkit 1.2-ben: Sikeres belépés esetén Sikertelen belépés esetében vagy Sikeres belépés esetében a szervlet az adatbázisból lekérdezi a játékos adatait, hogy azokat el tudja majd küldeni a game.java szervletnek: Statement stmt = con.createStatement(); ResultSet rs = stmt.executeQuery("SELECT password, palya, poziciox, pozicioy, nezet, terkep, mehet, azonosito,bentvan FROM jatekosok WHERE nev="+nev+""); if (rs.next()) { if (rs.getString(1)equals(password)) { int x = rs.getInt(3); int y =
rs.getInt(4); int level = rs.getInt(2); int nezet = rs.getInt(5); int terkep = rs.getInt(6); int mehet = rs.getInt(7); int id = rs.getInt(8); boolean bentvan = rs.getBoolean(9); Ezek után a szervlet forráskódja: import java.sql*; import java.io*; import java.util*; - 81 - WAP alapú alkalmazás fejlesztése A játék dokumentálása import javax.servlet*; import javax.servlethttp*; public class beleptet extends HttpServlet{ String head ="<?xml version="1.0"?> <!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN" "http://wwwwapforumorg/DTD/wml 11xml">"; String contentType = "text/vnd.wapwml"; HttpServletResponse response; ByteArrayOutputStream bytes; String encoding; OutputStreamWriter w; PrintWriter out; String database; String appl; void init(HttpServletResponse resp) throws ServletException, IOException { ServletContext context=getServletContext(); response=resp; response.setContentType(contentType);
response.setHeader("Cache-Control","no-cache"); encoding = response.getCharacterEncoding (); bytes = new ByteArrayOutputStream (8192); w = new OutputStreamWriter (bytes, encoding); out = new PrintWriter (w); database = context.getInitParameter("ODBC"); appl = context.getInitParameter("application"); } void close() throws ServletException, IOException{ out.flush (); response.setContentLength (bytessize ()); try { bytes.writeTo (responsegetOutputStream ()); } catch (Exception e) { e.printStackTrace (); } } public void doPost ( HttpServletRequest HttpServletResponse request, resp) throws ServletException, IOException {} public void doGet ( HttpServletRequest request, HttpServletResponse resp ) throws ServletException, IOException { init(resp); out.println(head); out.println("<wml>"); out.print("<card id="Belepes">"); out.println("<p align="center">"); try { String nev =
request.getParameter("nev"); String password = request.getParameter("password"); Class.forName("sunjdbcodbcJdbcOdbcDriver"); Connection con = DriverManager.getConnection("jdbc:odbc:"+database); Statement stmt = con.createStatement(); ResultSet rs = stmt.executeQuery("SELECT password,palya,poziciox,pozicioy,nezet,terkep,mehet,azonosito,bentvan FROM jatekosok WHERE nev="+nev+""); if (rs.next()) { if (rs.getString(1)equals(password)) { int x = rs.getInt(3); int y = rs.getInt(4); int level = rs.getInt(2); int nezet = rs.getInt(5); int terkep = rs.getInt(6); int mehet = rs.getInt(7); int id = rs.getInt(8); boolean bentvan = rs.getBoolean(9); if (bentvan==false) { out.println("SIKERULT BELEPNI<br/>"); out.println("<anchor>Jatek folytatasa<br/>"); out.println("<go href="/"+appl+"/servlet/game" sendreferer="false" method="get">"); - 82 -
WAP alapú alkalmazás fejlesztése A játék dokumentálása out.println("<postfield name="id " value=""+id +""/>"); out.println("<postfield name="nev" value="$(nev)"/>"); out.println("<postfield name="pswd" value="$(pswd)"/>"); out.println("<postfield name="x" value=""+x+""/>"); out.println("<postfield name="y" value=""+y+""/>"); out.println("<postfield name="level" value=""+level+""/>"); out.println("<postfield name="nez" value=""+nezet+""/>"); out.println("<postfield name="terkep" value=""+terkep+""/>"); out.println("<postfield name="mehet" value=""+mehet+""/>");
out.println("</go>"); out.println("</anchor><br/>"); } else { out.println("MAR BE VAN LEPVE<br/>"); out.println("<anchor>Kileptetes<br/>"); out.println("<go href="/"+appl+"/servlet/kilepes" sendreferer="false" method="get">"); out.println("<postfield name="id " value=""+id +""/>"); out.println("<postfield name="nev" value="$(nev)"/>"); out.println("<postfield name="pswd" value="$(pswd)"/>"); out.println("<postfield name="x" value=""+x+""/>"); out.println("<postfield name="y" value=""+y+""/>"); out.println("<postfield name="level" value=""+level+""/>"); out.println("<postfield name="nez"
value=""+nezet+""/>"); out.println("<postfield name="terkep" value=""+terkep+""/>"); out.println("<postfield name="mehet" value=""+mehet+""/>"); out.println("</go>"); out.println("</anchor><br/>"); } out.println("<anchor>Kilepes a jatekbol<br/>"); out.println("<go href="/"+appl+"/servlet/labirintgame" sendreferer="false" method="get">"); out.println("</go>"); out.println("</anchor><br/>"); } else { out.println("NEM SIKERULT!!<br/>"); out.println("<anchor>Vissza<br/>"); out.println("<go href="/"+appl+"/servlet/labirintgame" sendreferer="false" method="get">"); out.println("</go>");
out.println("</anchor><br/>"); } } else { out.println("NEM SIKERULT!!<br/>"); out.println("<anchor>Vissza<br/>"); out.println("<go href="/"+appl+"/servlet/labirintgame" sendreferer="false" method="get">"); out.println("</go>"); out.println("</anchor><br/>"); } stmt.close(); con.close(); } catch (SQLException e ) { } catch (ClassNotFoundException e ) { } out.println("</p>"); out.println("</card>"); out.println("</wml>"); close(); } } A szervlet által eloállított WML oldal sikeres belépés esetén: <?xml version="1.0"?> <!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN" "http://wwwwapforumorg/DTD/wml 11xml"> <wml> <card id="Belepes"> <p align="center"> - 83 - WAP alapú alkalmazás fejlesztése A
játék dokumentálása SIKERULT BELEPNI <br/> <anchor>Jatek folytatasa<br/> <go href="/labirintus/servlet/game" sendreferer="false" method="get"> <postfield name="id " value="4"/> <postfield name="nev" value="$(nev:noesc)"/> <postfield name="pswd" value="$(pswd:noesc)"/> <postfield name="x" value="60"/> <postfield name="y" value="67"/> <postfield name="level" value="1"/> <postfield name="nez" value="1"/> <postfield name="terkep" value="1"/> <postfield name="mehet" value="0"/> </go></anchor> <br/> <anchor>Kilepes a jatekbol<br/> <go href="/labirintus/servlet/labirintgame" sendreferer="false" method="get"/> </anchor> <br/>
</p> </card> </wml> Sikertelen belépés eredménye: <?xml version="1.0"?> <!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN" "http://wwwwapforumorg/DTD/wml 11xml"> <wml> <card id="Belepes"> <p align="center"> NEM SIKERULT!! <br/> <anchor>Vissza<br/> <go href="/labirintus/servlet/labirintgame" sendreferer="false" method="get"/> </anchor> <br/> </p> </card> </wml> Ha már a játékos belépett és nem lépett ki: <?xml version="1.0"?> <!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN" "http://wwwwapforumorg/DTD/wml 11xml"> <wml> <card id="Belepes"> <p align="center"> MAR BE VAN LEPVE <br/> <anchor>Kileptetes<br/> <go href="/labirintus/servlet/kilepes" sendreferer="false"
method="get"> <postfield name="id " value="4"/> <postfield name="nev" value="$(nev:noesc)"/> <postfield name="pswd" value="$(pswd:noesc)"/> <postfield name="x" value="60"/> <postfield name="y" value="67"/> <postfield name="level" value="1"/> <postfield name="nez" value="1"/> <postfield name="terkep" value="1"/> <postfield name="mehet" value="0"/> </go></anchor> <br/> <anchor>Kilepes a jatekbol<br/> <go href="/labirintus/servlet/labirintgame" sendreferer="false" method="get"/> </anchor> <br/> </p> </card> </wml> - 84 - WAP alapú alkalmazás fejlesztése A játék dokumentálása A teljes JSP forrás: <%@ page import="java.sql*"
contentType="text/vnd.wapwml"%><% String head ="<?xml version="1.0"?> <!DOCTYPE wml PUBLIC "//WAPFORUM//DTD WML 11//EN" "http://wwwwapforumorg/DTD/wml 11xml">"; response.setHeader("Cache-Control","no-cache"); out.println(head); %> <wml> <card id="Belepes"> <p align="center"> <% try { String nev = request.getParameter("nev"); String password = request.getParameter("password"); Class.forName("sunjdbcodbcJdbcOdbcDriver"); Connection con = DriverManager.getConnection("jdbc:odbc:"+ application.getInitParameter("ODBC")); Statement stmt = con.createStatement(); ResultSet rs = stmt.executeQuery("SELECT password,palya,poziciox,pozicioy,nezet, terkep,mehet,azonosito,bentvan FROM jatekosok WHERE nev="+nev+""); if (rs.next()) { if (rs.getString(1)equals(password)) { int x = rs.getInt(3); int y =
rs.getInt(4); int level = rs.getInt(2); int nezet = rs.getInt(5); int terkep = rs.getInt(6); int mehet = rs.getInt(7); int id = rs.getInt(8); boolean bentvan = rs.getBoolean(9); if (bentvan==false) { %> SIKERULT BELEPNI<br/> <anchor>Jatek folytatasa<br/> <go href="game.jsp" sendreferer="false" method="get"> <postfield name="id " value="<%=id %>"/> <postfield name="nev" value="<%=nev%>"/> <postfield name="pswd" value="<%=password%>"/> <postfield name="x" value="<%=x%>"/> <postfield name="y" value="<%=y%>"/> <postfield name="level" value="<%=level%>"/> <postfield name="nez" value="<%=nezet%>"/> <postfield name="terkep" value="<%=terkep%>"/> <postfield name="mehet"
value="<%=mehet%>"/> </go> </anchor><br/> <% } else { %> MAR BE VAN LEPVE<br/> <anchor>Kileptetes<br/> <go href="kilepes.jsp" sendreferer="false" method="get"> <postfield name="id " value="<%=id %>"/> <postfield name="nev" value="<%=nev%>"/> <postfield name="pswd" value="<%=password%>"/> <postfield name="x" value="<%=x%>"/> <postfield name="y" value="<%=y%>"/> <postfield name="level" value="<%=level%>"/> <postfield name="nez" value="<%=nezet%>"/> <postfield name="terkep" value="<%=terkep%>"/> <postfield name="mehet" value="<%=mehet%>"/> </go> </anchor><br/> <% } %>
<anchor>Kilepes a jatekbol<br/> <go href="labirintgame.jsp" sendreferer="false" method="get"> </go> </anchor><br/> <% } else { %> NEM SIKERULT!!<br/> <anchor>Vissza<br/> <go href="labirintgame.jsp" sendreferer="false" method="get"> </go> </anchor><br/> - 85 - WAP alapú alkalmazás fejlesztése A játék dokumentálása <% } } else { %> NEM SIKERULT!!<br/> <anchor>Vissza<br/> <go href="labirintgame.jsp" sendreferer="false" method="get"> </go> </anchor><br/> <% } stmt.close(); con.close(); } catch (SQLException e ) { } catch (ClassNotFoundException e ) { } %> </p> </card> </wml> VIII5. REGISZTRALAS.JAVA A regisztralas.java szervlet nem tesz mást, mint a labirintgame szervlettol kapott nev és password paraméterek segítségével egy
új játékost vesz fel az adatbázisba. A beillesztés elott azonban még megnézi, hogy van-e az adatbázisban már olyan nevu játékos. Ha van, akkor sikertelen regisztrációról ad információt, ellenkezo esetben felajánlja a játék elkezdését. A szervlet egy WML oldalt generál kimenetül A beleptet.java ismertetésénél már bemutattam, hogy hogyan néz ki egy szervlet általánosan, valamint hogyan férhet hozzá az adatbázishoz, így mostantól már csak a fontosabb utasításokat ismertetem (esetleges SQL utasítások), valamint a forráskódok elott minden egyes alkalommal a szervlet kimenetét is megmutatom a WapToolkit 1.2-ben levo Nokia 6150-es telefon-szimulátor segítségével A következo programrészlet megkeresi a legnagyobb azonosítót az adatbázisban, mivel annál 1-el nagyobb lesz az új játékos azonosítója. Statement stmt = con.createStatement(); ResultSet rs = stmt.executeQuery("SELECT MAX(azonosito) FROM jatekosok"); rs.next(); int
az=rs.getInt(1)+1; stmt.close(); A következo programrészlet pedig elvégzi a játékos adatainak felvételét az adatbázisba: PreparedStatement pstmt = con.prepareStatement("INSERT INTO jatekosok (azonosito, nev, password, palya, bentvan, poziciox, pozicioy, nezet, mehet, terkep, ero, vedelem, pont) VALUES (" + az + "," + nev + "," + password + ", 1 ,0 , " + startx + "," + starty + ", 1,0,1,10,10,0 )"); pstmt.executeUpdate(); pstmt.close(); Az új játékos kezdopozíciója véletlenszeruen lesz megállapítva. Ezt a labirintusuresek változó illetve a labirintus.getrandomx() és labirintusgetrandomy() metódusok segítségével végzi el: Double a = new Double(Math.random()*labirintus.uresek*1.0); int startx = labirintus.getrandomx(aintValue()); int starty = labirintus.getrandomy(aintValue()); A labirintus.uresek megadja azt, hogy mennyi út, azaz üres pozíció van a labirintusban Az "a" változó értéke
véletlenszeruen kerül megállapításra. Értéke maximum labirintusuresek lehet Ezt követoen a labirintus.getrandomx() illetve labirintusgetrandomy() visszaadja a paraméterül kapott indexu üres hely koordinátáját. - 86 - WAP alapú alkalmazás fejlesztése A játék dokumentálása A szervlet végeredményül a következo oldalakat adja: Sikeres regisztrálás esetén Sikertelen regisztráció esetén A forráskód: import import import import import java.sql*; java.io*; java.util*; javax.servlet*; javax.servlethttp*; public class regisztralas extends HttpServlet{ String head ="<?xml version="1.0"?> <!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN" "http://wwwwapforumorg/DTD/wml 11xml">"; String contentType = "text/vnd.wapwml"; HttpServletResponse response; ByteArrayOutputStream bytes; String encoding; OutputStreamWriter w; PrintWriter out; String directory; String database; String appl; void
init(HttpServletResponse resp) throws ServletException, IOException { ServletContext context=getServletContext(); response = resp; response.setContentType(contentType); response.setHeader("Cache-Control","no-cache"); encoding = response.getCharacterEncoding (); bytes = new ByteArrayOutputStream (8192); w = new OutputStreamWriter (bytes, encoding); out = new PrintWriter (w); directory = context.getRealPath( "/data" ); database = context.getInitParameter("ODBC"); appl = context.getInitParameter("application"); } void close() throws ServletException, IOException{ out.flush (); response.setContentLength (bytessize ()); try {bytes.writeTo (responsegetOutputStream ());} catch (Exception e) {e.printStackTrace ();} } public void doPost ( HttpServletRequest HttpServletResponse request, resp) throws ServletException, IOException {} public void doGet ( HttpServletRequest HttpServletResponse request, resp - 87 - WAP alapú alkalmazás
fejlesztése ) { A játék dokumentálása throws ServletException, IOException init(resp); out.println(head); out.println("<wml>"); out.print("<card id="Regisztralas">"); out.println("<p align="center">"); try { String nev = request.getParameter("nev"); String password = request.getParameter("password"); Class.forName("sunjdbcodbcJdbcOdbcDriver"); Connection con = DriverManager.getConnection("jdbc:odbc:"+database); Statement stmt = con.createStatement(); ResultSet rs = stmt.executeQuery("SELECT MAX(azonosito) FROM jatekosok"); rs.next(); int az=rs.getInt(1)+1; stmt.close(); stmt = con.createStatement(); rs = stmt.executeQuery("SELECT azonosito FROM jatekosok WHERE nev="+nev+""); boolean van=false; if (rs.next()) {van=true;} stmt.close(); if (van==false) { labirint labirintus = new labirint(directory+"/level1.dat"); Double a = new
Double(Math.random()*labirintus.uresek*1.0); int startx = labirintus.getrandomx(aintValue()); int starty = labirintus.getrandomy(aintValue()); PreparedStatement pstmt = con.prepareStatement("INSERT INTO jatekosok (azonosito,nev,password,palya,bentvan,poziciox,pozicioy,nezet,mehet,terkep,ero,vedel em,pont) VALUES ("+az+","+nev+","+password+",1,0,"+startx+","+starty+",1,0,1,10,10,0)"); pstmt.executeUpdate(); pstmt.close(); con.close(); out.println("SIKERULT REGISZTRALNI<br/>"); out.println("<anchor>Jatek kezdese<br/>"); out.println("<go href="/"+appl+"/servlet/beleptet" sendreferer="false" method="get">"); out.println("<postfield name="password" value=""+password+""/>"); out.println("<postfield name="nev" value=""+nev+""/>");
out.println("</go>"); out.println("</anchor><br/>"); out.println("<anchor>Kilepes<br/>"); out.println("<go href="/"+appl+"/servlet/labirintgame" sendreferer="false" method="get">"); out.println("</go>"); out.println("</anchor><br/>"); } else { con.close(); out.println("<small><b>NEM SIKERULT REGISZTRALNI</b>, jatekos</small><br/>"); van mar ilyen nevu out.println("<anchor>Vissza<br/>"); out.println("<go href="/"+appl+"/servlet/labirintgame" sendreferer="false" method="get"/>"); out.println("</anchor><br/>"); } } catch (SQLException e ) {} catch (ClassNotFoundException e ) {} out.println("</p>"); out.println("</card>"); out.println("</wml>");
close(); } } - 88 - WAP alapú alkalmazás fejlesztése A játék dokumentálása Sikeres regisztrálás eredményeként a következo WML oldalt hozza létre a szervlet: <?xml version="1.0"?> <!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN" "http://wwwwapforumorg/DTD/wml 11xml"> <wml> <card id="Regisztralas"> <p align="center"> SIKERULT REGISZTRALNI <br/> <anchor>Jatek kezdese<br/> <go href="/labirintus/servlet/beleptet" sendreferer="false" method="get"> <postfield name="password" value="wap"/> <postfield name="nev" value="wap1"/> </go></anchor> <br/> <anchor>Kilepes<br/> <go href="/labirintus/servlet/labirintgame" sendreferer="false" method="get"/> </anchor> <br/> </p> </card> </wml> Sikertelen
regisztrálás eredménye: <?xml version="1.0"?> <!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN" "http://wwwwapforumorg/DTD/wml 11xml"> <wml> <card id="Regisztralas"> <p align="center"> <small><b>NEM SIKERULT REGISZTRALNI</b>, van mar ilyen nevu jatekos</small> <br/> <anchor>Vissza<br/> <go href="/labirintus/servlet/labirintgame" sendreferer="false" method="get"/> </anchor> <br/> </p> </card> </wml> A JSP oldal a következoképpen néz ki: <%@ page import="java.sql*,Lab,java.lang*,java.util*" contentType="text/vnd.wapwml"%>< jsp:useBean id="labirintus" scope="session" class="Lab"/><% String head ="<?xml version="1.0"?> <!DOCTYPE wml PUBLIC "//WAPFORUM//DTD WML 11//EN"
"http://wwwwapforumorg/DTD/wml 11xml">"; response.setHeader("Cache-Control","no-cache"); out.println(head); %> <wml> <card id="Regisztralas"> <p align="center"> <% try { String nev = request.getParameter("nev"); String password = request.getParameter("password"); Class.forName("sunjdbcodbcJdbcOdbcDriver"); Connection con = DriverManager.getConnection("jdbc:odbc:"+ application.getInitParameter("ODBC")); Statement stmt = con.createStatement(); ResultSet rs = stmt.executeQuery("SELECT MAX(azonosito) FROM jatekosok"); rs.next(); int az=rs.getInt(1)+1; stmt.close(); stmt = con.createStatement(); rs = stmt.executeQuery("SELECT azonosito FROM jatekosok WHERE nev="+nev+""); boolean van=false; if (rs.next()) {van=true;} stmt.close(); if (van==false) { - 89 - WAP alapú alkalmazás fejlesztése A játék dokumentálása
labirintus.setlabirint(applicationgetRealPath("/data/level1dat")); Double a = new Double(Math.random()*labirintus.geturesek()*1.0); int startx = labirintus.getrandomx(aintValue()); int starty = labirintus.getrandomy(aintValue()); PreparedStatement pstmt = con.prepareStatement("INSERT INTO jatekosok (azonosito,nev,password,palya,bentvan,poziciox,pozicioy,nezet,mehet,terkep, ero,vedelem,pont) VALUES ("+az+","+nev+","+password+",1,0,"+startx +","+ starty+",1,0,1,10,10,0)"); pstmt.executeUpdate(); pstmt.close(); con.close();%> SIKERULT REGISZTRALNI<br/> <anchor>Jatek kezdese<br/> <go href="beleptet.jsp" sendreferer="false" method="get"> <postfield name="password" value="<%=password%>"/> <postfield name="nev" value="<%=nev%>"/> </go> </anchor><br/> <anchor>Kilepes<br/>
<go href="labirintgame.jsp" sendreferer="false" method="get"> </go> </anchor><br/><% } else { con.close(); %> <small> <b> NEM SIKERULT REGISZTRALNI </b>, van mar ilyen nevu jatekos </small> <br/> <anchor>Vissza<br/> <go href="labirintgame.jsp" sendreferer="false" method="get"/> </anchor><br/> <% } } catch (SQLException e ) {} catch (ClassNotFoundException e ) {} %> </p> </card> </wml> - 90 - WAP alapú alkalmazás fejlesztése A játék dokumentálása VIII6. GAME.JAVA A game.java szervlet végzi el a labirintust tartalmazó kép, valamint az irányítást elvégzo linkek megjelenítését. A szervlet egy WML oldalt ad kimenetül, mely tartalmaz egy képet, 4 linket és egy accept valamint egy options típusú gombot. A szervlet a következo paramétereket kapja: String String String String String String
String String String String nev password xx yy terkep level nez mehet id update = = = = = = = = = = request.getParameter("nev"); request.getParameter("pswd"); request.getParameter("x"); request.getParameter("y"); request.getParameter("terkep"); request.getParameter("level"); request.getParameter("nez"); request.getParameter("mehet"); request.getParameter("id "); request.getParameter("update"); // Ez tartalmazza a frissítés gyorsaságát A megjelenítendo képet a create.java szervlettol veszi a következo programrészlettel: out.print("<img alt="A labirintus" src="/"+appl+"/servlet/create?"); out.print( "x="+x+"&"); out.print( "y="+y+"&"); out.print( "level="+level +"&"); out.print( "map="+terkep +"&"); out.print( "id
="+id +"&"); out.println("nez="+nez +""/><br/>"); mely nem tesz mást, mint hogy a WML oldalba beilleszt egy img elemet. A game szervlet úgy muködik, hogy miután a belépés megtörtént a játékba, a szervlet egy olyan WML oldalt generál, mely bizonyos idoközönként – ezt lehet beállítani a frissites opció gombbal – saját magát meghívja, ezáltal frissíti a képet a játékban. Ezt szemlélteti a következo programrészlet: out.println("<onevent type="ontimer">"); out.println("<go href="/labirintus/servlet/game" sendreferer="false" method="get">"); if (mehet==1) { out.println("<postfield name="x" value=""+x for+""/>"); out.println("<postfield name="y" value=""+y for+""/>"); } else { out.println("<postfield name="x"
value=""+xx+""/>"); out.println("<postfield name="y" value=""+yy+""/>"); } out.println("<postfield name="nez" value=""+nez +""/>"); out.println("<postfield name="level" value=""+level +""/>"); out.println("<postfield name="terkep" value=""+terkep +""/>"); out.println("<postfield name="mehet" value=""+mehet +""/>"); out.println("<postfield name="nev" value="$(nev)"/>"); out.println("<postfield name="pswd" value="$(pswd)"/>"); out.println("<postfield name="id " value=""+id +""/>"); out.println("</go>"); out.println("</onevent>"); A kiemelt rész azért fontos, mert így meg van az
oldva, hogy abban az esetben, amikor a játékos fut – azaz korábban a Fut linket aktiválta –, nem egy helyben marad a játékos, hanem az elotte levo üres helyre megy. Ha meg nem fut, akkor pedig egy helyben marad, és úgy frissítodik az állapot Azt is figyelni kell, hogy a játékos ne fusson át a falon, illetve egy pozícióban több játékos ne legyen. Tehát amikor az elotte levo helyen fal vagy játékos van, akkor nem szabad, hogy oda fusson. Ekkor „egyhelyben fut”, vagy megáll a játékos. Ezért a szervlet tartalmaz egy labirintus típusú adatszerkezetet, melyet a kapott level és a szervlet iniciális directory paramétere alapján hoz létre: labirint labirintus = new labirint(directory+"/level"+level+".dat"); A fal és az ellenség figyelése: if ((labirintus.getxy(x for,y for)!=1 && ellenseg==false)) { - 91 - WAP alapú alkalmazás fejlesztése A játék dokumentálása out.println("<onevent
type="ontimer">"); } else { out.println("<onevent type="ontimer">"); } A szervlet a 4 linket egy táblázatban jeleníti meg. A 4 link: • Harc • Balra • Jobbra • Fut/Allj A negyedik link felirata attól függ, hogy a játékos fut-e vagy sem. A Harc link a fight.java szervletre hivatkozik, míg az összes többi a gamejava szervletet (saját magát) hívja meg, persze a megfelelo paraméterek módosításával. Ezek a paraméterek a következok: Balra nez=nezleft Jobbra nez=nezright Fut/Allj mehet=1/0 Ahol a nezleft, illetve nezright az éppen aktuális iránynál eggyel nagyobb (nezleft=nez+1), vagy eggyel kevesebb (nezleft=nez-1), és azt mondja meg, hogy melyik irányt kell választani, ha balra, vagy ha jobbra fordul a játékos. A két további gomb egy-egy do WML elem segítségével jelennek meg: Kilepes: out.println("<do type="accept" label="Kilepes">"); out.println("<go
href="/"+appl+"/servlet/kilepes" sendreferer="false" method="get">"); out.println("<postfield name="nev" value="$(nev)"/>"); out.println("<postfield name="pswd" value="$(pswd)"/>"); out.println("<postfield name="id " value=""+id +""/>"); out.println("<postfield name="x" value=""+xx+""/>"); out.println("<postfield name="y" value=""+yy+""/>"); out.println("<postfield name="nez" value=""+nez +""/>"); out.println("<postfield name="level" value=""+level +""/>"); out.println("<postfield name="terkep" value=""+terkep +""/>"); out.println("<postfield name="mehet" value=""+mehet
+""/>"); out.println("</go>"); out.println("</do>"); Frissites: out.println("<do type="options" label="Frissites">"); out.println("<go href="/"+appl+"/servlet/frissites" sendreferer="false" method="get">"); out.println("<postfield name="nev" value="$(nev)"/>"); out.println("<postfield name="frissites" value=""+update+""/>"); out.println("<postfield name="pswd" value="$(pswd)"/>"); out.println("<postfield name="id " value=""+id +""/>"); out.println("<postfield name="x" value=""+xx+""/>"); out.println("<postfield name="y" value=""+yy+""/>"); out.println("<postfield name="nez"
value=""+nez +""/>"); out.println("<postfield name="level" value=""+level +""/>"); out.println("<postfield name="terkep" value=""+terkep +""/>"); out.println("<postfield name="mehet" value=""+mehet +""/>"); out.println("</go>"); out.println("</do>"); A szervlet további adminisztrációs feladatokat is ellát. Minden egyes hívás esetén az adatbázisban aktualizálja a játékos pozícióját azért, hogy a többiek is érzékeljék a mozgását, valamint itt történik meg az esetleges tárgyak felvételének aktualizálása, azaz a megfelelo szintek értékének növelése. Ezeket még a WML oldal fejlécének (head) kiíratása elott elvégzi, hogy a képet létrehozó create szervlet is érzékelje az esetleges változásokat. A szervletnek azt is el kell a frissítés során
végezni, hogy ha a játékos az elozo körben meghalt, és a halott mezo „true”, akkor azt „false”-ra állítsa. Ezzel jelzi, hogy a játékos a következo körben beléphet Azért van ez így, mert a harcolás során, ha a játékos védelmi szintje 0 lesz, akkor a szervlet a „halott” mezot „true”-ra állítja, így jelezve a szenvedo alanynak, hogy meghalt. Errol ez a szervlet a frissítésnek megfelelo ido múlva értesül, és a játékos számára megjelenít egy olyan oldalt, mely informálja ot, hogy meghalt. Ezen - 92 - WAP alapú alkalmazás fejlesztése A játék dokumentálása információ kiíratása elott történik meg a „halott” mezo true-ra állítása, hogy a legközelebbi belépésnél ne jelezze, hogy megint meghalt. Ha meghalt a játékos, a következo üzenetet kapja: A WML oldal: <?xml version="1.0"?> <!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN" " http://www.wapforumorg/DTD/wml 11xml">
<wml> <card id="Halott" title="Meghaltal"> <p align="center"> Megoltek teged! <br/> <anchor>Kilepes<br/> <go href="/labirintus/servlet/labirintgame"/> </anchor> </p> </card> </wml> A szervlet a következo adatbázis muveleteket végzi el: 1. Aktualizálja a játékos helyét PreparedStatement pstmt = con.prepareStatement("UPDATE jatekosok SET poziciox="+x+",pozicioy="+y+",nezet="+nez+",mehet="+mehet+",bentvan=true WHERE azonosito="+id ); pstmt.executeUpdate(); pstmt.close(); 2. Lekérdezi a játékos frissítési periódusát, a pontszámát, és azt, hogy meghalt-e stmt = con.createStatement(); rs = stmt.executeQuery("SELECT frissites,halott,pont FROM jatekosok WHERE azonosito="+id ); Ha az update változónak még nincsen értéke, akkor azt az adatbázisból kell lekérdezni. Ez általában a legelso alkalommal
történik meg. Ellenkezo esetben pedig a „frissites” mezo aktualizálása történik meg: if (update == null) { update=rs.getString(1); stmt.close(); } else { stmt.close(); pstmt = con.prepareStatement("UPDATE jatekosok SET frissites="+update+" WHERE azonosito="+id ); pstmt.executeUpdate(); pstmt.close(); } Ha halott, akkor pedig engedélyezzük számára, hogy játsszon tovább: if (halott == true) { pstmt = con.prepareStatement("UPDATE jatekosok SET halott=false WHERE azonosito="+id ); pstmt.executeUpdate(); pstmt.close(); } Normális esetben, amikor a játékos nem halt meg, a következo oldalt generálja a szervlet: - 93 - WAP alapú alkalmazás fejlesztése A játék dokumentálása A forráskód: import import import import import java.sql*; java.io*; java.util*; javax.servlet*; javax.servlethttp*; public class game extends HttpServlet{ String head ="<?xml version="1.0"?> <!DOCTYPE wml PUBLIC
"-//WAPFORUM//DTD WML 1.1//EN" "http://wwwwapforumorg/DTD/wml 12xml">"; String contentType = "text/vnd.wapwml"; HttpServletResponse response; ByteArrayOutputStream bytes; String encoding; OutputStreamWriter w; PrintWriter out; String directory; String ODBC; String appl; void init(HttpServletResponse resp) throws ServletException, IOException { ServletContext context=getServletContext(); response = resp; response.setContentType(contentType); response.setHeader("Cache-Control","no-cache"); encoding = response.getCharacterEncoding (); bytes = new ByteArrayOutputStream (8192); w = new OutputStreamWriter (bytes, encoding); out = new PrintWriter (w); directory = context.getRealPath( "/data" ); ODBC = context.getInitParameter("ODBC"); appl = context.getInitParameter("application"); } void close() throws ServletException, IOException{ out.flush (); response.setContentLength (bytessize ()); try
{bytes.writeTo (responsegetOutputStream ());} catch (Exception e) {e.printStackTrace ();} } public void doPost ( HttpServletRequest HttpServletResponse request, resp) throws ServletException, IOException {} public void doGet ( HttpServletRequest request, HttpServletResponse resp ) throws ServletException, IOException { String nev = request.getParameter("nev"); String password = request.getParameter("pswd"); String xx = request.getParameter("x"); String yy = request.getParameter("y"); String terkep = request.getParameter("terkep"); String level = request.getParameter("level"); String nez = request.getParameter("nez"); String mehet = request.getParameter("mehet"); String id = request.getParameter("id "); String update = request.getParameter("update"); String pont="no"; int nezleft; int mehet; int nezright; boolean ellenseg=false,halott=false; int level; int nez; int x; int
y; int terkep; if (level ==null) level=1; else level=Integer.parseInt(level ); if (terkep ==null) terkep=0; else terkep=Integer.parseInt(terkep ); - 94 - WAP alapú alkalmazás fejlesztése A játék dokumentálása if (nez ==null) nez=1; else nez=Integer.parseInt(nez ); if (mehet ==null) mehet=0; else mehet=Integer.parseInt(mehet ); mehet =Integer.toString(mehet); init(resp); labirint labirintus = new labirint(directory+"/level"+level+".dat"); if (xx==null | yy==null) { x=labirintus.startx; y=labirintusstarty; } else { x=Integer.parseInt(xx); y=IntegerparseInt(yy); } int x left,x right,x for,x back,y left,y right,y for,y back; if (nez==1) { x left=x+1; y left=y; if (nez==2) { x left=x; y left=y-1; if (nez==3) { x left=x-1; y left=y; else { x left=x; y left=y+1; x right=x-1; y right=y; x right=x; y right=y+1; x right=x+1; y right=y; x for=x; y for=y+1; x for=x+1; y for=y; x for=x; y for=y-1; x back=x ; y back=y-1; } else x back=x-1; y back=y; } else x
back=x; y back=y+1; } x right=x; x for=x-1; x back=x+1; y right=y-1; y for=y; y back=y; } nezleft=nez+1; if (nezleft>4) {nezleft=1;} nezright=nez-1; if (nezright<1) {nezright=4;} try { Class.forName("sunjdbcodbcJdbcOdbcDriver"); Connection con = DriverManager.getConnection("jdbc:odbc:"+ODBC); Statement stmt = con.createStatement(); ResultSet rs; int i,j; /* Ha a jatekos elott van valaki, akkor meg kell allni / rs = stmt.executeQuery("SELECT poziciox,pozicioy,azonosito FROM jatekosok WHERE poziciox="+x for+" AND pozicioy="+y for+" AND bentvan=true AND palya="+level ); ellenseg=false; while (rs.next()) { i = rs.getInt(1); j = rs.getInt(2); ellenseg=true; } if (ellenseg==true) { mehet=0; mehet ="0";} PreparedStatement pstmt = con.prepareStatement("UPDATE jatekosok SET poziciox="+x+",pozicioy="+y+",nezet="+nez+",mehet="+mehet+",bentvan=true WHERE azonosito="+id );
pstmt.executeUpdate(); pstmt.close(); stmt = con.createStatement(); rs = stmt.executeQuery("SELECT frissites,halott,pont FROM jatekosok WHERE azonosito="+id ); rs.next(); halott=rs.getBoolean(2); pont=rs.getString(3); if (update == null) { update=rs.getString(1); stmt.close(); } else { stmt.close(); pstmt = con.prepareStatement("UPDATE jatekosok SET frissites="+update+" WHERE azonosito="+id ); pstmt.executeUpdate(); pstmt.close(); } if (halott == true) { pstmt = con.prepareStatement("UPDATE jatekosok SET halott=false WHERE azonosito="+id ); pstmt.executeUpdate(); pstmt.close(); } con.close(); } catch (SQLException e ) {} catch (ClassNotFoundException e ) {} - 95 - WAP alapú alkalmazás fejlesztése A játék dokumentálása out.println(head); out.println("<wml>"); if (halott==false) { out.print("<card newcontext="true" id="game" title=""+pont+" p">"); if
((labirintus.getxy(x for,y for)!=1 && ellenseg==false)) { out.println("<onevent type="ontimer">"); out.println("<go href="/"+appl+"/servlet/game" sendreferer="false" method="get">"); if (mehet==1) { out.println("<postfield name="x" value=""+x for+""/>"); out.println("<postfield name="y" value=""+y for+""/>"); } else { out.println("<postfield name="x" value=""+xx+""/>"); out.println("<postfield name="y" value=""+yy+""/>"); } out.println("<postfield name="nez" value=""+nez +""/>"); out.println("<postfield name="level" value=""+level +""/>"); out.println("<postfield name="terkep" value=""+terkep
+""/>"); out.println("<postfield name="mehet" value=""+mehet +""/>"); out.println("<postfield name="nev" value="$(nev)"/>"); out.println("<postfield name="pswd" value="$(pswd)"/>"); out.println("<postfield name="id " value=""+id +""/>"); out.println("</go>"); out.println("</onevent>"); } else { out.println("<onevent type="ontimer">"); out.println("<go href="/"+appl+"/servlet/game" sendreferer="false" method="get">"); out.println("<postfield name="x" value=""+xx+""/>"); out.println("<postfield name="y" value=""+yy+""/>"); out.println("<postfield name="nez" value=""+nez
+""/>"); out.println("<postfield name="level" value=""+level +""/>"); out.println("<postfield name="terkep" value=""+terkep +""/>"); out.println("<postfield name="mehet" value=""+mehet +""/>"); out.println("<postfield name="nev" value="$(nev)"/>"); out.println("<postfield name="pswd" value="$(pswd)"/>"); out.println("<postfield name="id " value=""+id +""/>"); out.println("</go>"); out.println("</onevent>"); } out.println("<timer value=""+update+""/>"); out.println("<p align="center">"); out.print("<img alt="A labirintus" src="/"+appl+"/servlet/create?"); out.print(
"x="+x+"&"); out.print( "y="+y+"&"); out.print( "level="+Level +"&"); out.print( "map="+terkep +"&"); out.print( "id ="+id +"&"); out.println("nez="+nez +""/><br/>"); out.println("<small>"); out.println("<table columns="4">"); out.println("<tr>"); out.print("<td><anchor>Harc<br/>"); out.println("<go href="/"+appl+"/servlet/fight" sendreferer="false" method="get">"); out.println("<postfield name="x" value=""+x+""/>"); out.println("<postfield name="y" value=""+y+""/>"); out.println("<postfield name="nez" value=""+nez +""/>");
out.println("<postfield name="level" value=""+level +""/>"); out.println("<postfield name="terkep" value=""+terkep +""/>"); out.println("<postfield name="mehet" value=""+mehet +""/>"); out.println("<postfield name="nev" value="$(nev)"/>"); out.println("<postfield name="pswd" value="$(pswd)"/>"); out.println("<postfield name="id " value=""+id +""/>"); out.println("</go>"); out.println("</anchor></td>"); out.print("<td><anchor>Balra<br/>"); out.println("<go href="/"+appl+"/servlet/game" sendreferer="false" method="get">"); out.println("<postfield name="x"
value=""+x+""/>"); out.println("<postfield name="y" value=""+y+""/>"); out.println("<postfield name="nez" value=""+nezleft+""/>"); out.println("<postfield name="level" value=""+level +""/>"); out.println("<postfield name="terkep" value=""+terkep +""/>"); out.println("<postfield name="mehet" value=""+mehet +""/>"); - 96 - WAP alapú alkalmazás fejlesztése A játék dokumentálása out.println("<postfield name="nev" value="$(nev)"/>"); out.println("<postfield name="pswd" value="$(pswd)"/>"); out.println("<postfield name="id " value=""+id +""/>"); out.println("</go>");
out.println("</anchor></td>"); out.print("<td><anchor>Jobbra<br/>"); out.println("<go href="/"+appl+"/servlet/game" sendreferer="false" method="get">"); out.println("<postfield name="nev" value="$(nev)"/>"); out.println("<postfield name="pswd" value="$(pswd)"/>"); out.println("<postfield name="x" value=""+x+""/>"); out.println("<postfield name="y" value=""+y+""/>"); out.println("<postfield name="nez" value=""+nezright+""/>"); out.println("<postfield name="level" value=""+level +""/>"); out.println("<postfield name="terkep" value=""+terkep +""/>"); out.println("<postfield
name="mehet" value=""+mehet +""/>"); out.println("<postfield name="id " value=""+id +""/>"); out.println("</go>"); out.println("</anchor></td>"); if (mehet==1) { out.print("<td><anchor>Allj<br/>"); out.println("<go href="/"+appl+"/servlet/game" sendreferer="false" method="get">"); out.println("<postfield name="nev" value="$(nev)"/>"); out.println("<postfield name="pswd" value="$(pswd)"/>"); out.println("<postfield name="x" value=""+x+""/>"); out.println("<postfield name="y" value=""+y+""/>"); out.println("<postfield name="nez" value=""+nez +""/>");
out.println("<postfield name="level" value=""+level +""/>"); out.println("<postfield name="terkep" value=""+terkep +""/>"); out.println("<postfield name="mehet" value="0"/>"); out.println("<postfield name="id " value=""+id +""/>"); out.println("</go>"); out.println("</anchor></td>"); } else { out.print("<td><anchor>Futas<br/>"); out.println("<go href="/"+appl+"/servlet/game" sendreferer="false" method="get">"); out.println("<postfield name="nev" value="$(nev)"/>"); out.println("<postfield name="pswd" value="$(pswd)"/>"); out.println("<postfield name="x" value=""+x+""/>");
out.println("<postfield name="y" value=""+y+""/>"); out.println("<postfield name="nez" value=""+nez +""/>"); out.println("<postfield name="level" value=""+level +""/>"); out.println("<postfield name="terkep" value=""+terkep +""/>"); out.println("<postfield name="mehet" value="1"/>"); out.println("<postfield name="id " value=""+id +""/>"); out.println("</go>"); out.println("</anchor></td>"); } out.println("</tr></table></small>"); out.println("</p>"); out.println("<do type="accept" label="Kilepes">"); out.println("<go href="/"+appl+"/servlet/kilepes" sendreferer="false"
method="get">"); out.println("<postfield name="nev" value="$(nev)"/>"); out.println("<postfield name="pswd" value="$(pswd)"/>"); out.println("<postfield name="id " value=""+id +""/>"); out.println("<postfield name="x" value=""+xx+""/>"); out.println("<postfield name="y" value=""+yy+""/>"); out.println("<postfield name="nez" value=""+nez +""/>"); out.println("<postfield name="level" value=""+level +""/>"); out.println("<postfield name="terkep" value=""+terkep +""/>"); out.println("<postfield name="mehet" value=""+mehet +""/>"); out.println("</go>");
out.println("</do>"); out.println("<do type="options" label="Frissites">"); out.println("<go href="/"+appl+"/servlet/frissites" sendreferer="false" method="get">"); out.println("<postfield name="frissites" value=""+update+""/>"); out.println("<postfield name="nev" value="$(nev)"/>"); out.println("<postfield name="pswd" value="$(pswd)"/>"); - 97 - WAP alapú alkalmazás fejlesztése out.println("<postfield out.println("<postfield out.println("<postfield out.println("<postfield out.println("<postfield out.println("<postfield out.println("<postfield out.println("</go>"); out.println("</do>"); A játék dokumentálása name="id " value=""+id
+""/>"); name="x" value=""+xx+""/>"); name="y" value=""+yy+""/>"); name="nez" value=""+nez +""/>"); name="level" value=""+level +""/>"); name="terkep" value=""+terkep +""/>"); name="mehet" value=""+mehet +""/>"); out.println("</card>"); } else { out.println("<card id="Halott" title="Meghaltal">"); out.println("<p align="center">Megoltek teged!<br/>"); out.print("<anchor>Kilepes<br/>"); out.println("<go href="/"+appl+"/servlet/labirintgame"/>"); out.println("</anchor></p>"); out.println("</card>"); } out.println("</wml>"); close(); } } A szervlet
által eloállított WML oldal: <?xml version="1.0"?> <!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN" "http://wwwwapforumorg/DTD/wml 11xml"> <wml> <card newcontext="true" id="game" title="100 p."> <onevent type="ontimer"> <go href="/labirintus/servlet/game" sendreferer="false" method="get"> <postfield name="x" value="60"/> <postfield name="y" value="67"/> <postfield name="nez" value="2"/> <postfield name="level" value="1"/> <postfield name="terkep" value="1"/> <postfield name="mehet" value="0"/> <postfield name="nev" value="$(nev:noesc)"/> <postfield name="pswd" value="$(pswd:noesc)"/> <postfield name="id " value="4"/>
</go> </onevent> <timer value="50"/> <p align="center"> <img alt="A labirintus" src="/labirintus/servlet/create?x=60&y=67& level=1&map=1&id =4&nez=2"/> <br/> <small><table columns="4"><tr> <td><anchor>Harc<br/> <go href="/labirintus/servlet/fight" sendreferer="false" method="get"> <postfield name="x" value="60"/> <postfield name="y" value="67"/> <postfield name="nez" value="2"/> <postfield name="level" value="1"/> <postfield name="terkep" value="1"/> <postfield name="mehet" value="0"/> <postfield name="nev" value="$(nev:noesc)"/> <postfield name="pswd" value="$(pswd:noesc)"/>
<postfield name="id " value="4"/> </go></anchor></td> <td><anchor>Balra<br/> <go href="/labirintus/servlet/game" sendreferer="false" method="get"> <postfield name="x" value="60"/> <postfield name="y" value="67"/> <postfield name="nez" value="3"/> <postfield name="level" value="1"/> <postfield name="terkep" value="1"/> <postfield name="mehet" value="0"/> <postfield name="nev" value="$(nev:noesc)"/> <postfield name="pswd" value="$(pswd:noesc)"/> <postfield name="id " value="4"/> </go></anchor></td> <td><anchor>Jobbra<br/> - 98 - WAP alapú alkalmazás fejlesztése A játék dokumentálása <go
href="/labirintus/servlet/game" sendreferer="false" method="get"> <postfield name="nev" value="$(nev:noesc)"/> <postfield name="pswd" value="$(pswd:noesc)"/> <postfield name="x" value="60"/> <postfield name="y" value="67"/> <postfield name="nez" value="1"/> <postfield name="level" value="1"/> <postfield name="terkep" value="1"/> <postfield name="mehet" value="0"/> <postfield name="id " value="4"/> </go></anchor></td> <td><anchor>Futas<br/> <go href="/labirints/servlet/game" sendreferer="false" method="get"> <postfield name="nev" value="$(nev:noesc)"/> <postfield name="pswd" value="$(pswd:noesc)"/>
<postfield name="x" value="60"/> <postfield name="y" value="67"/> <postfield name="nez" value="2"/> <postfield name="level" value="1"/> <postfield name="terkep" value="1"/> <postfield name="mehet" value="1"/> <postfield name="id " value="4"/> </go></anchor></td> </tr></table></small> </p> <do type="accept" label="Kilepes"> <go href="/labirintus/servlet/kilepes" sendreferer="false" method="get"> <postfield name="nev" value="$(nev:noesc)"/> <postfield name="pswd" value="$(pswd:noesc)"/> <postfield name="id " value="4"/> <postfield name="x" value="60"/> <postfield name="y"
value="67"/> <postfield name="nez" value="2"/> <postfield name="level" value="1"/> <postfield name="terkep" value="1"/> <postfield name="mehet" value="0"/> </go> </do> <do type="options" label="Frissites"> <go href="/labirintus/servlet/frissites" sendreferer="false" method="get"> <postfield name="frissites" value="50"/> <postfield name="nev" value="$(nev:noesc)"/> <postfield name="pswd" value="$(pswd:noesc)"/> <postfield name="id " value="4"/> <postfield name="x" value="60"/> <postfield name="y" value="67"/> <postfield name="nez" value="2"/> <postfield name="level" value="1"/> <postfield
name="terkep" value="1"/> <postfield name="mehet" value="0"/> </go> </do> </card> </wml> A JSP oldal: <%@ page import="java.sql*,Lab,java.lang*,java.util*" contentType="text/vnd.wapwml"%>< jsp:useBean id="labirintus" scope="session" class="Lab"/><% String head ="<?xml version="1.0"?> <!DOCTYPE wml PUBLIC "//WAPFORUM//DTD WML 11//EN" "http://wwwwapforumorg/DTD/wml 11xml">"; response.setHeader("Cache-Control","no-cache"); out.println(head); String nev = String pswd = String xx = String yy = String terkep = String level = String nez = String mehet = String id = String update = int nezleft; request.getParameter("nev"); request.getParameter("pswd"); request.getParameter("x"); request.getParameter("y");
request.getParameter("terkep"); request.getParameter("level"); request.getParameter("nez"); request.getParameter("mehet"); request.getParameter("id "); request.getParameter("update"); - 99 - WAP alapú alkalmazás fejlesztése A játék dokumentálása int mehet; int nezright; boolean ellenseg=false,halott=false; int level; int nez; int x; int y; int terkep; String pont="no"; if (level ==null) level=1; else level=Integer.parseInt(level ); if (terkep ==null) terkep=0; else terkep=Integer.parseInt(terkep ); if (nez ==null) nez=1; else nez=Integer.parseInt(nez ); if (mehet ==null) mehet=0; else mehet=Integer.parseInt(mehet ); mehet =Integer.toString(mehet); labirintus.setlabirint(applicationgetRealPath("/data/level1dat")); if (xx==null | yy==null) { x=labirintus.getstartx(); y=labirintusgetstarty(); } else { x=Integer.parseInt(xx); y=IntegerparseInt(yy); } int x left,x right,x for,x back,y left,y
right,y for,y back; if (nez==1) { x left=x+1; y left=y; if (nez==2) { x left=x; y left=y-1; if (nez==3) { x left=x-1; y left=y; else { x left=x; y left=y+1; x right=x-1; y right=y; x right=x; y right=y+1; x right=x+1; y right=y; x for=x; y for=y+1; x for=x+1; y for=y; x for=x; y for=y-1; x back=x ; y back=y-1; } else x back=x-1; y back=y; } else x back=x; y back=y+1; } x right=x; x for=x-1; x back=x+1; y right=y-1; y for=y; y back=y; } nezleft=nez+1; if (nezleft>4) {nezleft=1;} nezright=nez-1; if (nezright<1) {nezright=4;} try { Class.forName("sunjdbcodbcJdbcOdbcDriver"); Connection con = DriverManager.getConnection("jdbc:odbc:"+ application.getInitParameter("ODBC")); Statement stmt = con.createStatement(); ResultSet rs; int i,j; rs = stmt.executeQuery("SELECT poziciox,pozicioy,azonosito FROM jatekosok WHERE poziciox="+x for+"AND pozicioy="+y for+" AND bentvan=true AND palya="+level +" AND
azonosito<>"+ id ); ellenseg=false; while (rs.next()) { i = rs.getInt(1); j = rs.getInt(2); ellenseg=true; } if (ellenseg==true) { mehet=0; mehet ="0";} PreparedStatement pstmt = con.prepareStatement("UPDATE jatekosok SET poziciox="+x+",pozicioy="+y+",nezet="+nez+",mehet="+mehet+",bentvan=true WHERE azonosito="+id ); pstmt.executeUpdate(); pstmt.close(); stmt = con.createStatement(); rs = stmt.executeQuery("SELECT frissites,halott,pont FROM jatekosok WHERE azonosito="+id ); rs.next(); halott=rs.getBoolean(2); pont=rs.getString(3); if (update == null) { update=rs.getString(1); stmt.close(); } else { stmt.close(); pstmt = con.prepareStatement("UPDATE jatekosok SET frissites="+update+" WHERE azonosito="+id ); pstmt.executeUpdate(); pstmt.close(); } - 100 - WAP alapú alkalmazás fejlesztése A játék dokumentálása if (halott == true) { pstmt = con.prepareStatement("UPDATE
jatekosok SET halott=false WHERE azonosito="+id ); pstmt.executeUpdate(); pstmt.close(); } con.close(); } catch (SQLException e ) {} catch (ClassNotFoundException e ) {} %> <wml> <% if (halott==false) { %> <card newcontext="true" id="game" title="<%=pont%> p."> <% if ((labirintus.getxy(x for,y for)!=1 && ellenseg==false)) { %> <onevent type="ontimer"> <go href="game.jsp" sendreferer="false" method="get"> <% if (mehet==1) { %> <postfield name="x" value="<%=x for%>"/> <postfield name="y" value="<%=y for%>"/> <% } else { %> <postfield name="x" value="<%=xx%>"/> <postfield name="y" value="<%=yy%>"/> <% } %> <postfield name="nez" value="<%=nez %>"/> <postfield name="level"
value="<%=level %>"/> <postfield name="terkep" value="<%=terkep %>"/> <postfield name="mehet" value="<%=mehet %>"/> <postfield name="nev" value="<%=nev%>"/> <postfield name="pswd" value="<%=pswd%>"/> <postfield name="id " value="<%=id %>"/> </go> </onevent> <% } else { %> <onevent type="ontimer"> <go href="game.jsp" sendreferer="false" method="get"> <postfield name="x" value="<%=xx%>"/> <postfield name="y" value="<%=yy%>"/> <postfield name="nez" value="<%=nez %>"/> <postfield name="level" value="<%=level %>"/> <postfield name="terkep" value="<%=terkep %>"/> <postfield
name="mehet" value="<%=mehet %>"/> <postfield name="nev" value="<%=nev%>"/> <postfield name="pswd" value="<%=pswd%>"/> <postfield name="id " value="<%=id %>"/> </go> </onevent> <% } %><timer value="<%=update%>"/> <p align="center"> <img alt="A labirintus" src="create.jsp?x=<%=x%>&y=<%=y%>&level=<%= level %> &map=<%=terkep %>&id =<%=id %>&nez=<%=nez %>"/><br/> <small> <table columns="4"> <tr> <td><anchor>Harc<br/> <go href="fight.jsp"> <postfield name="x" value="<%=x%>"/> <postfield name="y" value="<%=y%>"/> <postfield name="nez" value="<%=nez
%>"/> <postfield name="level" value="<%=level %>"/> <postfield name="terkep" value="<%=terkep %>"/> <postfield name="mehet" value="<%=mehet %>"/> <postfield name="nev" value="<%=nev%>"/> <postfield name="pswd" value="<%=pswd%>"/> <postfield name="id " value="<%=id %>"/> </go> </anchor></td> <td><anchor>Balra<br/> <go href="game.jsp" sendreferer="false" method="get"> <postfield name="x" value="<%=x%>"/> <postfield name="y" value="<%=y%>"/> <postfield name="nez" value="<%=nezleft%>"/> <postfield name="level" value="<%=level %>"/> <postfield name="terkep" value="<%=terkep
%>"/> <postfield name="mehet" value="<%=mehet %>"/> <postfield name="nev" value="<%=nev%>"/> - 101 - WAP alapú alkalmazás fejlesztése A játék dokumentálása <postfield name="pswd" value="<%=pswd%>"/> <postfield name="id " value="<%=id %>"/> </go> </anchor></td> <td><anchor>Jobbra<br/> <go href="game.jsp" sendreferer="false" method="get"> <postfield name="nev" value="<%=nev%>"/> <postfield name="pswd" value="<%=pswd%>"/> <postfield name="x" value="<%=x%>"/> <postfield name="y" value="<%=y%>"/> <postfield name="nez" value="<%=nezright%>"/> <postfield name="level" value="<%=level
%>"/> <postfield name="terkep" value="<%=terkep %>"/> <postfield name="mehet" value="<%=mehet %>"/> <postfield name="id " value="<%=id %>"/> </go> </anchor></td> <% if (mehet==1) { %> <td><anchor>Allj<br/> <go href="game.jsp" sendreferer="false" method="get"> <postfield name="nev" value="<%=nev%>"/> <postfield name="pswd" value="<%=pswd%>"/> <postfield name="x" value="<%=x%>"/> <postfield name="y" value="<%=y%>"/> <postfield name="nez" value="<%=nez %>"/> <postfield name="level" value="<%=level %>"/> <postfield name="terkep" value="<%=terkep %>"/> <postfield name="mehet"
value="0"/> <postfield name="id " value="<%=id %>"/> </go> </anchor></td> <% } else { %> <td><anchor>Futas<br/> <go href="game.jsp" sendreferer="false" method="get"> <postfield name="nev" value="<%=nev%>"/> <postfield name="pswd" value="<%=pswd%>"/> <postfield name="x" value="<%=x%>"/> <postfield name="y" value="<%=y%>"/> <postfield name="nez" value="<%=nez %>"/> <postfield name="level" value="<%=level %>"/> <postfield name="terkep" value="<%=terkep %>"/> <postfield name="mehet" value="1"/> <postfield name="id " value="<%=id %>"/> </go> </anchor></td> <% } %>
</tr></table></small> </p> <do type="accept" label="Kilepes"> <go href="kilepes.jsp" sendreferer="false" method="get"> <postfield name="nev" value="<%=nev%>"/> <postfield name="pswd" value="<%=pswd%>"/> <postfield name="id " value="<%=id %>"/> <postfield name="x" value="<%=xx%>"/> <postfield name="y" value="<%=yy%>"/> <postfield name="nez" value="<%=nez %>"/> <postfield name="level" value="<%=level %>"/> <postfield name="terkep" value="<%=terkep %>"/> <postfield name="mehet" value="<%=mehet %>"/> </go> </do> <do type="options" label="Frissites"> <go
href="frissites.jsp" sendreferer="false" method="get"> <postfield name="nev" value="<%=nev%>"/> <postfield name="frissites" value="<%=update%>"/> <postfield name="pswd" value="<%=pswd%>"/> <postfield name="id " value="<%=id %>"/> <postfield name="x" value="<%=xx%>"/> <postfield name="y" value="<%=yy%>"/> <postfield name="nez" value="<%=nez %>"/> <postfield name="level" value="<%=level %>"/> <postfield name="terkep" value="<%=terkep %>"/> - 102 - WAP alapú alkalmazás fejlesztése A játék dokumentálása <postfield name="mehet" value="<%=mehet %>"/> </go> </do> </card> <% } else { %> <card
id="Halott" title="Meghaltal"> <p align="center">Megoltek teged!<br/> <anchor>Kilepes<br/> <go href="labirintgame.jsp"/> </anchor></p> </card> <% } %> </wml> VIII7. CREATE.JAVA A szervlet feladata eloállítani a képet, mely a játékos elott megjelenik. A kép eloállítása a wbmp adatszerkezet segítségével történik. Ennek megfeleloen a kimenet típusa: String contentType = "image/vnd.wapwbmp"; A szervlet a képet a kapott x, y, level és néz paramétereknek megfeleloen készíti el. Természetesen használja az alkalmazás directory iniciális paraméterét, mely megadja, hogy hol található a labirintust tartalmazó level1.dat állomány A kép inicializálása: wbmp picture; picture = new wbmp(directory,Integer.parseInt(level),IntegerparseInt(nez)); picture.clear(); picture.putwindow(IntegerparseInt(x),IntegerparseInt(y));
picture.putwall(IntegerparseInt(x),IntegerparseInt(y)); A szervlet feladata a tárgyak helyének aktualizálása, azaz annak figyelése, hogy az összes azonos típusú tárgy elfogyott-e vagy sem. Ha elfogyott, akkor az összeset láthatóvá teszi Természetesen ezeket az adatbázisban végzi el: stmt.close(); stmt = con.createStatement(); rs = stmt.executeQuery("SELECT x,y,id FROM fegyver WHERE bentvan=true"); if (!rs.next()) { /* Ha nincsen fegyver, akkor az osszes targy megjelenitese / pstmt = con.prepareStatement("UPDATE fegyver SET bentvan=true WHERE bentvan=false"); pstmt.executeUpdate(); pstmt.close(); } stmt.close(); stmt = con.createStatement(); /* A pancelok megjelenitese / rs = stmt.executeQuery("SELECT x,y,id FROM pancel WHERE bentvan=true"); if (!rs.next()) { /* Ha nincsen pancel, akkor az osszes targy megjelenitese / pstmt = con.prepareStatement("UPDATE pancel SET bentvan=true WHERE bentvan=false"); pstmt.executeUpdate();
pstmt.close(); } Feladatai közé tartozik a labirintus térképének megjelenítése, és azokban a tárgyak, a játékos, valamint a többi játékos megjelenítése, továbbá az ellenség képének kirakása akkor, ha a játékos elotti helyen áll. A térkép megjelenítése: for (i=startx;i<endx+1;i++) { for (j=starty;j<endy+1;j++) { if (picture.labirintusgetxy(i,j) == 1) { picture.rectangle((i-startx)*5+64,(j-starty)5,(i-startx)5+5+64,(jstarty)5+5); } } } - 103 - WAP alapú alkalmazás fejlesztése A játék dokumentálása A startx, starty, endx, endy nem jelent mást, mint azon koordinátákat tartalmazó négyzet két szemközti csúcsa, melyek a játékos aktuális pozíciójától maximum 2 helyre vannak, azaz: int int int int startx starty endx endy = = = = Integer.parseInt(x)-2; Integer.parseInt(y)-2; Integer.parseInt(x)+2; Integer.parseInt(y)+2; Az ellenségek helyének lekérdezése – és kirakása, ha elotte van –, valamint jelzése a térképen:
rs = stmt.executeQuery("SELECT poziciox,pozicioy FROM jatekosok WHERE poziciox>="+startx+" AND poziciox<="+endx+" AND pozicioy>="+starty+" AND pozicioy<="+endy+" AND bentvan=true AND palya="+Integer.parseInt(level)+" AND azonosito<>"+id ); while (rs.next()) { i = rs.getInt(1); j = rs.getInt(2); /* térképre rajzolása / picture.rectangle((i-startx)*5+64+2,(j-starty)5+2,(i-startx)5+3+64,(jstarty)5+3); if ((x for==i)&&(y for==j)) { /* Kis .pic kép kirajzolasa */ picture.getenemy(directory+"/enemy2pic"); picture.putenemy(20,10); } } A tárgyak felvétele a játékos számára automatikusan történik, vagyis amikor az aktuális pozícióban valamilyen tárgy van, akkor az automatikusan megnöveli a megfelelo szintet, és természetesen a tárgy eltunik: /* Fegyver / stmt.close(); stmt = con.createStatement(); rs = stmt.executeQuery("SELECT x,y,id FROM fegyver WHERE
x>="+startx+" AND x<="+endx+" AND y>="+starty+" AND y<="+endy+" AND bentvan=true"); int id =0,k=0; while (rs.next()) { i = rs.getInt(1); j = rs.getInt(2); k = rs.getInt(3); if ((Integer.parseInt(x)==i)&&(IntegerparseInt(y)==j)) { if (ero==100) { k = 0 ; } if (ero+5>100) { ero= 100; } else { ero= ero+5;} pstmt = con.prepareStatement("UPDATE jatekosok SET ero="+ero+" WHERE azonosito="+id ); pstmt.executeUpdate(); pstmt.close(); id =k; } picture.rectangle((i-startx)*5+64+2,(j-starty)5+2,(i-startx)5+3+64,(jstarty)5+3); } stmt.close(); stmt = con.createStatement(); /* A felvett eszkoz "lathatatlanna tetele" / if (id !=0) { pstmt = con.prepareStatement("UPDATE fegyver SET bentvan=false WHERE id="+id ); pstmt.executeUpdate(); pstmt.close(); } /* Pancel / stmt.close(); stmt = con.createStatement(); rs = stmt.executeQuery("SELECT x,y,id FROM pancel WHERE
x>="+startx+" AND x<="+endx+" AND y>="+starty+" AND y<="+endy+" AND bentvan=true"); id =0;k=0; - 104 - WAP alapú alkalmazás fejlesztése A játék dokumentálása while (rs.next()) { i = rs.getInt(1); j = rs.getInt(2); k = rs.getInt(3); if ((Integer.parseInt(x)==i)&&(IntegerparseInt(y)==j)) { if (vedelem==100) {k=0 ; } if (vedelem+5>100) {vedelem=100; } else {vedelem=vedelem+5; } pstmt = con.prepareStatement("UPDATE jatekosok SET vedelem=" + vedelem + " WHERE azonosito="+id ); pstmt.executeUpdate(); pstmt.close(); id =k; } picture.rectangle((i-startx)*5+64+2,(j-starty)5+2,(i-startx)5+3+64,(jstarty)5+3); } stmt.close(); stmt = con.createStatement(); /* A felvett eszkoz "lathatatlanna tetele" / if (id !=0) { pstmt = con.prepareStatement("UPDATE pancel SET bentvan=false WHERE id="+id ); pstmt.executeUpdate(); pstmt.close(); } Meg kell még jeleníteni a játékos két
tulajdonságát. Ahhoz azonban azokat le kell kérdezni: stmt.close(); stmt = con.createStatement(); rs = stmt.executeQuery("SELECT ero,vedelem FROM jatekosok WHERE azonosito="+id ); ero=0;vedelem=0; if (rs.next()) { ero=rs.getInt(1); vedelem=rs.getInt(2); } Ezek után már meg lehet jeleníteni: /* Az ero es vedelem megjelenitese / picture.rectangle(70,29,90,32); lo = new Double(70+20.0/1000*ero); picture.rectangle(70,30,lointValue(),31); picture.rectangle(70,34,90,37); lo = new Double(70+20.0/1000*vedelem); picture.rectangle(70,35,lointValue(),36); A legutolsó feladat pedig a térképen egy nyíl kirajzolása, mely mutatja, hogy a játékos merre néz: if (Integer.parseInt(nez)==1) { picture.setPoint((xxx-startx)*4+4+64,(yyy-starty)4+2); picture.setPoint((xxx-startx)*4+4+64,(yyy-starty)4+3); picture.setPoint((xxx-startx)*4+4+64,(yyy-starty)4+4); picture.setPoint((xxx-startx)*4+4+64,(yyy-starty)4+5); picture.setPoint((xxx-startx)*4+4+64,(yyy-starty)4+6);
picture.setPoint((xxx-startx)*4+5+64,(yyy-starty)4+5); picture.setPoint((xxx-startx)*4+6+64,(yyy-starty)4+4); picture.setPoint((xxx-startx)*4+3+64,(yyy-starty)4+5); picture.setPoint((xxx-startx)*4+2+64,(yyy-starty)4+4); } if (Integer.parseInt(nez)==2) { picture.setPoint((xxx-startx)*4+2+64,(yyy-starty)4+4); picture.setPoint((xxx-startx)*4+3+64,(yyy-starty)4+4); picture.setPoint((xxx-startx)*4+4+64,(yyy-starty)4+4); picture.setPoint((xxx-startx)*4+5+64,(yyy-starty)4+4); picture.setPoint((xxx-startx)*4+6+64,(yyy-starty)4+4); picture.setPoint((xxx-startx)*4+5+64,(yyy-starty)4+5); picture.setPoint((xxx-startx)*4+4+64,(yyy-starty)4+6); picture.setPoint((xxx-startx)*4+5+64,(yyy-starty)4+3); picture.setPoint((xxx-startx)*4+4+64,(yyy-starty)4+2); } if (Integer.parseInt(nez)==3) { - 105 - WAP alapú alkalmazás fejlesztése A játék dokumentálása picture.setPoint((xxx-startx)*4+4+64,(yyy-starty)4+3); picture.setPoint((xxx-startx)*4+4+64,(yyy-starty)4+4);
picture.setPoint((xxx-startx)*4+4+64,(yyy-starty)4+5); picture.setPoint((xxx-startx)*4+4+64,(yyy-starty)4+6); picture.setPoint((xxx-startx)*4+4+64,(yyy-starty)4+7); picture.setPoint((xxx-startx)*4+5+64,(yyy-starty)4+3); picture.setPoint((xxx-startx)*4+6+64,(yyy-starty)4+4); picture.setPoint((xxx-startx)*4+3+64,(yyy-starty)4+3); picture.setPoint((xxx-startx)*4+2+64,(yyy-starty)4+4); } if (Integer.parseInt(nez)==4) { picture.setPoint((xxx-startx)*4+3+64,(yyy-starty)4+4); picture.setPoint((xxx-startx)*4+4+64,(yyy-starty)4+4); picture.setPoint((xxx-startx)*4+5+64,(yyy-starty)4+4); picture.setPoint((xxx-startx)*4+6+64,(yyy-starty)4+4); picture.setPoint((xxx-startx)*4+7+64,(yyy-starty)4+4); picture.setPoint((xxx-startx)*4+3+64,(yyy-starty)4+5); picture.setPoint((xxx-startx)*4+4+64,(yyy-starty)4+6); picture.setPoint((xxx-startx)*4+3+64,(yyy-starty)4+3); picture.setPoint((xxx-startx)*4+4+64,(yyy-starty)4+2); } A forráskód egyben: import import import import import java.sql*; java.io*;
java.util*; javax.servlet*; javax.servlethttp*; public class create extends HttpServlet{ String contentType = "image/vnd.wapwbmp"; HttpServletResponse response; ByteArrayOutputStream bytes; String encoding; OutputStreamWriter w; String directory; String database; void init(HttpServletResponse resp) throws ServletException, IOException { ServletContext context=getServletContext(); response = resp; response.setContentType(contentType); response.setHeader("Cache-Control","no-cache"); encoding = response.getCharacterEncoding (); bytes = new ByteArrayOutputStream (4096); directory = context.getRealPath( "/data" ); database = context.getInitParameter("ODBC"); } void close() throws ServletException, IOException{ response.setContentLength (bytessize ()); try { bytes.writeTo (responsegetOutputStream ()); } catch (Exception e) { e.printStackTrace ();} } public void doGet ( HttpServletRequest request, HttpServletResponse resp ) throws
ServletException, IOException { String x = request.getParameter("x"); // A jatekos x pozicioja String y = request.getParameter("y"); // A jatekos y pozicioja String level = request.getParameter("level"); // A palya szama String nez = request.getParameter("nez"); // A jatekos merre nez? String map = request.getParameter("map"); // Van-e terkep? String id = request.getParameter("id "); // Mi a jatekos azonositoja? int map; if (level==null) level="1"; if (map ==null) map=0; else map=Integer.parseInt(map ); - 106 - WAP alapú alkalmazás fejlesztése A játék dokumentálása if (nez==null) nez="1"; init(resp); wbmp picture; if (x==null | y==null) { picture = new wbmp(directory); x=Integer.toString(picturelabirintusstartx); y=Integer.toString(picturelabirintusstarty); } else picture = new wbmp(directory,Integer.parseInt(level),IntegerparseInt(nez)); picture.clear();
picture.putwindow(IntegerparseInt(x),IntegerparseInt(y)); picture.putwall(IntegerparseInt(x),IntegerparseInt(y)); if (map!=0) { int xxx,yyy; for (int i=0;i<26;i++) for (int j=0;j<26;j++) picture.clearPoint(i+64,j); xxx = Integer.parseInt(x);yyy=IntegerparseInt(y); int ero,vedelem; int startx = Integer.parseInt(x)-2; int starty = Integer.parseInt(y)-2; int endx = Integer.parseInt(x)+2; int endy = Integer.parseInt(y)+2; int x for,y for,i,j; if (startx<0) {startx=0;endx=4;} if (starty<0) {starty=0;endy=4;} if (endx>picture.labirintuslength) endx=picturelabirintuslength; if (endy>picture.labirintuswidth) endy=picturelabirintuswidth; picture.rectangle(0+64,0,25+64,25); Double lo; if (Integer.parseInt(nez)==1) { x for = xxx ; y for=yyy+1; } else if (Integer.parseInt(nez)==2) { x for = xxx+1; y for=yyy ; } else if (Integer.parseInt(nez)==3) { x for = xxx ; y for=yyy-1; } else { x for=xxx-1; y for=yyy;} try { Class.forName("sunjdbcodbcJdbcOdbcDriver"); Connection
con = DriverManager.getConnection("jdbc:odbc:"+database); Statement stmt = con.createStatement(); ResultSet rs; PreparedStatement pstmt; for (i=startx;i<endx+1;i++) { for (j=starty;j<endy+1;j++) { if (picture.labirintusgetxy(i,j) == 1) { picture.rectangle((i-startx)*5+64,(j-starty)5,(i-startx)5+5+64,(jstarty)5+5); } } } /* Tobbi jatekos mekeresese / rs = stmt.executeQuery("SELECT poziciox,pozicioy FROM jatekosok WHERE poziciox>="+startx+" AND poziciox<="+endx+" AND pozicioy>="+starty+" AND pozicioy<="+endy+" AND bentvan=true AND palya="+Integer.parseInt(level)+" AND azonosito<>"+id ); while (rs.next()) { i = rs.getInt(1); j = rs.getInt(2); picture.rectangle((i-startx)*5+64+2,(j-starty)5+2,(i-startx)5+3+64,(jstarty)5+3); if ((x for==i)&&(y for==j)) { /* Kis .pic kép kirajzolasa */ picture.getenemy(directory+"/enemy2pic"); picture.putenemy(20,10); } } - 107 - WAP alapú
alkalmazás fejlesztése A játék dokumentálása /* A fegyverek megjelenitese / stmt.close(); stmt = con.createStatement(); rs = stmt.executeQuery("SELECT x,y,id FROM fegyver WHERE bentvan=true"); if (!rs.next()) { /* Ha nincsen fegyver, akkor az osszes targy megjelenitese / pstmt = con.prepareStatement("UPDATE fegyver SET bentvan=true WHERE bentvan=false"); pstmt.executeUpdate(); pstmt.close(); } stmt.close(); stmt = con.createStatement(); /* A pancelok megjelenitese / rs = stmt.executeQuery("SELECT x,y,id FROM pancel WHERE bentvan=true"); if (!rs.next()) { /* Ha nincsen pancel, akkor az osszes targy megjelenitese / pstmt = con.prepareStatement("UPDATE pancel SET bentvan=true WHERE bentvan=false"); pstmt.executeUpdate(); pstmt.close(); } stmt.close(); stmt = con.createStatement(); rs = stmt.executeQuery("SELECT ero,vedelem FROM jatekosok WHERE azonosito="+id ); ero=0;vedelem=0; if (rs.next()) { ero=rs.getInt(1);
vedelem=rs.getInt(2); } /* Fegyver / stmt.close(); stmt = con.createStatement(); rs = stmt.executeQuery("SELECT x,y,id FROM fegyver WHERE x>="+startx+" AND x<="+endx+" AND y>="+starty+" AND y<="+endy+" AND bentvan=true"); int id =0,k=0; while (rs.next()) { i = rs.getInt(1); j = rs.getInt(2); k = rs.getInt(3); if ((Integer.parseInt(x)==i)&&(IntegerparseInt(y)==j)) { if (ero==100) { k = 0 ; } if (ero+5>100) { ero= 100; } else { ero= ero+5;} pstmt = con.prepareStatement("UPDATE jatekosok SET ero="+ero+" WHERE azonosito="+id ); pstmt.executeUpdate(); pstmt.close(); id =k; } picture.rectangle((i-startx)*5+64+2,(j-starty)5+2,(i-startx)5+3+64,(jstarty)5+3); } stmt.close(); stmt = con.createStatement(); /* A felvett eszkoz "lathatatlanna tetele" / if (id !=0) { pstmt = con.prepareStatement("UPDATE fegyver SET bentvan=false WHERE id="+id ); pstmt.executeUpdate(); pstmt.close(); }
/* Pancel / stmt.close(); stmt = con.createStatement(); rs = stmt.executeQuery("SELECT x,y,id FROM pancel WHERE x>="+startx+" AND x<="+endx+" AND y>="+starty+" AND y<="+endy+" AND bentvan=true"); id =0;k=0; while (rs.next()) { i = rs.getInt(1); j = rs.getInt(2); k = rs.getInt(3); - 108 - WAP alapú alkalmazás fejlesztése A játék dokumentálása if ((Integer.parseInt(x)==i)&&(IntegerparseInt(y)==j)) { if (vedelem==100) {k=0 ; } if (vedelem+5>100) {vedelem=100; } else {vedelem=vedelem+5; } pstmt = con.prepareStatement("UPDATE jatekosok SET vedelem="+ vedelem+" WHERE azonosito="+id ); pstmt.executeUpdate(); pstmt.close(); id =k; } picture.rectangle((i-startx)*5+64+2,(j-starty)5+2,(i-startx)5+3+64,(jstarty)5+3); } stmt.close(); stmt = con.createStatement(); /* A felvett eszkoz "lathatatlanna tetele" / if (id !=0) { pstmt = con.prepareStatement("UPDATE pancel SET
bentvan=false WHERE id="+id ); pstmt.executeUpdate(); pstmt.close(); } /* Az ero es vedelem megjelenitese / picture.rectangle(70,29,90,32); lo = new Double(70+20.0/1000*ero); picture.rectangle(70,30,lointValue(),31); picture.rectangle(70,34,90,37); lo = new Double(70+20.0/1000*vedelem); picture.rectangle(70,35,lointValue(),36); stmt.close(); con.close(); } catch (SQLException e ) {} catch (ClassNotFoundException e ) {} if (Integer.parseInt(nez)==1) { picture.setPoint((xxx-startx)*4+4+64,(yyy-starty)4+2); picture.setPoint((xxx-startx)*4+4+64,(yyy-starty)4+3); picture.setPoint((xxx-startx)*4+4+64,(yyy-starty)4+4); picture.setPoint((xxx-startx)*4+4+64,(yyy-starty)4+5); picture.setPoint((xxx-startx)*4+4+64,(yyy-starty)4+6); picture.setPoint((xxx-startx)*4+5+64,(yyy-starty)4+5); picture.setPoint((xxx-startx)*4+6+64,(yyy-starty)4+4); picture.setPoint((xxx-startx)*4+3+64,(yyy-starty)4+5); picture.setPoint((xxx-startx)*4+2+64,(yyy-starty)4+4); } if (Integer.parseInt(nez)==2) {
picture.setPoint((xxx-startx)*4+2+64,(yyy-starty)4+4); picture.setPoint((xxx-startx)*4+3+64,(yyy-starty)4+4); picture.setPoint((xxx-startx)*4+4+64,(yyy-starty)4+4); picture.setPoint((xxx-startx)*4+5+64,(yyy-starty)4+4); picture.setPoint((xxx-startx)*4+6+64,(yyy-starty)4+4); picture.setPoint((xxx-startx)*4+5+64,(yyy-starty)4+5); picture.setPoint((xxx-startx)*4+4+64,(yyy-starty)4+6); picture.setPoint((xxx-startx)*4+5+64,(yyy-starty)4+3); picture.setPoint((xxx-startx)*4+4+64,(yyy-starty)4+2); } if (Integer.parseInt(nez)==3) { picture.setPoint((xxx-startx)*4+4+64,(yyy-starty)4+3); picture.setPoint((xxx-startx)*4+4+64,(yyy-starty)4+4); picture.setPoint((xxx-startx)*4+4+64,(yyy-starty)4+5); picture.setPoint((xxx-startx)*4+4+64,(yyy-starty)4+6); picture.setPoint((xxx-startx)*4+4+64,(yyy-starty)4+7); picture.setPoint((xxx-startx)*4+5+64,(yyy-starty)4+3); picture.setPoint((xxx-startx)*4+6+64,(yyy-starty)4+4); picture.setPoint((xxx-startx)*4+3+64,(yyy-starty)4+3);
picture.setPoint((xxx-startx)*4+2+64,(yyy-starty)4+4); } if (Integer.parseInt(nez)==4) { picture.setPoint((xxx-startx)*4+3+64,(yyy-starty)4+4); picture.setPoint((xxx-startx)*4+4+64,(yyy-starty)4+4); picture.setPoint((xxx-startx)*4+5+64,(yyy-starty)4+4); - 109 - WAP alapú alkalmazás fejlesztése A játék dokumentálása picture.setPoint((xxx-startx)*4+6+64,(yyy-starty)4+4); picture.setPoint((xxx-startx)*4+7+64,(yyy-starty)4+4); picture.setPoint((xxx-startx)*4+3+64,(yyy-starty)4+5); picture.setPoint((xxx-startx)*4+4+64,(yyy-starty)4+6); picture.setPoint((xxx-startx)*4+3+64,(yyy-starty)4+3); picture.setPoint((xxx-startx)*4+4+64,(yyy-starty)4+2); } } /* A kep elkuldese.*/ picture.flush(bytes); close(); } } A megfelelo JSP oldal: <%@ page import="java.sql*,jspwbmp,java.io*" contentType="image/vnd.wapwbmp"%><jsp:useBean id="picture" scope="session" class="jspwbmp"/><%
response.setHeader("Cache-Control","no-cache"); String x = request.getParameter("x"); String y = request.getParameter("y"); String level = request.getParameter("level"); String nez = request.getParameter("nez"); String map = request.getParameter("map"); String id = request.getParameter("id "); int map; if (level==null) level="1"; if (map ==null) map=0; else map=Integer.parseInt(map ); if (nez==null) nez="1"; if (x==null | y==null) { picture.setwbmp(applicationgetRealPath("/data/level1dat")); x=Integer.toString(picturegetlabirintus()getstartx()); y=Integer.toString(picturegetlabirintus()getstarty()); } else picture.setwbmp(applicationgetRealPath("/data/level1dat"), Integer.parseInt(level),IntegerparseInt(nez)); picture.clear(); picture.putwindow(IntegerparseInt(x),IntegerparseInt(y)); picture.putwall(IntegerparseInt(x),IntegerparseInt(y)); if (map!=0) { int xxx,yyy;
for (int i=0;i<26;i++) for (int j=0;j<26;j++) picture.clearPoint(i+64,j); xxx = Integer.parseInt(x);yyy=IntegerparseInt(y); int ero,vedelem; int startx = Integer.parseInt(x)-2; int starty = Integer.parseInt(y)-2; int endx = Integer.parseInt(x)+2; int endy = Integer.parseInt(y)+2; int x for,y for,i,j; if (startx<0) {startx=0;endx=4;} if (starty<0) {starty=0;endy=4;} if (endx>picture.getlabirintus()getlength()) endx=picture.getlabirintus()getlength(); if (endy>picture.getlabirintus()getwidth()) endy=picture.getlabirintus()getwidth(); picture.rectangle(0+64,0,25+64,25); Double lo; if (Integer.parseInt(nez)==1) { x for = xxx ; y for=yyy+1; } else if (Integer.parseInt(nez)==2) { x for = xxx+1; y for=yyy ; } else if (Integer.parseInt(nez)==3) { x for = xxx ; y for=yyy-1; } else { x for=xxx-1; y for=yyy;} try { Class.forName("sunjdbcodbcJdbcOdbcDriver"); Connection con = DriverManager.getConnection("jdbc:odbc:"+
application.getInitParameter("ODBC")); Statement stmt = con.createStatement(); - 110 - WAP alapú alkalmazás fejlesztése A játék dokumentálása ResultSet rs; PreparedStatement pstmt; for (i=startx;i<endx+1;i++) { for (j=starty;j<endy+1;j++) { if (picture.getlabirintus()getxy(i,j) == 1) { picture.rectangle((i-startx)*5+64,(j-starty)5,(i-startx)5+5+64,(jstarty)5+5); } } } /* Tobbi jatekos mekeresese / rs = stmt.executeQuery("SELECT poziciox,pozicioy FROM jatekosok WHERE poziciox>="+startx+" AND poziciox<="+endx+" AND pozicioy>="+starty+" AND pozicioy<="+endy+" AND bentvan=true AND palya="+Integer.parseInt(level)+" AND azonosito<>"+id ); while (rs.next()) { i = rs.getInt(1); j = rs.getInt(2); picture.rectangle((i-startx)*5+64+2,(j-starty)5+2,(i-startx)5+3+64,(jstarty)5+3); if ((x for==i)&&(y for==j)) { /* Kis .pic kép kirajzolasa */
picture.getenemy("c:/data/enemy2pic"); picture.putenemy(20,10); } } /* A fegyverek megjelenitese / stmt.close(); stmt = con.createStatement(); rs = stmt.executeQuery("SELECT x,y,id FROM fegyver WHERE bentvan=true"); if (!rs.next()) { /* Ha nincsen fegyver, akkor az osszes targy megjelenitese / pstmt = con.prepareStatement("UPDATE fegyver SET bentvan=true WHERE bentvan=false "); pstmt.executeUpdate(); pstmt.close(); } stmt.close(); stmt = con.createStatement(); /* A pancelok megjelenitese / rs = stmt.executeQuery("SELECT x,y,id FROM pancel WHERE bentvan=true"); if (!rs.next()) { /* Ha nincsen pancel, akkor az osszes targy megjelenitese / pstmt = con.prepareStatement("UPDATE pancel SET bentvan=true WHERE bentvan=false "); pstmt.executeUpdate(); pstmt.close(); } stmt.close(); stmt = con.createStatement(); rs = stmt.executeQuery("SELECT ero,vedelem FROM jatekosok WHERE azonosito="+id ); ero=0;vedelem=0; if (rs.next()) {
ero=rs.getInt(1); vedelem=rs.getInt(2); } /* Fegyver / stmt.close(); stmt = con.createStatement(); rs = stmt.executeQuery("SELECT x,y,id FROM fegyver WHERE x>="+startx+" AND x<="+endx+" AND y>="+starty+" AND y<="+endy+" AND bentvan=true"); int id =0,k=0; while (rs.next()) { i = rs.getInt(1); j = rs.getInt(2); k = rs.getInt(3); if ((Integer.parseInt(x)==i)&&(IntegerparseInt(y)==j)) { if (ero==100) { k = 0 ; } if (ero+5>100) { ero= 100; } else { ero= ero+5;} - 111 - WAP alapú alkalmazás fejlesztése A játék dokumentálása pstmt = con.prepareStatement("UPDATE jatekosok SET ero="+ero+" WHERE azonosito="+id ); pstmt.executeUpdate(); pstmt.close(); id =k; } picture.rectangle((i-startx)*5+64+2,(j-starty)5+2,(i-startx)5+3+64,(jstarty)5+3); } stmt.close(); stmt = con.createStatement(); /* A felvett eszkoz "lathatatlanna tetele" / if (id !=0) { pstmt =
con.prepareStatement("UPDATE fegyver SET bentvan=false WHERE id="+id ); pstmt.executeUpdate(); pstmt.close(); } /* Pancel / stmt.close(); stmt = con.createStatement(); rs = stmt.executeQuery("SELECT x,y,id FROM pancel WHERE x>="+startx+" AND x<="+endx+" AND y>="+starty+" AND y<="+endy+" AND bentvan=true"); id =0;k=0; while (rs.next()) { i = rs.getInt(1); j = rs.getInt(2); k = rs.getInt(3); if ((Integer.parseInt(x)==i)&&(IntegerparseInt(y)==j)) { if (vedelem==100) {k=0 ; } if (vedelem+5>100) {vedelem=100; } else {vedelem=vedelem+5; } pstmt = con.prepareStatement("UPDATE jatekosok SET vedelem="+vedelem+" WHERE azonosito="+id ); pstmt.executeUpdate(); pstmt.close(); id =k; } picture.rectangle((i-startx)*5+64+2,(j-starty)5+2,(i-startx)5+3+64,(jstarty)5+3); } stmt.close(); stmt = con.createStatement(); /* A felvett eszkoz "lathatatlanna tetele" / if (id !=0) { pstmt =
con.prepareStatement("UPDATE pancel SET bentvan=false WHERE id="+id ); pstmt.executeUpdate(); pstmt.close(); } /* Az ero es vedelem megjelenitese / picture.rectangle(70,29,90,32); lo = new Double(70+20.0/1000*ero); picture.rectangle(70,30,lointValue(),31); picture.rectangle(70,34,90,37); lo = new Double(70+20.0/1000*vedelem); picture.rectangle(70,35,lointValue(),36); stmt.close(); con.close(); } catch (SQLException e ) {} catch (ClassNotFoundException e ) {} if (Integer.parseInt(nez)==1) { picture.setPoint((xxx-startx)*4+4+64,(yyy-starty)4+2); picture.setPoint((xxx-startx)*4+4+64,(yyy-starty)4+3); picture.setPoint((xxx-startx)*4+4+64,(yyy-starty)4+4); picture.setPoint((xxx-startx)*4+4+64,(yyy-starty)4+5); picture.setPoint((xxx-startx)*4+4+64,(yyy-starty)4+6); - 112 - WAP alapú alkalmazás fejlesztése A játék dokumentálása picture.setPoint((xxx-startx)*4+5+64,(yyy-starty)4+5); picture.setPoint((xxx-startx)*4+6+64,(yyy-starty)4+4);
picture.setPoint((xxx-startx)*4+3+64,(yyy-starty)4+5); picture.setPoint((xxx-startx)*4+2+64,(yyy-starty)4+4); } if (Integer.parseInt(nez)==2) { picture.setPoint((xxx-startx)*4+2+64,(yyy-starty)4+4); picture.setPoint((xxx-startx)*4+3+64,(yyy-starty)4+4); picture.setPoint((xxx-startx)*4+4+64,(yyy-starty)4+4); picture.setPoint((xxx-startx)*4+5+64,(yyy-starty)4+4); picture.setPoint((xxx-startx)*4+6+64,(yyy-starty)4+4); picture.setPoint((xxx-startx)*4+5+64,(yyy-starty)4+5); picture.setPoint((xxx-startx)*4+4+64,(yyy-starty)4+6); picture.setPoint((xxx-startx)*4+5+64,(yyy-starty)4+3); picture.setPoint((xxx-startx)*4+4+64,(yyy-starty)4+2); } if (Integer.parseInt(nez)==3) { picture.setPoint((xxx-startx)*4+4+64,(yyy-starty)4+3); picture.setPoint((xxx-startx)*4+4+64,(yyy-starty)4+4); picture.setPoint((xxx-startx)*4+4+64,(yyy-starty)4+5); picture.setPoint((xxx-startx)*4+4+64,(yyy-starty)4+6); picture.setPoint((xxx-startx)*4+4+64,(yyy-starty)4+7);
picture.setPoint((xxx-startx)*4+5+64,(yyy-starty)4+3); picture.setPoint((xxx-startx)*4+6+64,(yyy-starty)4+4); picture.setPoint((xxx-startx)*4+3+64,(yyy-starty)4+3); picture.setPoint((xxx-startx)*4+2+64,(yyy-starty)4+4); } if (Integer.parseInt(nez)==4) { picture.setPoint((xxx-startx)*4+3+64,(yyy-starty)4+4); picture.setPoint((xxx-startx)*4+4+64,(yyy-starty)4+4); picture.setPoint((xxx-startx)*4+5+64,(yyy-starty)4+4); picture.setPoint((xxx-startx)*4+6+64,(yyy-starty)4+4); picture.setPoint((xxx-startx)*4+7+64,(yyy-starty)4+4); picture.setPoint((xxx-startx)*4+3+64,(yyy-starty)4+5); picture.setPoint((xxx-startx)*4+4+64,(yyy-starty)4+6); picture.setPoint((xxx-startx)*4+3+64,(yyy-starty)4+3); picture.setPoint((xxx-startx)*4+4+64,(yyy-starty)4+2); } } /* A kep elkuldese.*/ out.write(picturegetlength()); out.write(picturegetwidth()); int ay = 0; int ax = 0; int b,i; while (ay < picture.getwidth()) { b = 0; for (i=1;i<9;i++) { b = b * 2 + picture.getdata(ax,ay); ax = ax + 1; } if (ax >=
picture.getlength()) { ax = 0; ay = ay + 1; } out.write(b); } %> VIII8. KILEPES.JAVA A szervlet feladata a játékos kilépésének adminisztrálása, azaz az adatbázisban a játékoshoz tartozó sorban a „bentvan” mezo „false”-ra állítódik. A szervlet szintén megkapja a szokásos paramétereket: String String String String String String String String String nev password x y nez level terkep mehet id = = = = = = = = = request.getParameter("nev"); request.getParameter("pswd"); request.getParameter("x"); request.getParameter("y"); request.getParameter("nez"); request.getParameter("level"); request.getParameter("terkep"); request.getParameter("mehet"); request.getParameter("id "); Az adminisztrációs programrészlet: - 113 - WAP alapú alkalmazás fejlesztése A játék dokumentálása PreparedStatement pstmt = con.prepareStatement("UPDATE jatekosok SET
bentvan=false WHERE azonosito="+id ); pstmt.executeUpdate(); pstmt.close(); con.close(); A szervlet kimenete egy WML oldal, mely a játékost informálja a kilépés sikerességérol, és felkínálja a játék folytatását, valamint a kezdo oldalra való visszalépést: A forráskód: import import import import import java.sql*; java.io*; java.util*; javax.servlet*; javax.servlethttp*; public class kilepes extends HttpServlet{ String head ="<?xml version="1.0"?> <!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN" "http://wwwwapforumorg/DTD/wml 11xml">"; String contentType = "text/vnd.wapwml"; HttpServletResponse response; ByteArrayOutputStream bytes; String encoding; OutputStreamWriter w; PrintWriter out; String database; String appl; void init(HttpServletResponse resp) throws ServletException, IOException { ServletContext context=getServletContext(); response = resp; response.setContentType(contentType);
response.setHeader("Cache-Control","no-cache"); encoding = response.getCharacterEncoding (); bytes = new ByteArrayOutputStream (8192); w = new OutputStreamWriter (bytes, encoding); out = new PrintWriter (w); database = context.getInitParameter("ODBC"); appl = context.getInitParameter("application"); } void close() throws ServletException, IOException{ out.flush (); response.setContentLength (bytessize ()); try {bytes.writeTo (responsegetOutputStream ()); } catch (Exception e) {e.printStackTrace ();} } public void doPost ( HttpServletRequest HttpServletResponse request, resp) throws ServletException, IOException {} public void doGet ( HttpServletRequest request, HttpServletResponse resp ) throws ServletException, IOException { init(resp); out.println(head); out.println("<wml>"); out.print("<card id="Kilepes">"); out.println("<p align="center">"); - 114 - WAP alapú
alkalmazás fejlesztése try { String String String String String String String String String nev password x y nez level terkep mehet id = = = = = = = = = A játék dokumentálása request.getParameter("nev"); request.getParameter("pswd"); request.getParameter("x"); request.getParameter("y"); request.getParameter("nez"); request.getParameter("level"); request.getParameter("terkep"); request.getParameter("mehet"); request.getParameter("id "); Class.forName("sunjdbcodbcJdbcOdbcDriver"); Connection con = DriverManager.getConnection("jdbc:odbc:"+database); Statement stmt = con.createStatement(); out.println("ALLAPOT ELMENTESE<br/>"); PreparedStatement pstmt = con.prepareStatement("UPDATE jatekosok SET bentvan=false WHERE azonosito="+id ); pstmt.executeUpdate(); pstmt.close(); con.close(); out.println("SIKERULT ELMENTENI<br/>");
out.println("<anchor>Jatek folytatasa<br/>"); out.println("<go href="/"+appl+"/servlet/game" sendreferer="false" method="get">"); out.println("<postfield name="id " value=""+id +""/>"); out.println("<postfield name="nev" value=""+nev+""/>"); out.println("<postfield name="pswd" value=""+password+""/>"); out.println("<postfield name="x" value=""+x+""/>"); out.println("<postfield name="y" value=""+y+""/>"); out.println("<postfield name="level" value=""+level+""/>"); out.println("<postfield name="nez" value=""+nez+""/>"); out.println("<postfield name="terkep"
value=""+terkep+""/>"); out.println("<postfield name="mehet" value=""+mehet+""/>"); out.println("</go>"); out.println("</anchor><br/>"); out.println("<anchor>Kilepes a jatekbol<br/>"); out.println("<go href="/"+appl+"/servlet/labirintgame" sendreferer="false" method="get">"); out.println("</go>"); out.println("</anchor><br/>"); } catch (SQLException e ) {} catch (ClassNotFoundException e ) {} out.println("</p>"); out.println("</card>"); out.println("</wml>"); close(); } } A szervlet kimenete: <?xml version="1.0"?> <!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN" "http://wwwwapforumorg/DTD/wml 11xml"> <wml> <card id="Kilepes"> <p
align="center"> ALLAPOT ELMENTESE <br/> SIKERULT ELMENTENI <br/> <anchor>Jatek folytatasa<br/> <go href="/labirintus/servlet/game" sendreferer="false" method="get"> <postfield name="id " value="4"/> <postfield name="nev" value=""/> <postfield name="pswd" value=""/> <postfield name="x" value="60"/> <postfield name="y" value="67"/> <postfield name="level" value="1"/> <postfield name="nez" value="2"/> - 115 - WAP alapú alkalmazás fejlesztése A játék dokumentálása <postfield name="terkep" value="1"/> <postfield name="mehet" value="0"/> </go></anchor> <br/> <anchor>Kilepes a jatekbol<br/> <go href="/labirintus/servlet/labirintgame"
sendreferer="false" method="get"/> </anchor> <br/> </p> </card> </wml> A következoképpen néz ki a szervletnek megfelelo JSP oldal: <%@ page import="java.sql*" contentType="text/vnd.wapwml"%><% String head ="<?xml version="1.0"?> <!DOCTYPE wml PUBLIC "//WAPFORUM//DTD WML 11//EN" "http://www.wapforumorg/DTD/wml 11xml">"; response.setHeader("Cache-Control","no-cache"); out.println(head); %> <wml> <card id="Kilepes"> <p align="center"> <% try { String nev = request.getParameter("nev"); String password = request.getParameter("pswd"); String x = request.getParameter("x"); String y = request.getParameter("y"); String nez = request.getParameter("nez"); String level = request.getParameter("level"); String terkep =
request.getParameter("terkep"); String mehet = request.getParameter("mehet"); String id = request.getParameter("id "); Class.forName("sunjdbcodbcJdbcOdbcDriver"); Connection con = DriverManager.getConnection("jdbc:odbc:"+ application.getInitParameter("ODBC")); Statement stmt = con.createStatement(); %>ALLAPOT ELMENTESE<br/><% PreparedStatement pstmt = con.prepareStatement("UPDATE jatekosok SET bentvan=false WHERE azonosito="+id ); pstmt.executeUpdate(); pstmt.close(); con.close(); %>SIKERULT ELMENTENI<br/> <anchor>Jatek folytatasa<br/> <go href="game.jsp" sendreferer="false" method="get"> <postfield name="id " value="<%=id %>"/> <postfield name="nev" value="<%=nev%>"/> <postfield name="pswd" value="<%=password%>"/> <postfield name="x"
value="<%=x%>"/> <postfield name="y" value="<%=y%>"/> <postfield name="level" value="<%=level%>"/> <postfield name="nez" value="<%=nez%>"/> <postfield name="terkep" value="<%=terkep%>"/> <postfield name="mehet" value="<%=mehet%>"/> </go> </anchor><br/> <anchor>Kilepes a jatekbol<br/> <go href="labirintgame.jsp" sendreferer="false" method="get"> </go> </anchor><br/> <% } catch (SQLException e ) {} catch (ClassNotFoundException e ) {} %> </p> </card> </wml> - 116 - WAP alapú alkalmazás fejlesztése A játék dokumentálása VIII9. FRISSITES.JAVA A szervlet feladata a játékos frissítési sebességének a módosítása. Erre egy WML oldalt generál, mely tartalmaz egy input elemet, ahova a
játékos be tudja írni a számára legmegfelelobb frissítési gyakoriságot (minél nagyobb a szám, annál lassabb a frissítés). A frissítés maximális értéke 99 lehet A frissítés beírása után a Modosit link az új update paraméterrel hívja meg a game szervletet. A generált oldal: A forráskód: import import import import import java.sql*; java.io*; java.util*; javax.servlet*; javax.servlethttp*; public class frissites extends HttpServlet{ String head ="<?xml version="1.0"?> <!DOCTYPE wml PUBLIC "//WAPFORUM//DTD WML 11//EN" "http://wwwwapforumorg/DTD/wml 12xml">"; String contentType = "text/vnd.wapwml"; HttpServletResponse response; ByteArrayOutputStream bytes; String encoding; OutputStreamWriter w; PrintWriter out; String appl; void init(HttpServletResponse resp) throws ServletException, IOException { ServletContext context = getServletContext(); response = resp; response.setContentType(contentType);
response.setHeader("Cache-Control","no-cache"); encoding = response.getCharacterEncoding (); bytes = new ByteArrayOutputStream (8192); w = new OutputStreamWriter (bytes, encoding); out = new PrintWriter (w); appl = context.getInitParameter( "application" ); } void close() throws ServletException, IOException{ out.flush (); response.setContentLength (bytessize ()); try {bytes.writeTo (responsegetOutputStream ());} catch (Exception e) {e.printStackTrace ();} } public void doPost ( HttpServletRequest HttpServletResponse request, resp) throws ServletException, IOException {} public void doGet ( HttpServletRequest request, HttpServletResponse resp ) throws ServletException, IOException { String String String String String nev update password xx yy = = = = = request.getParameter("nev"); request.getParameter("frissites"); request.getParameter("pswd"); request.getParameter("x"); request.getParameter("y"); -
117 - WAP alapú alkalmazás fejlesztése String String String String String terkep level nez mehet id = = = = = A játék dokumentálása request.getParameter("terkep"); request.getParameter("level"); request.getParameter("nez"); request.getParameter("mehet"); request.getParameter("id "); init(resp); out.println(head); out.println("<wml>"); out.print("<card id="beallitas" title="Frissites">"); out.println("<p align="center">"); out.println("Frissites:<input type="text" format="NN" name="frissites"/>"); out.println("<anchor>Modosit<br/>"); out.println("<go href="/"+appl+"/servlet/game" sendreferer="false" method="get">"); out.println("<postfield name="update" value="$(frissites)"/>");
out.println("<postfield name="nev" value="$(nev)"/>"); out.println("<postfield name="pswd" value="$(pswd)"/>"); out.println("<postfield name="id " value=""+id +""/>"); out.println("<postfield name="x" value=""+xx+""/>"); out.println("<postfield name="y" value=""+yy+""/>"); out.println("<postfield name="nez" value=""+nez +""/>"); out.println("<postfield name="level" value=""+level +""/>"); out.println("<postfield name="terkep" value=""+terkep +""/>"); out.println("<postfield name="mehet" value=""+mehet +""/>"); out.println("</go>");
out.println("</anchor> "$(frissites)"-re"); out.println("</p>"); out.println("</card>"); out.println("</wml>"); close(); } } A szervlet kimenete a következo WML oldal lesz: <?xml version="1.0"?> <!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN" "http://wwwwapforumorg/DTD/wml 11xml"> <wml> <card id="beallitas" title="Frissites"> <p align="center"> Frissites: <input type="text" format="NN" name="frissites"/> <anchor>Modosit<br/><go href="/labirintus/servlet/game" sendreferer="false" method="get"> <postfield name="update" value="$(frissites:noesc)"/> <postfield name="nev" value="$(nev:noesc)"/> <postfield name="pswd" value="$(pswd:noesc)"/> <postfield
name="id " value="4"/> <postfield name="x" value="60"/> <postfield name="y" value="67"/> <postfield name="nez" value="2"/> <postfield name="level" value="1"/> <postfield name="terkep" value="1"/> <postfield name="mehet" value="0"/> </go></anchor> "$(frissites:noesc)"-re </p> </card> </wml> A JSP oldal: <%@ page contentType="text/vnd.wapwml"%><% String head ="<?xml version="1.0"?> <!DOCTYPE wml PUBLIC "//WAPFORUM//DTD WML 11//EN" "http://wwwwapforumorg/DTD/wml 11xml">"; response.setHeader("Cache-Control","no-cache"); out.println(head); String nev = request.getParameter("nev"); String password = request.getParameter("pswd"); String x =
request.getParameter("x"); String y = request.getParameter("y"); String terkep = request.getParameter("terkep"); String level = request.getParameter("level"); String nez = request.getParameter("nez"); String mehet = request.getParameter("mehet"); - 118 - WAP alapú alkalmazás fejlesztése A játék dokumentálása String id = request.getParameter("id "); %> <wml> <card id="beallitas" title="Frissites"> <p align="center"> Frissites:<input type="text" format="NN" name="frissites"/> <anchor>Modosit<br/> <go href="game.jsp" sendreferer="false" method="get"> <postfield name="nev" value="<%=nev%>"/> <postfield name="update" value="$(frissites)"/> <postfield name="pswd" value="<%=password%>"/>
<postfield name="id " value="<%=id%>"/> <postfield name="x" value="<%=x%>"/> <postfield name="y" value="<%=y%>"/> <postfield name="nez" value="<%=nez%>"/> <postfield name="level" value="<%=level%>"/> <postfield name="terkep" value="<%=terkep%>"/> <postfield name="mehet" value="<%=mehet%>"/> </go> </anchor> "$(frissites)"-re </p> </card> </wml> VIII10. FIGHT.JAVA A szervlet egy WML oldalt generál, azonban az oldal tartalmaz egy onenterforward eseménykezelot, mely hatására betöltodik ismét a game szervlet. A szervlet feladata a harc kimenetének adminisztrálása, azaz a támadó játékos ero szintjének, és a védekezo játékos védelmi szintjének csökkentése valamint a pontszám növelése. A
szabály az, hogy a támadó játékos erejének 10%-ával csökkennek a szintek és növekszik a pontszám. A szervlet természetesen csak akkor csökkenti a támadó játékos ero szintjét, ha közvetlenül elotte van az, akit támad. A játék olyan, hogy ha a játékos elott van az ellenség, akkor nem léphet arra a helyre, ahol a másik áll, azaz egy pozícióban csak egy játékos állhat. Ezáltal az adatbázisban könnyen meg lehet találni azt a játékost, aki a támadó elott áll, melybol biztosan csak 1 van! A következo SQL utasítás végzi el az adatbázisból a játékossal szemben levo ellenfél adatainak lekérdezését, valamint leellenorzi, hogy tényleg van-e a játékos elott valaki: rs = stmt.executeQuery("SELECT poziciox,pozicioy,azonosito FROM jatekosok WHERE poziciox="+x for+" AND pozicioy="+y for+" AND bentvan=true AND palya="+level +" azonosito<>"+id ); ellenseg=false;id2=0; while (rs.next()) { i =
rs.getInt(1); j = rs.getInt(2); ellenseg=true; id2=rs.getInt(3); } AND Ha ellenség van elotte, akkor a megfelelo értékkel csökkenteni kell a támadó erejét a támadónak, és a védelmi szintjét a másik játékosnak, mely azonosítóját az id2 változó tartalmazza, valamint azt is kell adminisztrálni, hogy a játékos meghalt-e, azaz a támadás után a védelmi szintje 0 lett-e. A támadó játékos erejének és pontszámának lekérdezése: rs = stmt.executeQuery("SELECT ero,pont FROM jatekosok WHERE azonosito="+id ); rs.next(); ero = rs.getInt(1); pont=rs.getInt(2); lo=new Double(ero/10.0); int csok=lo.intValue(); pont=pont+csok; stmt.close(); A támadott játékos védelmi szintjének lekérdezése: stmt=con.createStatement(); rs = stmt.executeQuery("SELECT vedelem FROM jatekosok WHERE azonosito = "+ id2); rs.next(); - 119 - WAP alapú alkalmazás fejlesztése A játék dokumentálása vedelem=rs.getInt(1); stmt.close(); String
bent="true"; String halott="false"; /* ha meghalt a játékos / if (vedelem-csok<=0) { vedelem=csok+10; bent="false"; pont=pont+20; halott="true"; } Az adatbázis módosítása két lépésben történik. Eloször a támadott adatait, majd a támadó adatait módosítjuk: pstmt = con.prepareStatement("UPDATE jatekosok SET halott="+halott+",bentvan="+bent+",vedelem="+ (vedelem-csok)+" WHERE azonosito="+id2); pstmt.executeUpdate(); pstmt.close(); pstmt = con.prepareStatement("UPDATE jatekosok SET ero="+ (ero-csok)+", pont="+pont+" WHERE azonosito="+id ); pstmt.executeUpdate(); pstmt.close(); A forráskód: import import import import import java.sql*; java.io*; java.util*; javax.servlet*; javax.servlethttp*; public class fight extends HttpServlet{ String head ="<?xml version="1.0"?> <!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN"
"http://wwwwapforumorg/DTD/wml 12xml">"; String contentType = "text/vnd.wapwml"; HttpServletResponse response; ByteArrayOutputStream bytes; String encoding; OutputStreamWriter w; PrintWriter out; String directory; String ODBC; String appl; void init(HttpServletResponse resp) throws ServletException, IOException { ServletContext context = getServletContext(); response = resp; response.setContentType(contentType); response.setHeader("Cache-Control","no-cache"); encoding = response.getCharacterEncoding (); bytes = new ByteArrayOutputStream (8192); w = new OutputStreamWriter (bytes, encoding); out = new PrintWriter (w); directory = context.getRealPath( "/data" ); ODBC = context.getInitParameter("ODBC"); appl = context.getInitParameter("application"); } void close() throws ServletException, IOException{ out.flush (); response.setContentLength (bytessize ()); try { bytes.writeTo (responsegetOutputStream ());} catch
(Exception e) {e.printStackTrace ();} } public void doPost ( HttpServletRequest HttpServletResponse request, resp) throws ServletException, IOException {} - 120 - WAP alapú alkalmazás fejlesztése A játék dokumentálása public void doGet ( HttpServletRequest request, HttpServletResponse resp ) throws ServletException, IOException { String nev = request.getParameter("nev"); String password = request.getParameter("pswd"); String xx = request.getParameter("x"); String yy = request.getParameter("y"); String terkep = request.getParameter("terkep"); String level = request.getParameter("level"); String nez = request.getParameter("nez"); String mehet = request.getParameter("mehet"); String id = request.getParameter("id "); Double lo; int mehet,nez; int x,y; int x left,x right,x for,x back,y left,y right,y for,y back; labirint labirintus = new labirint(directory+"/level"+level
+".dat"); if (nez ==null) nez=1; else nez=Integer.parseInt(nez ); if (mehet ==null) mehet=0; else mehet=Integer.parseInt(mehet ); mehet = Integer.toString(mehet); init(resp); if (xx==null | yy==null) { x=labirintus.startx; y=labirintusstarty; } else { x=Integer.parseInt(xx); y=IntegerparseInt(yy); } if (nez==1) { x for=x; x back=x ; y for=y+1; y back=y-1; } else if (nez==2) { x for=x+1; x back=x-1; y for=y; y back=y; } else if (nez==3) { x for=x; x back=x; y for=y-1; y back=y+1; } else { x for=x-1; x back=x+1; y for=y; y back=y; } try { Class.forName("sunjdbcodbcJdbcOdbcDriver"); Connection con = DriverManager.getConnection("jdbc:odbc:"+ODBC); Statement stmt = con.createStatement(); ResultSet rs; PreparedStatement pstmt; boolean ellenseg=false; int i,j,ero,vedelem,pont,id2; rs = stmt.executeQuery("SELECT poziciox,pozicioy,azonosito FROM jatekosok WHERE poziciox="+x for+"AND pozicioy="+y for+"AND bentvan=true AND palya="+level
+" AND azonosito<>"+id ); ellenseg=false;id2=0; while (rs.next()) { i = rs.getInt(1); j = rs.getInt(2); ellenseg=true;id2=rs.getInt(3); } if (ellenseg==true) { rs = stmt.executeQuery("SELECT ero,pont FROM jatekosok WHERE azonosito="+id ); rs.next(); ero = rs.getInt(1); pont=rs.getInt(2); lo=new Double(ero/10.0); int csok=lo.intValue(); pont=pont+csok; stmt.close(); stmt=con.createStatement(); rs = stmt.executeQuery("SELECT vedelem FROM jatekosok WHERE azonosito="+id2); rs.next(); vedelem=rs.getInt(1); stmt.close(); String bent="true"; String halott="false"; - 121 - WAP alapú alkalmazás fejlesztése A játék dokumentálása if (vedelem-csok<=0) { vedelem=csok+10; bent="false"; pont=pont+20; halott="true"; } pstmt = con.prepareStatement("UPDATE jatekosok SET halott="+halott+",bentvan="+bent+",vedelem="+(vedelem-csok)+" WHERE azonosito="+id2);
pstmt.executeUpdate(); pstmt.close(); pstmt = con.prepareStatement("UPDATE jatekosok SET ero="+(erocsok)+", pont="+pont+" WHERE azonosito="+id ); pstmt.executeUpdate(); pstmt.close(); con.close(); } } catch (SQLException e ) {} catch (ClassNotFoundException e ) {} out.println(head); out.println("<wml>"); out.print("<card id="harc" title="HARC">"); out.println("<onevent type="onenterforward">"); out.println("<go href="/"+appl+"/servlet/game" sendreferer="false" method="get">"); out.println("<postfield name="nev" value="$(nev)"/>"); out.println("<postfield name="pswd" value="$(pswd)"/>"); out.println("<postfield name="id " value=""+id +""/>"); out.println("<postfield name="x"
value=""+xx+""/>"); out.println("<postfield name="y" value=""+yy+""/>"); out.println("<postfield name="nez" value=""+nez +""/>"); out.println("<postfield name="level" value=""+level +""/>"); out.println("<postfield name="terkep" value=""+terkep +""/>"); out.println("<postfield name="mehet" value=""+mehet +""/>"); out.println("</go>"); out.println("</onevent>"); out.println("<p align="center">"); out.println("</p>"); out.println("</card>"); out.println("</wml>"); close(); } } A szervlet kimenetül egy olyan WML oldalt ad, mely rögtön meghívja a game szervletet: <?xml version="1.0"?> <!DOCTYPE wml PUBLIC
"-//WAPFORUM//DTD WML 1.1//EN" "http://wwwwapforumorg/DTD/wml 11xml"> <wml> <card id="harc" title="HARC"> <onevent type="onenterforward"> <go href="/labirintus/servlet/game" sendreferer="false" method="get"> <postfield name="nev" value="$(nev:noesc)"/> <postfield name="pswd" value="$(pswd:noesc)"/> <postfield name="id " value="4"/> <postfield name="x" value="60"/> <postfield name="y" value="67"/> <postfield name="nez" value="2"/> <postfield name="level" value="1"/> <postfield name="terkep" value="1"/> <postfield name="mehet" value="0"/> </go> </onevent> <p align="center"/> </card> </wml> - 122 - WAP alapú
alkalmazás fejlesztése A játék dokumentálása A szervletnek megfelelo JSP oldal: <%@ page import="java.sql*,Lab,java.lang*,java.util*" contentType="text/vnd.wapwml"%>< jsp:useBean id="labirintus" scope="session" class="Lab"/><% String head ="<?xml version="1.0"?> <!DOCTYPE wml PUBLIC "//WAPFORUM//DTD WML 11//EN" "http://www.wapforumorg/DTD/wml 11xml">"; response.setHeader("Cache-Control","no-cache"); String nev = request.getParameter("nev"); String pswd = request.getParameter("pswd"); String xx = request.getParameter("x"); String yy = request.getParameter("y"); String terkep = request.getParameter("terkep"); String level = request.getParameter("level"); String nez = request.getParameter("nez"); String mehet = request.getParameter("mehet"); String id =
request.getParameter("id "); Double lo; int mehet,nez; int x,y; int x left,x right,x for,x back,y left,y right,y for,y back; labirintus.setlabirint(applicationgetRealPath("/data/level1dat")); if (nez ==null) nez=1; else nez=Integer.parseInt(nez ); if (mehet ==null) mehet=0; else mehet=Integer.parseInt(mehet ); mehet = Integer.toString(mehet); if (xx==null | yy==null) { x=labirintus.getstartx(); y=labirintusgetstarty(); } else { x=Integer.parseInt(xx); y=IntegerparseInt(yy); } if (nez==1) { x for=x; x back=x ; y for=y+1; y back=y-1; } else if (nez==2) { x for=x+1; x back=x-1; y for=y; y back=y; } else if (nez==3) { x for=x; x back=x; y for=y-1; y back=y+1; } else { x for=x-1; x back=x+1; y for=y; y back=y; } try { Class.forName("sunjdbcodbcJdbcOdbcDriver"); Connection con = DriverManager.getConnection("jdbc:odbc:"+ application.getInitParameter("ODBC")); Statement stmt = con.createStatement(); ResultSet rs; PreparedStatement pstmt;
boolean ellenseg=false; int i,j,ero,vedelem,pont,id2; rs = stmt.executeQuery("SELECT poziciox,pozicioy,azonosito FROM jatekosok WHERE poziciox="+x for+" AND pozicioy="+y for+" AND bentvan=true AND palya="+level +" AND azonosito<>"+ id ); ellenseg=false;id2=0; while (rs.next()) { i = rs.getInt(1); j = rs.getInt(2); ellenseg=true; id2=rs.getInt(3); } if (ellenseg==true) { rs = stmt.executeQuery("SELECT ero,pont FROM jatekosok WHERE azonosito="+id ); rs.next(); ero = rs.getInt(1); pont=rs.getInt(2); lo=new Double(ero/10.0); int csok=lo.intValue(); pont=pont+csok; stmt.close(); stmt=con.createStatement(); rs = stmt.executeQuery("SELECT vedelem FROM jatekosok WHERE azonosito="+id2); rs.next(); - 123 - WAP alapú alkalmazás fejlesztése A játék dokumentálása vedelem=rs.getInt(1); stmt.close(); String bent="true"; String halott="false"; if (vedelem-csok<=0) { vedelem=csok+10;
bent="false"; pont=pont+20; halott="true"; } pstmt = con.prepareStatement("UPDATE jatekosok SET halott="+halott+",bentvan="+ bent+",vedelem="+(vedelem-csok)+" WHERE azonosito="+id2); pstmt.executeUpdate(); pstmt.close(); pstmt = con.prepareStatement("UPDATE jatekosok SET ero="+(ero-csok)+",pont=" + pont+" WHERE azonosito="+id ); pstmt.executeUpdate(); pstmt.close(); con.close(); } } catch (SQLException e ) {} catch (ClassNotFoundException e ) {} out.println(head); %> <wml> <card id="harc" title="HARC"> <onevent type="onenterforward"> <go href="game.jsp" sendreferer="false" method="get"> <postfield name="nev" value="<%=nev%>"/> <postfield name="pswd" value="<%=pswd%>"/> <postfield name="id " value="<%=id %>"/>
<postfield name="x" value="<%=xx%>"/> <postfield name="y" value="<%=yy%>"/> <postfield name="nez" value="<%=nez %>"/> <postfield name="level" value="<%=level %>"/> <postfield name="terkep" value="<%=terkep %>"/> <postfield name="mehet" value="<%=mehet %>"/> </go> </onevent> <p align="center"></p> </card> </wml> VIII11. REKORDOK.JAVA A szervlet feladata a legjobb 10 játékos pontszámának kiíratása. A rekordok lekérdezése egy egyszeru SQL utasítás segítségével történik: rs = stmt.executeQuery("SELECT pont,nev FROM jatekosok ORDER BY pont DESC "); Az eredmény: A forrás: - 124 - WAP alapú alkalmazás fejlesztése import import import import import A játék dokumentálása java.sql*; java.io*; java.util*;
javax.servlet*; javax.servlethttp*; public class rekordok extends HttpServlet{ String head ="<?xml version="1.0"?> <!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN" "http://wwwwapforumorg/DTD/wml 12xml">"; String contentType = "text/vnd.wapwml"; HttpServletResponse response; ByteArrayOutputStream bytes; String encoding; OutputStreamWriter w; PrintWriter out; String ODBC; void init(HttpServletResponse resp) throws ServletException, IOException { ServletContext context=getServletContext(); response = resp; response.setContentType(contentType); response.setHeader("Cache-Control","no-cache"); encoding = response.getCharacterEncoding (); bytes = new ByteArrayOutputStream (8192); w = new OutputStreamWriter (bytes, encoding); out = new PrintWriter (w); ODBC = context.getInitParameter("ODBC"); } void close() throws ServletException, IOException{ out.flush (); response.setContentLength (bytessize ());
try { bytes.writeTo (responsegetOutputStream ());} catch (Exception e) {e.printStackTrace ();} } public void doPost ( HttpServletRequest HttpServletResponse request, resp) throws ServletException, IOException {} public void doGet ( HttpServletRequest request, HttpServletResponse resp ) throws ServletException, IOException { String i,j; A max változó tartalmazza azt, hogy az elso 10 játékost irassa ki: int max=10; int sorsz=1; init(resp); out.println(head); out.println("<wml>"); out.print("<card id="harc" title="Rekordok">"); out.println("<p align="center">"); out.println("<table columns="3" align="CLR">"); try { Class.forName("sunjdbcodbcJdbcOdbcDriver"); Connection con = DriverManager.getConnection("jdbc:odbc:"+ODBC); Statement stmt = con.createStatement(); ResultSet rs; PreparedStatement pstmt; rs = stmt.executeQuery("SELECT pont,nev FROM
jatekosok ORDER BY pont DESC "); Maximum max db. játékos nevének és pontszámának kiiratása: while (rs.next() & max-->0) { i=rs.getString(1);j=rsgetString(2); out.println("<tr><td>"+(sorsz++)+"</td><td>"+j+"</td><td>"+i+"</td></tr>"); } } catch (SQLException e ) {System.outprintln(e);} catch (ClassNotFoundException e ) {System.outprintln(e);} out.println("</table>"); out.println("</p>"); - 125 - WAP alapú alkalmazás fejlesztése A játék dokumentálása out.println("<do type="prev" label="Vissza">"); out.println("<prev/>"); out.println("</do>"); out.println("</card>"); out.println("</wml>"); close(); } } Az eloállított WML oldal: <wml> <card id="harc" title="Rekordok"> <p align="center">
<table columns="3" align="CLR"> <tr><td>1.</td><td>www</td><td>100</td></tr> <tr><td>2.</td><td>www2</td><td>80</td></tr> <tr><td>3.</td><td>www2</td><td>50</td></tr> </table></p> <do type="prev" label="Vissza"> <prev/> </do> </card> </wml> A rekordok.jsp oldal: <%@ page import="java.sql*,Lab,java.lang*,java.util*" contentType="text/vnd.wapwml"%>< jsp:useBean id="labirintus" scope="session" class="Lab"/><% String head ="<?xml version="1.0"?> <!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN" "http://wwwwapforumorg/DTD/wml 11xml">"; response.setHeader("Cache-Control","no-cache"); out.println(head);%> <wml>
<card id="harc" title="Rekordok"> <p align="center"> <table columns="3" align="CLR"> <% try { Class.forName("sunjdbcodbcJdbcOdbcDriver"); Connection con = DriverManager.getConnection("jdbc:odbc:"+applicationgetInitParameter("ODBC")); Statement stmt = con.createStatement(); ResultSet rs; PreparedStatement pstmt; int sorsz; String i,j; sorsz=0; rs = stmt.executeQuery("SELECT nev,pont FROM jatekosok ORDER BY pont DESC"); Maximum 10 játékos adatainak kiiratása: while (rs.next() & sorsz++<10) { i = rs.getString(1); j = rs.getString(2);%> <tr><td><%=sorsz%>.</td><td><%=i%></td><td><%=j%></td></tr><% } stmt.close(); con.close(); } catch (SQLException e ) {} catch (ClassNotFoundException e ) {} %> </table></p> <do type="prev" label="Vissza"> <prev/>
</do> </card> </wml> VIII12. CREATELABIRINT.JAVA A következo alkalmazás függetlenül muködik a többi szervlettol. A feladata a labirintust tartalmazó adatfájl létrehozása. A CreateLabirint fájl egy 100x100-as labirintust hoz létre, melyben 4500 út (45%) van A - 126 - WAP alapú alkalmazás fejlesztése A játék dokumentálása labirintus létrehozása véletlenszeru kezdopontból indul, és véletlenszeru irányba folytatódik, azonban mindig csak a már létezo útból halad tovább, ezáltal a labirintus bármely helyére bárhonnan el lehet jutni. A létrehozott labirintus megfelel annak az eloírásnak is, hogy maximum 3-as keresztezodések lehetnek benne. A programot a java CreateLabirint utasítással lehet elindítani. Létrehoz egy level.dat és egy leveltxt állományt A txt állomány a felhasználó számára jobban átlátható módon tartalmazza a labirintust, míg a .dat állomány a szervletek számára szükséges formátumban
tartalmazza a labirintust, azaz: – az elso két bájt a labirintus mérete (jelen esetben ez 100,100) – a továbbiakban sorfolytonosan következik a labirintus. A bájtok jelentése: • Fal esetén 1 • Út esetén 2 • Kezdopont esetén 3 (Ezt a szervletek nem használják még. A labirintus létrehozása innen indult el.) A .dat állomány nem tartalmazza a labirintus méretét, hanem csak magát a labirintust: Fal esetén: Út esetén: Továbbá nem sorfolytonos, hanem minden 100. után egy soremelés van A fájlok mérete tehát: .dat à 10002 (100x100 bájt, + 2 bájt a mértnek) .txt à 10100 bájt kell hogy legyen (100x100 bájt + 100 bájt a soremeléseknek) A program forrása: import java.io*; import java.util*; public class create { static boolean [][] lab = new boolean[101][101]; static int [] utakx = new int[4501]; static static static static int [] utaky = new int[4501]; int i,j,k,l,ut,p,sx,sy; boolean [] iranyok = new boolean [5]; int b,e,s; A szomszédos utak
megszámolása: static int szomsz(int ut) { s = 0; if ( lab[utakx[ut]-1][utaky[ut]-1]) if ( lab[utakx[ut]][utaky[ut]-1]) if ( lab[utakx[ut]+1][utaky[ut]-1]) if ( lab[utakx[ut]-1][utaky[ut]]) if ( lab[utakx[ut]+1][utaky[ut]]) if ( lab[utakx[ut]-1][utaky[ut]+1]) if ( lab[utakx[ut]+1][utaky[ut]+1]) if ( lab[utakx[ut]][utaky[ut]+1]) return s; } s++; s++; s++; s++; s++; s++; s++; s++; public static void main (String[] args) { Random rnd = new Random(); A kezdo pozíció véletlenszeru kiválasztása: i=rnd.nextInt(50)+rndnextInt(50); j=rnd.nextInt(50)+rndnextInt(50); sx=i;sy=j; utakx[1]=i; utaky[1]=j; System.outprint("StartX: ");Systemoutprintln(i); System.outprint("StartY: ");Systemoutprintln(j); System.outprintln("Generating"); System.outprintln("Completed: "); lab[i][j]=true; ut=1; while (ut<4500) { System.outprint((char)8); - 127 - A labirintust tartalmazza Az i. út vízszintes pozíciója (oszlopa) Az i. út függoleges pozíciója (sora)
WAP alapú alkalmazás fejlesztése A játék dokumentálása System.outprint((char)8); System.outprint((char)8); System.outprint((char)8); System.outprint((int)(ut/450)); System.outprint("%"); p=rnd.nextInt(ut)+1; i=utakx[p]; j=utaky[p]; p=0; Annak megvizsgálása, hogy merre mehet tovább: if ((j-1>2) && (lab[i][j-1]==false)) { p++; iranyok[1]=true; } else {iranyok[1]=false;} if ((j+1<100) && (lab[i][j+1]==false)) { p++; iranyok[2]=true; } else {iranyok[2]=false;} if ((i-1>2) && (lab[i-1][j]==false)) { p++; iranyok[3]=true; } else {iranyok[3]=false;} if ((i+1<100) && (lab[i+1][j]==false)) { p++; iranyok[4]=true; } else {iranyok[4]=false;} if (p>0) { A lehetséges irányok közül egy irány kiválasztása: p=rnd.nextInt(p)+1; l=1; for (k=1;k<5;k++) { if (iranyok[k]) { if (l==p) { Továbbhaladás a kiválasztott irányba: if (k==1) { lab[i][j-1]=true; utakx[ut+1]=i; utaky[ut+1]=j-1;} if (k==2) { lab[i][j+1]=true;
utakx[ut+1]=i; utaky[ut+1]=j+1;} if (k==3) { lab[i-1][j]=true; utakx[ut+1]=i-1; utaky[ut+1]=j;} if (k==4) { lab[i+1][j]=true; utakx[ut+1]=i+1; utaky[ut+1]=j;} ut++; Ha az új helynek 2-nél több szomszédja van, akkor az nem jó, tehát vissza kell lépni if (szomsz(ut)>2) { ut--; if (k==1) { lab[i][j-1]=false; } if (k==2) { lab[i][j+1]=false; } if (k==3) { lab[i-1][j]=false; } if (k==4) { lab[i+1][j]=false; } } break; } l++; } } } } System.outprintln("OK"); OutputStream f =null; A .txt állomány létrehozása: try {f=new FileOutputStream("level.txt");} catch (IOException e) { System.outprintln(e);} b=178;e=13;s=32; try { for (j=1;j<101;j++) { for (i=1;i<101;i++) { if (lab[i][j]) {f.write(s);} else {fwrite(b);} } f.write(e); } f.close(); } catch (IOException e) {System.outprintln(e);} f =null; A .dat állomány létrehozása: try {f=new FileOutputStream("level.dat");} catch (IOException e) { System.outprintln(e);} b=100; try { f.write(b);
f.write(b); b=1;s=2;e=3; for (j=1;j<101;j++) { for (i=1;i<101;i++) { if ((i==sx) && (j==sy)) { f.write(e);} else { - 128 - WAP alapú alkalmazás fejlesztése A játék dokumentálása if (lab[i][j]) {f.write(s);} else {fwrite(b);} } } } f.close(); } catch (IOException e) {System.outprintln(e);} } } Miután a .dat állomány létrejött, a játékban szereplo level1dat-ra könnyen ki lehet cserélni Fontos azonban, hogy ekkor a játékosok pozíciója valószínuleg nem lesz jó, ugyanis lehet, hogy "falban" vannak. Ezért ekkor a "DATA.MDB" adatfájlt is aktualizálni kell Ezt az updatejava program végzi el VIII13. UPDATE.JAVA Feladata a labirintus megváltoztatása után a játékosok véletlenszeru elhelyezése az új labirintusban. A forráskód: import java.sql*; import java.io*; import java.util*; public class update { static String directory; static String database; static String appl; public static void main (String[] args) {
directory = args[0]; //.dat database = args[1]; // ODBC System.outprintln("Labirint stored in "+directory); System.outprintln("Database name: "+database); try { Class.forName("sunjdbcodbcJdbcOdbcDriver"); Az adatbázis megnyitása: Connection con = DriverManager.getConnection("jdbc:odbc:"+database); Statement stmt = con.createStatement(); stmt = con.createStatement(); Az adatbázisban szerepló játékosok lekérdezése: ResultSet rs = stmt.executeQuery("SELECT azonosito,nev FROM jatekosok"); boolean van=false; while (rs.next()) { String az = rs.getString(1); String name = rs.getString(2); System.outprintln("Updating "+name+"s information"); Az új labirintus megnyitása: labirint labirintus = new labirint(directory); Az új labirintusban levo szabad helyek – azaz az utak – lekérdezése: Double a = new Double(Math.random()*labirintus.uresek*1.0); Az utak közül egy kiválasztása: int startx =
labirintus.getrandomx(aintValue()); int starty = labirintus.getrandomy(aintValue()); A játékos pozíciójának módosítása az új pozícióra: PreparedStatement pstmt = con.prepareStatement("UPDATE jatekosok SET poziciox="+startx+", pozicioy="+starty+" WHERE azonosito="+az); pstmt.executeUpdate(); pstmt.close(); } stmt.close(); } catch (SQLException e ) {System.outprintln(e);} catch (ClassNotFoundException e ) {System.outprintln(e);} } } A program használata: java update level.dat database update, ahol • • level.dat az új labirintus database update pedig a módosítandó adatbázis ODBC hivatkozási neve. - 129 - WAP alapú alkalmazás fejlesztése Végszó IX. VÉGSZÓ A diplomamunkámban bemutattam annak lehetoségét, hogy hogyan lehet az egyre népszerubb Java nyelv segítségével az egyre jobban elterjedo mobiltelefonokra egy játékot fejleszteni. A játékok fejlesztésén túl azonban többfajta alkalmazásokat lehet még a
telefonokra fejleszteni. Lehetoség van például bankok információs szolgáltatásának elérésére (akár egyenleglekérdezésre vagy átutalásra), különbözo hírek azonnali elolvasására is. A mobil kommunikáció segítségével egy eddig csak a számítógépeken elérheto „világ” nyílt meg a felhasználók elott. A WAP szabvány folyamatos fejlesztésével foglalkozó WAP Forum egyre inkább abba az irányba viszi a WAP szabványosítását, hogy a vezetéknélküli és a vezetékes eszközökön a világháló szinte ugyanúgy jelenjen meg. A WAP szabvány 13-as verziója már azt is lehetové teszi, hogy például a WML oldalakban a telefonok billentyujét (0-9-es számok) hozzá lehessen rendelni az egyes linkekhez. Ez jobban megkönnyíti például egy játék használatát Végül néhány mondat a játék esetleges további fejlesztésének lehetoségeirol: A játék egyetlen pályáját további pályákkal lehetne kibovíteni. A pályák generálását
nagymértékben megkönnyíti a CreateLabirint.java alkalmazás Az egyes pályákon való továbbjutás feltétele egy eléggé magas pontszám elérése, vagy pedig egy kijárat megtalálása. Minden egyes pályán egy rangsort felállítani az azokban legtöbb pontot szerzo játékosok feltüntetésével. A játékszabályok olyan módosításával, hogy egy közös ellenségeket kell elpusztítani –, akik maguktól haladnak a labirintusban –, a játék még érdekesebbé teheto. - 130 - WAP alapú alkalmazás fejlesztése Felhasznált irodalom X. FELHAS ZN ÁLT IROD ALOM 1. „Wireless Application Protocoll Architecture Specification”, WAP Forum, 1998 Április 30 URL: http://www.wapforumorg 2. „Wireless Markup Language”, WAP Forum, 1998 Április 30 URL: http://www.wapforumorg 3. „Wireless Markup Language Script”, WAP Forum, 1998 Április 30 URL: http://www.wapforumorg 4. JavaServer Pages programozóknak, Mika Péter, 2000 Szeptember - 131 -