Eötvös Loránd Tudományegyetem Informatikai Kar
Squash or Die
Készített Kurucz Attila (KUANABI.ELTE) Készítette: programtervező matematikus szak, nappali tagozat Témavezető: Tarcsi Ádám
Budapest, 2010. március
Tartalomjegyzék I.
Egy-két szó a squashról __________________________________________________ 3 A squash kialakulásának története _________________________________________________ 3 Szabályok _____________________________________________________________________ 5
II.
Felhasználói dokumentáció ______________________________________________ 12 Hardver-szoftver követelmények _________________________________________________ 12 Telepítés _____________________________________________________________________ 12 A program részei_______________________________________________________________ 12 A program használata __________________________________________________________ 12 Játék közben __________________________________________________________________ 13 A szerver használata ____________________________________________________________ 14
III. Fejlesztői dokumentáció _________________________________________________ 15 Osztálydiagram ________________________________________________________________ 15 Game ________________________________________________________________________ 16 Button _______________________________________________________________________ 20 ReplayButton _________________________________________________________________ 21 Computer ____________________________________________________________________ 21 GameObject __________________________________________________________________ 22 Hud _________________________________________________________________________ 22 Networking ___________________________________________________________________ 27 Record _______________________________________________________________________ 29 Sounds ______________________________________________________________________ 30 TextInput ____________________________________________________________________ 31 Utilities ______________________________________________________________________ 32
IV.
Állapotdiagram ______________________________________________________ 33
V.
Forráskód ____________________________________________________________ 33
I.
Egy-két szó a squashról
A squash kialakulásának története Az emberek évszázadok óta játszanak olyan ütős labdajátékokat, ahol a labdát vagy a falnak ütik, vagy oda-vissza adogatják egymásnak egy háló felett. A 19. Században rendkívül népszerűek voltak az ütős labdajátékok; ekkoriban született meg a rackets a londoni Flott Börtönben. A sors iróniája, hogy ez a börtönben kialakult játék később éppen az oskolákban vált népszerűvé. A fallabda, úgy tartják, ezen iskolák egyikében, a londoni Harrow Schoolban alakult ki 1830 táján. A diákok, miközben arra vártak, hogy bemehessenek a rackets-pályára, egy kisebb teremben a falnak ütögettek egy gumilabdát. Később rájöttek, hogy puhább labdával sokkal változatosabbak az ütések, maga a játék pedig jóval nehezebb. Az elnevezés, squash, angolul a következőket jelenti: szétlapít, összeprésel, valamint plattyan, tottyan - vagyis a puha labda "viselkedésére", az általa keltett hangeffektusra utal. Kezdetben kevéssé törekedtek a játékszabályok egységesítésére, vagyis egyszerre több, egymástól kissé eltérő változat létezett. Szerencsére csak kettő vált ezek közül népszerűvé. Míg a világ legnagyobb részén puha labdával az úgynevezett "soft ball" változatot játsszák 6,4 méter széles pályán, addig Észak-Amerikában kemény labdával a "hard ball" változatot, valamivel keskenyebb pályán. A soft-ball szabályait 1923-ban rögzítették. A fallabdások száma hamarosan meghaladta a rackets-játékosokét. Főleg azokban az országokban népszerűsödött gyorsan, ahol a brit hadsereg állomásozott: Indiában, Egyiptomban, Dél-Afrikában, Ausztráliában és Új-Zélandon. 1930-ban tartották az első Brit Nyílt Bajnokságot (British Open), melyet az első nem hivatalos világbajnokságként tartanak számon. A bajnok az angol Don Butcher lett, aki a címért honfitársát, Charles Readet győzte le. A következő harmincöt évben többnyire egyiptomi és pakisztáni játékosok álltak a ranglista élén. Legtöbben labdaszedőként kezdték pályafutásukat, így rengeteg lehetőség nyílt a számukra a gyakorlásra, edző azonban ritkán foglalkozott velük. Számos különleges fogást, illetve ütésfajtát fejlesztettek ki, melyek segítségével hihetetlenül technikás versenyzőkké váltak. Az 1960-as évek végén egy mindenre elszánt, kemény férfi, az ír származású Jonah Barrington végre megtörte az egyiptomi és pakisztáni dominanciát. Csak húszéves kora körül kezdett el fallabdázni, de kivételes elkötelezettséget mutatott a sportág iránt. Rengeteget edzett, és ezáltal az akkori játékosoknál sokkal jobb kondícióra tett szert. Hatszor nyerte meg a Brit Nyílt Bajnokságot, ezzel bebizonyította, hogy megfelelő kondícióval le lehet győzni még a legtechnikásabb játékost is. Ettől kezdve a fallabda már nem ugyanaz a játék volt. Barringtont követve a hivatásos játékosok mind jobban odafigyeltek a megfelelő kondícióra. Az élvonalbeliek a fantasztikus ütéstechnika mellett egytől egyig kiváló erőnlétre, gyorsaságra és kitartásra tettek szert. Három játékos emelkedett ki leginkább a mezőnyből: az ausztrál Geoff Hunt és két 3
pakisztáni, Jahangir Khan és Jansher Khan. Hunt volt legjobb azok közül az ausztrál játékosok közül, akik a 70-es években törtek fel, ő vette el a világbajnoki címet Barringtontól. Solan úgy tartják, hogy minden idők legjobb játékosa Jahangir Khan, aki agresszív játékstílusával lesöpörte ellenfeleit a pályáról és annyira kiemelkedett a mezőnyből, hogy a 80-as években öt és fél éven keresztül egyszer sem szenvedett vereséget. Végül Jansher Khannak (akivel egyébként semmilyen rokoni kapcsolatban nem állt) sikerült őt legyőznie azzal, hogy remekül váltogatta a játék iramát. A mai napig ő a világ legjobb játékosa, de már egy seregnyi - főleg ausztrál és brit - ifjú tehetség ingatja a trónját. Amerikában a fallabda helyzete az utóbbi pár évben sokat változott. A soft-ballt korábban csak szabadidősportként űzték, kizárólag nyaranta. A téli idényben a csak ott létező hardballt játszották kemény, tömörebb labdával kicsit keskenyebb pályán. Az utóbbi időben azonban ott is egyre inkább terjed a világszerte népszerű soft-ball, olyannyira, hogy ma már számos versenyző egész évben ezt játssza. A két változat különböző játéktechnikát és stratégiát igényel. A kemény labda sokkal gyorsabban halad a pályán, így lényegesen jobb reflexre van szükség. A labdamenetek rövidebbek, és a játékosok elsősorban az egyből pontot érő ütésekre törekszenek. A soft-ballban is meglehetősen gyorsan mozog a labda, de miközben pattan a falon és a padlón, jelentős mértékben lelassul, így a játékosoknak sokat kell futniuk viszont több idejük van arra, hogy kivitelezzék ütéseiket. A soft-ballban igen nehéz egyből pontot érő labdát ütni, a labdamenetek hosszabbak, és a játékosnak ütéskombinációkat kell alkalmaznia, hogy a pontszerzés érdekében ütésképtelen helyzetbe hozza az ellenfelet. Ezen eltérések miatt nehéz a többéves gyakorlattal rendelkező északamerikai játékosoknak áttérni a hard-ballról a soft-ballra. Növekvő népszerűsége ellenére a fallabda nem kap elegendő nyilvánosságot, ami leginkább annak tudható be, hogy a mérkőzések a közönség számára nehezen hozzáférhetők. Azelőtt a közönséget csupán a pálya hátsó fala fölé emelkedő erkélyen tudták elhelyezni, természetesen igen korlátozott számban. A 70-es években vált gyakorlattá, hogy a pálya hátsó falát üvegből készítették. Hamarosan megjelentek a speciális, csak egy irányban átlátszó, szállítható, plexifalú pályák - jelentősebb eseményeken ma ezt használják. A pályát egy nagy terem közepén állítják fel, így a játék minden szögből látható, és egyszerre háromezer néző kísérheti figyelemmel a mérkőzést. Mivel a játék lényegében abból áll, hogy két játékos egy zárt helységben ütöget egy kicsi és gyors labdát, a fallabda televíziós közvetítése is meglehetősen nehéz feladat. Ám az utóbbi idők technikai fejlődésének köszönhetően ma már léteznek élvezhető minőségű közvetítések. A korszerű finomfelbontású kamerák használatával a labda gyors mozgása a TV-képernyőn is egyre követhetőbbé válik. Ezenkívül bevezették az eltérő színű falak alkalmazását, és speciális labdákat fejlesztettek ki. A kezdetben használ fehér labdák helyét mára olyan, fényvisszaverő pontokkal ellátott labdák vették át, melyek UV fényben világítanak. Ezek az újítások minden bizonnyal lehetővé teszik, hogy a sportág a jövőben az eddigieknél nagyobb nyilvánosságot kapjon.
4
Szabályok Pálya
A mérkőzés előtt Amikor a játékosok a pályára lépnek, az első játszma megkezdése előtt öt perc "felmelegítő" játék áll rendelkezésükre. Ezalatt a játékosok a pálya ellentétes térfelén állnak, és úgy ütik a főfalnak a labdát, hogy az az ellenfél térfelén pattanjon. Két és fél perc után a játékosok térfelet cserélnek. Két célja van: egyrészt az, hogy felmelegítsék a labdát (ugyanis amikor a labda még hideg, kevésbé pattan), másrészt az, hogy a játékosok magukat is bemelegítsék néhány ütéssel. A játszmát csak meleg labdával lehet elkezdeni. A felmelegítő játék után az ütő megpörgetésével döntik el, hogy ki adogat először, méghozzá úgy, hogy aki megnyeri a pörgetést, az választhat, hogy adogatni vagy fogadni akar-e először. Az esetek többségében az adogatást szokták választani,hiszen egy jó adogatással az ellenfelet mindjárt védekező játékra lehet kényszeríteni. A mérkőzés A fallabdát két játékos játssza egy 9,75 m hosszú és 6,4 m széles pályán. Miután ötperces játékkal felmelegítették a labdát, megpörgetik az ütőt, hogy eldöntsék, melyikőjük adogat először. Az adogatás megkezdésével elkezdődik a játék. Akkor nyeri meg a játékos a labdamenetet, ha ellenfele a tinre üti a labdát (fémmel borított, 0,45 m széles sáv a főfal legalján); ha a határvonalakon kívülre üti a labdát; ha nem tud beleütni a labdába, mielőtt az másodszor is pattanna a padlón. A labdamenet folyamán a játékosok megüthetik a labdát közvetlenül a levegőből vagy az után, hogy egyet pattant a padlón. Az oldalsó és a hátsó falak használhatók arra, hogy a labdát visszajuttassák a főfalra. 5
Mérkőzéseken ma már a nemzetközi pontozást alkalmazzák, ami azt jelenti, hogy egy játszma 11 pontig tart, éd két pont különbséggel lehet nyerni. Erre a módosításra azért volt szükség, mert a hagyományos 9 pontos profi mérkőzések túlságosan hosszúra nyúltak. Gyakran megesett, hogy két óránál is hosszabban játszottak, mert az idő nagy része azzal ment el, hogy változatlan állás mellett megszerezték egymástól az adogatás jogát. A nemzetközi pontozási rendszerben is előfordul, hogy a profik közötti mérkőzések nagyon hosszúra sikerülnek, mert azon a szinten már alig van elérhetetlen labda. Általában az a játékos kerül ki győztesen, amelyik öt játszmából hármat megnyer, de olyan pontozási rendszer is létezik, melyben háromból két nyert játszma szükséges a győzelemhez. A mérkőzéseket csapatok is vívhatják egymás ellen. A csapatok három-négy játékosból állnak. Ilyenkor a csapattagok rangsor szerint mérkőznek egymással, vagyis a csapatok erősorrendjében mérik össze erejüket. A leggyakrabban alkalmazott sorrend a 4-3-1-2, tehát a csapatok negyediknek besorolt játékosai kezdik a mérkőzést. A versenyeken számos versenyző, illetve csapat küzd egymás ellen. A verseny lehet egyenes kieséses rendszerben vagy körmérkőzéses rendszerben lebonyolítani, ez általában az induló csapatok számától függ.Az egyenes kieséses rendszerben mindig a győztes jut tovább, míg a végén csak egy marad. A körmérkőzéses rendszerben mindenki megmérkőzik mindenkivel és a legtöbb pontot szerző lesz a győztes. A hazai versenyrendszerben egy vegyes lebonyolítás létezik. Először egy három forduló alatt lebonyolított körmérkőzést rendeznek, ez egyfajta selejtező. A négy legeredményesebb csapat kerül a rájátszásba, ahol már kieséses rendszerben döntik el a végső helyezések sorrendjét. Az adogatás Az először adogató játékos eldöntheti, hogy a jobb vagy a bal oldali adogatónégyzetből akare adogatni. Többnyire a jobb oldalit szokás választani jobbkezes ellenfél esetén, és a bal oldalit balkezes esetén, mert így a labdát az ellenfélnek fonákról kell visszaadnia, ami általában mindenkinek gyengébb pontja. Az adogatás akkor érvényes, ha az adogató legalább egyik lábának egy pontja a labda megütésének pillanatában az adogatónégyzeten belül van úgy, hogy nem érinti a négyzetet körülhatároló vonalak egyikét sem. Az adogató feldobja a labdát a levegőbe, majd lepattanás előtt elüti a főfal felé. A labdának a főfalon az adogatóvonal és a határvonal közé eső területet kell érintenie, és úgy kell visszapattannia, hogy az éppen "használt" adogatónégyzettel ellentétes oldali hátsó pálya negyedben érjen padlót. A hátsó pálya negyed vagy más néven fogadónégyzet a keresztvonal, a félpályavonal, az oldalfal és a hátsó fal által határolt terület. (Ha a labda éppen a fogadónégyzet valamelyik határoló vonalán pattan, akkor az adogatás érvénytelen.) A labda pattanhat a hátsó falon, az oldalfalon vagy akár mindkettőn, mielőtt padlót érne, de nem mehet a határvonalakon kívülre. A sikertelen adogatás neve fault: ebben az esetben a fogadó nyeri meg az adott labdamenetet és pontot 6
Az adogatás érvénytelen az alábbi esetekben: • • • • • • • • •
Az adogatónak legalább az egyik lába nem érintkezik a padlóval az adogatónégyzeten belül (lábhiba). Az adogató beleér a labdába, miután az már lepattant a padlóra. Az adogató felkészül és üt, de elvéti a labdát. A labda nem pattan a főfalon az adogatóvonal felett. A labda az oldalfalon pattan először, és csak azután a főfalon. A labda az ellentétes fogadónégyzeten kívül eső területen pattan a padlón. A labda bármelyik falat a határvonalon kívül érinti. Az adogató kétszer üt bele a labdába. Az adogató összeütközik a labdával, miután az visszapattant a főfalról.
A nyertes labdamenet Ha az adogató sikeresen adogatott, a játék további részében az adogatóvonalnak és a padlón lévő vonalaknak nincs szerepük, összesen csak a tin és határvonal számít. Az adogató akkor nyeri a labdamenetet, ha ellenfele • • • • • • • • •
nem tud beleütni a labdába, mielőtt az másodszor is pattanna, nem tudja a labdát a főfalra ütni, a labda előbb pattan a padlón, mint a főfalon, a labdát bármelyik falon a határvonalon kívülre üti, a labda a plafonon pattan, vagy eltalál valamit, illetve áthalad valamin, ami a plafonról lóg le, az ütő húrjain viszi a labdát, illetve ha kétszer üt bele, az ütőn kívül bármi mással a labdához ér, szándékosan akadályozza az ütésben, véletlenül zavarja meg ütés közben úgy, hogy megakadályozza egy esetleges nyerő ütés kivitelezésében (e kérdéssel kapcsolatos további részletek a fejezet „Let és Stroke” című részében olvashatók)
Biztonság Mivel két játékos mozog elég gyorsan egy kis helyiségben, elég nagy az esélye annak, hogy futás közben összeütközzenek, vagy az ütővel, illetve a labdával megüssék egymást. Éppen ezért mindkét játékosnak mindig pontosan kell tudnia, hogy ellenfele hol helyezkedik el a pályán. A labdamenet folyamán mindkét játékos felelős a biztonságért, az is, aki éppen készül elütni a labdát, és az is, aki éppen elütötte a labdát. Az utóbbinak bizonyosnak kell lennie afelől, hogy az ütni készülőnek elegendő helye van-e arra, hogy a legrövidebb úton megközelítse a labdát, és hogy lendítsen az ütőjével. Önnek mint játékosnak akadályozni ellenfelét nemcsak balesetveszélyes, de módfelett sportszerűtlen magatartás is. Mindig tudatában kell lennie annak, hogy ellenfele hol helyezkedik el, ezzel minimalizálható annak az esélye, hogy eltalálja akár az ütővel, akár a labdával. Lehetőség szerint az előkészítés alatt sem szabad elvesztenie az ellenőrzést az ütő mozgása felett, és különösen kerülendő az eltúlzott lezárás. Ha úgy érzi, hogy esetleg megütheti ellenfelét, azonnal meg kell állnia letet kérni (vagyis engedélyt arra, hogy a labdamenetet újra játszhassák).
7
Az egyik legveszélyesebb szituáció akkor áll elő, amikor a játékosnak rá kell fordulnia a labdára ahhoz, hogy visszaüthesse. Ezt nevezik körbefordulásnak. Többnyire akkor fordul elő, amikor például Ön a pálya hátsó sarkában helyezkedik el, a labda pedig az oldalsó és a hátsó falról pattan vissza a pálya közepe felé. Ilyenkor hátrálni kell a pálya közepe felé, hogy legyen helye elütni a labdát, vagyis nem szabad 180 fokos fordulatot téve teste túlsó oldalán visszaütni azt. Ez azért lenne veszélyes, mert fordulás közben nem látja, hogy ellenfele hol van. Az ellenfél pedig nem tudja, melyik irányba akarjuk ütni a labdát, így nem lehet elképzelése arról sem, merre mozduljon el ahhoz, hogy ne őt érje az ütés. Ha ez a helyzet előfordul a pályán, mindenképpen meg kell állni ütés előtt, és letet kérni. Let és stroke szabályának a rendszere A testi épség megóvása érdekében a fallabda-játékszabályok tartalmazzák a let és stroke szabályának rendszerét. Ennek a szabályrendszernek sajnos az a jellemző tulajdonsága, hogy számos esetben igen nehéz eldönteni, hogy letet, az adott labdamenet újrajátszását, avagy stroke-ot kell-e megítélni. Stroke-nak azt a helyzetet nevezik, amikor a játékos azért nyeri meg az adott labdamenetet, mert ellenfele megzavarta vagy megakadályozta abban, hogy visszaadhassa a labdát. A let, illetve stroke megítélésében mindig két szempontnak kell érvényesülnie: elsősorban a biztonságnak, másodsorban a sportszerűségnek. Ha a játékos, attól való jogos félelmében, hogy megüti ellenfelét, megáll játék közben, megérdemli a letet, ha valóban nem tudja a labdát jól visszaütni. Kezdő játékosok hajlamosak arra, hogy azonnal letet kérjenek, amint a zavarás legkisebb gyanúja is felmerül, ami növeli ugyan a játék biztonságát, de nem érvényesül benne a sportszerűség szempontja. Az a játékos ugyanis, amelyik megállította a játékot, nyilvánvalóan előnyhöz jut, mert ha nem kért volna letet, ellenfele megnyerhette volna a menetet. Az is gyakran megesik, hogy az ellenfél ugyan elkövet mindent azért, hogy elkerülje a zavarást, de a kedvezőtlen helyzetet mégis ő maga okozta azáltal, hogy gyenge volt az ütése. Ilyenkor megérdemli, hogy elveszítse a labdamenetet. Tehát amikor egy játékos megáll, azt kell figyelembe venni, hogy mi lenne a feltételezhetően fair eredmény. Ha az a játékos, aki nyilvánvaló fölényben van, megáll azért, mert az ellenfél az útjában van, akkor az igazságos döntés a stroke megítélése. Annak érdekében, hogy világosabbak legyenek a letre és a stroke-ra vonatkozó szabályok, tekintsünk át három, a pályán gyakran felmerülő helyzetet: Az ellenfelet eltalálja a labda A szabály azt mondja, hogy ha az ellenfél elütötte a labdát, akkor attól a pillanattól kezdve az Ön rendelkezésére áll a főfal teljes egésze. Éppen ezért, ha a labda beleütközik az ellenfélbe, akkor attól függ, hogy stroke vagy let jár-e, hogy a labda egyenesen a főfal felé repült-e. Ha arrafelé repült, akkor Önt megilleti a stroke, hiszen ellenfele korlátozta, miatta nem állt rendelkezésére a teljes főfal. Ha az ütközés előtt a labda az oldalfalak valamelyike vagy a hátsó fal felé repült, akkor let jár.
8
Szándékosan tilos a labdával célba venni az ellenfelet, mert nemcsak példátlanul sportszerűtlen, de igen veszélyes magatartás is. Ha az a helyzet áll elő, hogy úgy érzi, ellenfelét megütné a labda, nem szabad beleütni. Ilyenkor ugyanaz érvényes, mint az előző esetben. Ha az ütés kivitelezése esetén a labda a főfal felé repült volna, akkor Önnek stroke jár, más esetben let. E szabály alól egy kivétel van, nevezetesen, mikor Ön ráfordul a labdára (körbefordulás). Soha nem jár stroke, akár eltalálta a labdával ellenfelét, akár megállította ütését az utolsó pillanatban, hogy ezt elkerülje. Ilyenkor az sem számít, hogy a főfal felé haladt-e a labda, vagy más irányba. Ebben a helyzetben az egyetlen lehetőség megállni és letet kérni. A körbefordulás fogalmán nemcsak azt értjük, amikor 180 fokos fordulatot tesz a pálya hátsó sarkában, hanem azt is, ha a háta mögé engedi a labdát, vagy ha a lábai között, illetve a háta mögött üti vissza. Ellenfele gátolja Önt a labda elérésében A szabály kimondja, hogy amint az ellenfél elütötte a labdát, lehetővé kell tennie, hogy Ön a legrövidebb úton közelíthesse meg a labdát. Ha ellenfele megakadályozza ebben, akkor attól függ a helyzet megítélése (let vagy stroke), hogy az Ön elmaradt ütése pontot érhetett volna, avagy sem. Az egész tehát azon múlik, hogy milyen volt az ellenfél ütése. Ha jó ütés volt, és Önnek csak arra lett volna esélye, hogy játékban tartsa a labdát, akkor letet kell kapnia, ha azonban gyenge ütés volt, és Ön valószínűleg pontot szerzett volna, akkor ezért stroke jár. A szabályok szerint mindent el kell követni azért, hogy elérjük a labdát. Ez a szabály azt az esetet igyekszik kiküszöbölni, mikor a játékos csak azért kér letet egy enyhén zavarásgyanús helyzetben, mert az ellenfél túl jót ütött, vagy mert már nincs ereje a labda után menni. Ez korántsem jelenti természetesen azt, hogy teljes sebességgel kell belerohanni az ellenfélbe ahhoz, hogy letet kérjünk. Úgy kell megállni, hogy lehetőleg elkerüljük az összeütközést. Az ellenfél nem hagy elég helyet ahhoz, hogy megfelelően felkészüljünk az ütővel. A szabály szerint az ellenfélnek annyi helyet kell hagynia, hogy bármilyen ütésfajtához elegendő tér legyen. Ha az ellenfél túl közel van, és meggátol abban, hogy eléggé hátra vigyük az ütőt, vagy a megfelelő lezáráshoz van utunkban, akkor stroke jár, de ismét csak akkor, ha a labda a főfalra repült volna. Egyéb esetben let jár. A fent bemutatott zavarásos eseteken kívül let jár még az alábbi esetekben is: • • •
ha a labda elszakad, szétszakad, széthasad a menet közben ha adogatásnál a fogadó nem állt készen, és kísérletet sem tett rá, hogy visszaüsse a labdát ha bármilyen zavaró körülmény adódik, akár a pályán, akár azon kívül
A pontjelzős és a döntőbíró feladata A legmagasabb szintű rendezvényeken a mérkőzéseknél két személynek van szerepe a játékosokon kívül: a pontjelzőnek és a döntőbírónak.
9
A pontjelző feladatai: • • • •
bejelenti a mérkőzést a közönségnek, bemondja a mérkőzés állását, közli az elrontott adogatást, az aláütést (a labda a tinre pattan), ha a labda kimegy, ha kettőt pattant, vagy kétszer értek bele, elismétli a döntőbíró döntéseit.
A döntőbíró feladatai: • • • •
állást foglalni, amikor a játékosok letet kérnek, állást foglalni, ha a játékosok nem értenek egyet a pontjelző által bemondottakkal, kijavítani a pontjelző esetleges tévedéseit (pl. a mérkőzés állásával kapcsolatban), ellenőrizni a felmelegítő játék időtartamát, illetve hogy mennyi szünetet tartanak a játékosok egy-egy játszma között (90 másodpercnyi szünet engedélyezett).
A fenti két tisztséget időnként egyetlen ember tölti be, de az a leggyakoribb, hogy maguk a játékosok látják el a feladatot. Ilyenkor az adogató szokta bemondani az eredményt az adogatás előtt, hogy minél kevesebb ok legyen a vitára az állást illetően. A zavarással kapcsolatos kérdésekben közös megegyezéssel szokás dönteni. Ez sokszor vitához vezet, mely általában lettel végződik. Mindazonáltal a szabály értelmében nem felajánlani a strokeot, amikor az járna, illetve letet kérni azért, mert nem tudtuk volna visszaadni a labdát, csalás! Ha játék közben úgy érzi, megilletné a let vagy a stroke, esetleg kérése van, akkor a döntőbíróhoz, ha bíró nincs, akkor ellenfeléhez kell fordulnia. Ennek szabályos módja a "let, please" elhangzása. Stroke-ot kérni nem lehet: vagy a döntőbíró, vagy a játékosok közös határozata fogja megszabni, hogy let vagy stroke jár-e a kérő félnek. Fontos szabály, hogy a kérést közvetlenül az esemény után lehet csak elmondani, néhány ütéssel később vagy a menet befejezése után már nincs rá lehetőség. Pontozás A mérkőzéseken ma már többnyire az új pontozási rendszert használják, amelyben egy játszmát 11 pontig játszanak, és minden labdamenet pontot ér. A játszmát pontazonosság esetén 2 pont különbséggel lehet megnyerni. Ha a fogadó nyeri meg a labdamenetet, pontot kap, és megszerzi a következő adogatás jogát is. Amikor a játszma állását bemondják, mindig az adogató játékos pontját mondják először. Például ha az hangzik el, hogy 3-5 az állás, az azt jelenti, hogy az adogató játékosnak 3 pontja van, a fogadónak pedig 5. Ha mindkét játékosnak ugyanannyi pontja van, például 3-3, azt 3 "egyenlő"-nek nevezik. A szigetországban még rendeznek olyan versenyeket, ahol hagyománytiszteletből a régi 9 pontos számolást alkalmazzák. Az ESF egy rövid próbaidőszak után hivatalosan is felhívta tagjainak figyelmét, hogy átállt a 11 pontos rendszerre. Európában ma már minden hivatalos versenyt ebben a formában bonyolítanak le. Vannak ettől eltérő formák is ezt inkább csak az érdekesség kedvéért említjük meg. A hagyományos számolás szerint egy játszma 9 pontig tartott, ahol csak az adogató szerezhetett pontot. Ha a fogadó nyerte meg a labdamenetet, akkor csak az adogatás jogát nyerhette meg. Amennyiben a játszma végén a játékosok 8:8-as pontazonossággal álltak, a 10
fogadó dönthette el, hogy 9 vagy 10 pont megnyeréséig tart a játszma. Mindkét esetben 1 pont különbséggel is lehet játszmát nyerni. Általában a 10 pontot szokás választani, 9 pont esetén ugyanis az adogató egyből játszmalabdát kap - ami azt jelenti, hogy egy labdamenet választja el a játszma megnyerésétől -, vagy mérkőzéslabdát, ami pedig azt, hogy csupán egy pontot kell szereznie a győzelemhez. Létezik egy amerikai pontozási rendszert is, de ezt nagyon kevés versenyen alkalmazzák. Ebben az esetben minden játszmát 15 pontig játszanak, és pontot szerezni attól függetlenül lehet, hogy ki adogatott. Ilyenkor a rövidített játék akkor következik, ha az állás 14-14. Ekkor a fogadó szintén választhat, hogy 15 vagy 17 pontig tartson a játszma. Eltérően a másik pontozási rendszertől, itt nem olyan könnyű megmondani, hogy melyik választás a jobb stratégia. 15 pont esetén a szerváló játszmalabdát kap, de mivel a fogadó is szerezhet pontot, ha megnyeri a labdamenetet, ez játszmalabdát jelent a fogadó számára is. A játékosok többsége úgy tartja, hogy biztonságosabb a 17 pontot választani, de igazából nem lehet eldönteni a kérdést, inkább megérzés kérdése az egész. Érezni kell, hogy van-e esélyünk a következő labdamenet megnyerésére.
11
II.
Felhasználói dokumentáció
Hardver-szoftver követelmények Szoftver: A program Microsoft .NET 3.5 környezetet és legalább Microsoft XNA Framework Redistributable 3.1-et igényel. Tesztelt operációs rendszerek: • •
Microsoft Windows XP SP3 Microsoft Windows 7
Hardver: A futtatáshoz az operáció rendszer és a futóprogramok hardverigényén felül a • •
klienshez 64 MB RAM, szerverhez 16 MB RAM
szükséges.
Telepítés Ha már a szükséges Frameworköket telepítése után maga a játék ill. a szerver telepítést nem igényel.
A program részei Kliens: • • • •
squash.exe settings.sqs Records (Mappa) Content (Mappa, XNA média anyagok)
Szerver: •
squash_server.exe
A program használata Indítsuk el a squash.exe –t, egy menü jelenik meg előttünk. 12
Connect Itt tudunk már egy elindított szerverhez csatlakozni, a Name mező kitöltése után megadjuk a szerver ip címét, aztán a Join as Player vagy Joins as Spectator gombra kattintva csatlakozunk a szerverhez. Play against computer Számítógép nehézségének beállítása után megküzdhetünk a géppel. Practice Gyakorló üzemmód. Nincs energiaszint, lehet gyakorolni a különböző ütéseket. Ha a labda szabálytalan helyre megy, akkor „újraterem” a pálya közepén. Replay A felvett játékokat több kameranézetből visszanézethetjük. Sound: On / Sound: Off Hang ki/be kapcsolása Hangerő csúszka Jobb alul található a menü zenéjének a hangereje. Exit Kilépés a programból
Játék közben Nézés Egér Mozgás W, A, S, D gombokkal tudunk mozogni a pályán. Ugrás Space Ütés A bal egérgomb lenyomásának hosszával állíthatjuk az ütés erősségét, az ütés a gomb felengedésekor történik meg, ha a labdához „elég” közel tartozkodunk. Chat T betűvel tudunk üzenetet küldeni ellenfelünknek. Come on C betűvel azt monjuk: „Come on!”
13
Játék közbeni képernyő információk • Jobb oldalon látható az energiaszintünk. Futásnál és ütésnél csökken, ha „pihenünk” azaz nem mozgunk akkor emelkedik. • Középen fent látható az ütőerő. • Bal fent az eredmény.
A szerver használata Help A segítség megjelenítése Exit Szerver leállítása és kilépés Parancssor Parancsok: • • • • •
start, szerver elindítás (program indításánál automatikusan elindul) stop, szerver leállítása a program befejezése nélkül példa: „say: hello world”, hello world chat üzenet küldése kick: kirugás név alapján kickid: kirugás ID alapján
14
III. Fejlesztői dokumentáció Osztálydiagram Metódusok és változók nélkül, ezek a következő fejezetekben egyesével tárgyalom a jobb áttekinthetőség kedvéért.
15
Game Attribútumok: - GraphicsDeviceManager graphics; - GraphicsDevice device; - SpriteBatch spriteBatch; + Computer computer; + Hud hud; + Networking networking = new Networking(); + Record record; - double waitTime = -1.0f; - const double timeToWait = 3.0f; - KeyboardState previousKeyboardState = Keyboard.GetState(); + GameObject player = new GameObject(); + GameObject opponent = new GameObject(); - GameObject court = new GameObject(); - GameObject courtout = new GameObject(); + GameObject ball = new GameObject(); + Sounds sounds; - float energy = 100.0f; - float minEnergy = 20.0f; - float energyDownAtRun = 0.25f; - float energyDownAtMaxHit = 3.0f; - float energyUpAtRelax = 0.15f; - float energyDownAtJump = 2.0f; - int screenX = 0; - int screenY = 0; - MouseState originalMouseState; - float leftrightRot = 0.0f; - float updownRot = 0.0f; + CamState camState = CamState.FreeLook; - const float rotationSpeed = 0.0015f; - const float powerChange = 150.0f; + const float powerMin = 30.0f; + const float powerMax = 100.0f; - float acceleration = 6000.0f; - const float jumpMov = 400.0f; + float drag = 0.01f; + double playerGravity = -980.0; + int cameraHeight = 165;//150; - const float moveSpeed = 3.0f; + Vector3 cameraRotatedTarget; + bool canHit = false; - float targetDistance = 500.0f; - float hitPower = 25.0f; + float viewAngle = 32.0f; + float hitDistance = 150.0f; - const float wallSlow = -0.65f; + string opponentName = "Computer"; + string yourName = "Ates"; - bool isWaitTime = false; - ShowState beforeEsc; + float currentPower = 0; + int playerPoint = 0; - double maindiag; - const double xall = 968;
16
- const double yall = 244; + int opponentPoint = 0; - bool antialiasing = true; - Matrix cameraProjectionMatrix; - Matrix cameraViewMatrix; - Vector3 cameraPosition = new Vector3(2.19f, 581.0f, 877.0f); + GameState gameState; + GameState nextGameState; + GameMode gameMode = GameMode.Practice; + const float courtX = 280.0f; + const float courtZ = 445.0f; + float fem = 42.0f; - const float rollSlow = 0.5f; + double defaultdisplaytime = 3; + ShowState showState; + bool soundEnabled = true; + double gravity = -980.0; + bool backFromMainWall = false; + int dropNum = 0; - const float wallSize = 120.0f; - int maxPoint = 11; - float showResultTime = 6.0f; + bool isRunGame = false; - bool setMusicVolumeButtonDown = false; - double lastMove; - double waitAfterLastMove = 1000; - double lastMessageSentTime = 0; - MouseState lastMouseState; + GameTime _gameTime;
Metódusok: public Game()
Game osztály konstruktora. protected override void Initialize()
Inicializálja a változókat. protected override void LoadContent()
Betölti a média anyagokat. (3D modellek, képek, hangok, zenék) public void RestartGame(GameTime gameTime) Új játék indítás gameMode–nak megfelelően protected override void Update(GameTime gameTime)
Játék motorja, aktuális kép kiszámolása. public void SendInformationsToServer()
Pozíció elküldése szervernek. public void UpdateGameState(GameTime gameTime)
Játékállapot frissítése. private void DecraseEnergy(float value)
17
Energia csökkentése. private void AddToCameraPosition(Vector3 vectorToAdd)
Camera pozíció módosítása. private void ProcessInput(float amount, GameTime gameTime)
Egér és billentyűzet input kezelése. private void UpdateBall(GameTime gameTime)
Labdafrissítés. (Lokálisan) public void PlayerFail(GameTime gameTime)
Játékos hibázik. public void SetWaitTime(GameTime gameTime)
Várakozási idő beállítása. public void MatchEnd(GameTime gameTime)
Meccs vége. public void WaitTimeStale(GameTime gameTime)
Várakozási idő lejárt. public void PlayerServe(GameTime gameTime)
Játékos szervál. public void OpponentFail(GameTime gameTime)
Ellenfél hibázott. private bool isBallIn()
Labda a pályán belül található? private void reSpawnBall()
Labda „visszatevése” a pálya közepére. private void UpdateViewMatrix()
Nézet mátrix frissítése. private void Hit(GameTime gameTime)
Játékos üt. void DrawGameObject(GameObject gameobject)
GameObject objektum kirajzolása. protected override void Draw(GameTime gameTime)
Az Update() utáni frissített jelenet kirajzolása. public void GetConsoleCommand(string cmd)
Console parancsok kezelése. public void BackToMainMenu()
18
Leállítja a felvételt, bontja a kapcsolatot és visszalép a főmenübe. public void PlayAgainPressYes()
„Play again?” kérdésre Yes-re klikkeltek. public void PressExit()
Kilépés public void OptionsSaveToFile()
Kilépés előtt az aktuális beállítások mentése fájlba. public void OptionsLoadFromFile()
Indítás után leállítás előtt állapotok visszaállítása. public void PressPracitce()
Gyakorló módra váltás. public void PressSoundOnOff()
Hang ki/be kapcsolása public void PressVSComputer()
Számítógép elleni módra váltás public void SetComputerDiff(int diff)
Számítógép nehézségének a beállítása. public void PressConnectAsPlayer()
Csatlakozás játékosként. public void PressConnectAsSpectator()
Csatlakozás nézőkét. public void PressConnect()
Csatlakozás gombra klikkelés. public void PressResume()
Resume gombra klikkelés. public void PressReplay()
Replay gombra klikkelés. public void UpdateMusicVolume(GameTime gameTime)
Menü zene hangerejének a frissítése. public void ChangeScreen(ShowState _showState)
Képernyőváltás. public void PressDisconnect()
Disconnect-ra klikkelés.
19
public void UpdatePlayerPosition(byte id, Vector3 newPositon, float rotation)
Ellenfeles pozíció(k) frissítése. public void UpdateBallPosition(Vector3 newPositon)
Labda pozíció frissítése. (Szervertől) public void NetworkPlayerServe()
Hálózati ellenfél szervál. public void NetworkPlayerFail(int failPlayerId)
Hálózati ellenfél hibázik. public void StartReplay(string fileName)
Lejátszás elindítása.
Button Ezek a gombok jelennek meg a menüben. Attribútumok: + int x; + int y; + int width; + int height; # byte alpha; # Texture2D texture, normalTexture, onMouseOverTexture; + bool isVisible = false; # Game parentGame; # Hud parentHud; # int borderSize; # bool pressedDown = false; # bool pressedUp = false; # bool lastIsMouserOver = false; # bool isMouserOver = false; + bool isEnabled = true; # MouseState lastMouseState; + delegate void OnClick(); + delegate void OnClick2(int num); - OnClick onClick; - OnClick2 onClick2; # int diff;
Metódusok: public Button(Game _parentGame, Hud _parentHud, int _width, int _height, byte _alpha, Texture2D _texture, Texture2D _onMouseOverTexture, int _borderSize, bool _isVisible, OnClick _onClick)
Button osztály konstruktora. Minden ami az adott gombhoz tartozik itt kerül inicializálásra. 20
public void SetLocation(int _x, int _y)
Pozíció megadása. public void Update(GameTime gameTime)
Gomb frissítése. public void Draw(SpriteBatch spriteBatch)
Gomb kirajzolása public void _onMouseOverTexture)
ChangeTexutre(Texture2D
_texture,
Texture2D
Gomb texturáinak módosítása. public void ChangeClick(OnClick newClick)
Onclick esemény módosítása.
ReplayButton Ezek a gombok visszajátszás betöltésekor jelennek meg. Attribútumok: + string buttonText; + string fileName;
Metódusok: public ReplayButton(string _buttonText, Game _parentGame, Hud _parentHud , int _width, int _height, byte _alpha, Texture2D _texture, Texture2D _onMouseOverTexture, int _borderSize, bool _isVisible, string _fileName) : base(_parentGame, _parentHud , _width, _height, _alpha, _texture, _onMouseOverTexture, _borderSize, _isVisible, null)
Ugyan azt tudja mint a Button, csak tartalmaz egy String-et a gombon és egy elérési utat egy fájlra. public new void Update(GameTime gameTime)
Frissítés public new void Draw(SpriteBatch spriteBatch)
Replay gomb kirajzolás.
Computer Számítógép működését megvalósító osztály. Attribútumok: - Game parentGame; + float computerHitDistance = 150.0f; - float computerSpeed = 2.5f;
21
- float computerEpsz = 7.0f; - float acceleration = 6000.0f; - const float computerHitPower = 25.0f; //25.0f; - float computerDisp; - int yAimHeightDisp; + GameObject computer; - const float wallSlow = -0.65f; - Vector3 leftBackCornerTarget = new Vector3(-317, 1000, (-487.5f) + (-975) * (-1 / wallSlow)); - Vector3 rightBackCornerTarget = new Vector3(317, 1000, (-487.5f) + (-975) * (-1 / wallSlow)); - Vector3 leftFrontCornerTarget = new Vector3(-317, 230, (-490.5f)); - Vector3 rightFrontCornerTarget = new Vector3(317, 230, (-490.5f));
Metódusok: public void ComputerServe(GameTime gameTime) Számítógép szervál. public void ComputerGoTo(float x, float z, GameTime gameTime)
Pozicióhoz tart. public void ComputerInCourt()
Számítógép pályán tartása. public void computerHit(bool isServe, GameTime gameTime)
Számítógép üt. public void SetComputerDiff(int computerDiff)
Nehézség beállítása public void UpdateComputer(GameTime gameTime)
Számítógép frissítése.
GameObject Játék objektum, amelyeket kirajzolunk. (Ilyen például: játékosok, labda, pálya) Attribútumok: + Model model = null; + Vector3 position = Vector3.Zero; + Vector3 rotation = Vector3.Zero; + float scale = 1.0f; + Vector3 velocity = Vector3.Zero; + string type = ""; + bool isVisible = true;
Hud Menü és 2D-s rajzolások megvasítása. Attribútumok: - Game parentGame;
22
+ Texture2D powerBar; - Texture2D energyBar; - Texture2D frame; - Texture2D arrowred; - Texture2D arrowgreen; - Texture2D cursorTexture; - Texture2D energyborder; + Texture2D connectTexture; + Texture2D connectGreyTexture; - Texture2D exitTexture; - Texture2D exitGreyTexture; - Texture2D practiceTexture; - Texture2D practiceGreyTexture; - Texture2D replayTexture; - Texture2D replayGreyTexture; - Texture2D soundOnTexture; - Texture2D soundOnGreyTexture; - Texture2D soundOffTexture; - Texture2D soundOffGreyTexture; - Texture2D vsComputerTexture; - Texture2D vsComputerGreyTexture; - Texture2D resumeTexture; - Texture2D resumeGreyTexture; - Texture2D yesTexture; - Texture2D yesGreyTexture; - Texture2D noTexture; - Texture2D noGreyTexture; - Texture2D joinAsPlayerTexture; - Texture2D joinAsPlayerGreyTexture; - Texture2D joinAsSpectatorTexture; - Texture2D joinAsSpectatorGreyTexture; - Texture2D backToMenuTexture; - Texture2D backToMenuTextureGreyTexture; - Texture2D okTexture; - Texture2D okGreyTexture; - Texture2D listButtonGreyTexture; - Texture2D listButtonTexture; - Texture2D volumeControlTexture; - Texture2D volumeControlUpSideDownTexture; - Texture2D slideTexture; + Texture2D disconnectTexture; + Texture2D disconnectGreyTexture; + Texture2D textInputBorder; - Texture2D[] setComputerDiffTexture = new Texture2D[9]; - Texture2D[] setComputerGreyDiffTexture = new Texture2D[9]; - float arrowDeg = 0.0f; - double centerTextDisplay = -1; - bool drawArrow = false; + bool isOpponentTyping = false; - Vector2 debugDrawPoint = new Vector2(600, 80); - Vector2 debugDrawPoint3 = new Vector2(600, 120); - Vector2 fpsDrawPoint = new Vector2(600, 10); - Vector2 computerPointDrawPointText = new Vector2(10, 44); - Vector2 playerPointDrawPointText = new Vector2(10, 8); - Vector2 computerPointDrawPointPoint = new Vector2(180, 44); - Vector2 playerPointDrawPointPoint = new Vector2(180, 8);
23
- int energybarFromRight = 10; - int energybarWidth = 10; - float topMul = 1.0f / 10.0f; + bool isGameInfoVisible = true; - bool isVisiblePing = true; - Vector2 pingDrawPoint; - ShowState beforeShowstate; - byte lineHeight = 20; - byte showTime = 12; //sec - float paleTime = 800; //millisec - List<TimeSpan> consoleTimeList = new List<TimeSpan>(); - List<string> consoleStringList = new List<string>(); - List
consoleColorList = new List(); - List consoleColorShadeList = new List(); - Vector2 consoleDrawPoint = new Vector2(100, 100); // bal alsó sarok - float consoleSize = 0.8f; //0.75f; - GraphicsDeviceManager graphics; - List<Button> buttons = new List<Button>(); - Button buttonYes, buttonNo, buttonShowMessageOk; + double startPracticeTime = 0; + List<double> parcticeHelpTime = new List<double>() - List<string> parcticeHelpString = new List<string>() - Color practiceHelpColor = Color.Yellow; - List texts = new List(); + TextInput consoleCursor; + TextInput getName; + TextInput getServerIpAddress; - Color cursorColor = Color.White; - byte cursorAlpha = 255; - ShowState showStateBeforShowMessage; - string showMessageText; + bool drawFPS = false; - byte dark = 100; - Texture2D menuBackGround; + Button resumeButton; + Button connectButton; + Button disConnectButton; - Button playVSComputer; - Button practiceButton; - Button replayButton; - Button soundButton; - Button exitButton; - byte menuDark = 100; - Button connectAsPlayer; - Button connectAsSpectator; - Button backToMenu;
24
- Button backToMenu3; + List replayButtons = new List(); - Button[] setComputerDiffButton = new Button[9]; - Button backToMenu2; - Color LabelColor = Color.Yellow; //new Color() - Color LabelShadeColor = new Color(0, 0, 0, 180); - Color ResultLabelColor = Color.Yellow; - string centerText; - int lastMouseX; - int lastMouseY; + SpriteFont font; + SpriteFont fontSmall; + const string playerServeText = "You serve, go to serve rectangle and serve!"; + const string opponentServeText = "Opponent serve, receive the ball!"; + const string playerFail = "Fail, opponent won the point!"; + const string opponentFail = "Opponent fail, you won the point!"; + const string youWin = "Congratulations, You win! :)"; + const string youLoose = "You loose :("; + const string nextGame = "Play another game?"; + const string setComputerDiff = "Set computer difficulty";
Metódusok: public void LoadContent(ContentManager Content)
Képek betöltése. public void CreateButtonsAndTexts(ContentManager Content)
Gombok és szövegdobozok létrehozása. public void CreateListButtons()
Visszajátszások listázása. public string FileDestToName(string fileName)
Fájl eléréséből kivágja a fájl nevét. public bool IsAnyTextInputActivate()
Van-e aktív textinput? public void SetDrawPoints(GraphicsDeviceManager graphics)
Kirajzolási pontok beállítása. public void UpdateArrow(GameObject ball, GameObject player)
Segítő nyíl kiszámolása. public void DisplayCenterText(GameTime time, string text, double dtime)
Középső üzenet megjelenítése. 25
public void player)
UpdateHuds(GameTime
gameTime,
GameObject
ball,
GameObject
Menü és információk frissítése. public void UpdateCursor()
Kurzor frissítése. public void UpdatePracticeHelp(GameTime gameTime)
Segítség frissítése. public void UpdateButtonsAndTexts(GameTime gameTime)
Gombok és szövegdobozok frissítése. public void DrawHuds(GraphicsDeviceManager spriteBatch, GameTime gameTime, float energy)
graphics,
SpriteBatch
Menü és információk kirajzolása. public void DrawSetComputerDiff(SpriteBatch spriteBatch)
Számítógép nehézségi szintjének kirajzolása public void spriteBatch)
DrawArrow(GraphicsDeviceManager
graphics,
SpriteBatch
Nyíl kirajzolása. public void DrawEnergy(float SpriteBatch spriteBatch)
energy,
GraphicsDeviceManager
graphics,
Energia kirajzolása. public void spriteBatch)
DrawConsoleList(GraphicsDeviceManager
graphics,
SpriteBatch
Konzol lista kirajzolása. private void UpdateConsoleList(GameTime gameTime)
Konzol lista frissítése. public void AddLineToConsole(string text, Color color, GameTime gameTime)
Sor hozzáadása a konzollistához. public void DrawMouseCursor(SpriteBatch spriteBatch)
Egér kurzor kirajzolása public void DrawButtonsAndTexts(SpriteBatch spriteBatch)
Szövegdobozok és gombok kirajzolása. public void DrawAskNextGame(SpriteBatch spriteBatch)
„Új játék?” kirajzolása. public void ShowMessage(string text)
Felugró üzenet. public void DrawShowMessage(SpriteBatch spriteBatch)
Felugró üzenet kirajzolása. 26
public void CloseShowMessage()
Felugró üzenet bezárása. public void DrawMenu(SpriteBatch spriteBatch)
Menü kirajzolása. public void DrawConnect(SpriteBatch spriteBatch)
Kapcsolódás kirajzolása. public void DrawSetReplay(SpriteBatch spriteBatch)
Visszajátszás betöltésének kirajzolása.
Networking Hálózat kezelése. Attribútumok: - const int sampleTcpPort = 1986; - const int sampleUdpPort = 1987; + static int messagesPerSecond = 60; - string userName; - StreamWriter swSender; - StreamReader srReceiver; - TcpClient tcpServer; - Thread thrMessagingTCP, thrMessagingUDP; - IPHostEntry ipAddr; - IPAddress ServerIpAddress; + bool isConnected; + Socket soUdp; + JoinState joinState; + IPHostEntry localHostEntry; + string serverAddress = ""; + string myAddress = ""; + string myLocalPort; - Game parentGame; + byte myId; + int playersOnServer = 0; + int actPlayerId = 0; + TimeSpan pingTimeSpan; + DateTime sendPingTime; + int ping; + double RefreshPingTime = 1000; + double lastRefeshPingTimeMilli;
Metódusok: public bool SetNetworking(Game _parentGame, _serverAddress, JoinState _joinState)
Kapcsolat teremtés a szerverrel. private bool InitializeConnection()
Kapcsolat inicializálása. 27
string
_userName,
string
public void SendImTypingMessaage(bool isTyping)
Gépelek üzenet küldése szervernek. public void CloseConnection(bool AddLine)
Kapcsolat bontása. private void ReceiveMessages()
TCP üzenetek fogadása. private bool ReceiveSyncMessage()
Szinkron üzenet fogadása. public string CutFromColon(string str)
Karakterlánc levágása „:” –tól a végéig. public void KeepListeningUDP()
UDP üzenetek fogadása. public void GetPongMessage()
Pong üzenet fogadása. public Vector3 GetVector3FromPack(byte[] pack, byte from, byte to)
Bájtsorozat Vector3-á konvertálása. public float GetFloatFromPack(byte[] pack, byte from, byte to)
Bájtsorozat Float típussá konvertálása. public void SendMessage(string str)
Üzenet küldése szervernek. public void SendChatMessage(string message)
Chat üzenet küldése. public void SendOurPositionToServer(Vector3 position, float rotation)
Játékos pozíciójának küldése a szervernek. public void SendHitVectorToServer(Vector3 hitVector)
Ütés küldése szervernek. public void SendPing()
Ping küldése. public static Byte[] SerializeMessage(T msg) where T : struct
T típus bájttömbbé alakítása public static T DeserializeMsg(Byte[] data) where T : struct
Bájttömb T típussá alakítása private byte[] cutByteArray(byte[] toCut, byte from, byte to)
Bájttömb levágása, from –tól a to –ig 28
Record Felvétel készítése illetve lejátszása. Attribútumok: - Game parentGame; - const float recFPS = 100; + string filename; + ReplayMode replayMode = ReplayMode.None; - TextWriter tw; - TextReader tr; - double fileGameTime = 0.0; - bool isReplay = false; - double recBeginTime; + bool isRec = false; + int showRecordEndTime = 5000; + double playStart = 0.0; - string line, readFileName; + float fps_milisecond; + float last_fps_milisecond; + GameMode recMode; + ActPlayer actPlayer; + static List<string> list = new List<string>(); - int readedLine = 0;
Metódusok: public void RecBegin(GameTime gameTime)
Felvétel indítása. public void Recording(GameTime gameTime)
Felvétel készítése. public void RecEnd()
Felvétel befejezése. public void RecordChangeActPlayer()
Aktuális játékos változásának felvétele. public void RecordHitSound(float volume)
Ütés hang felvétele public void RecordHitAirSound(float volume)
Mellé ütés felvétele. public void RecordComeon(float volume)
„Come on!” felvétele public void RecordBallBounceSound(float volume)
Labdapattanás felvétele.
29
public void RecordResult()
Eredmény felvétele. public void InitRecFile(string getFileName)
Felvétel fájl inicializálása. public void ReadRecFile(GameTime gameTime)
Felvétel fáj olvasása. public void EndReplay()
Lejátszása vége
Sounds Hangok és zene kezelése. Attribútumok: + bool isSound = true; + float musicVolume = 0.2f; + float toVolume = 0.2f; + float settedVolume = 0.2f; - const float musicVolumeMul = 0.5f; + double changeMusicTime = 2000.0f; + double changeTime; - Game parentGame; - SoundEffect[] hitSound = new SoundEffect[10]; - SoundEffect[] ballBounceSound = new SoundEffect[3]; - SoundEffect[] hitAirSound = new SoundEffect[3]; - SoundEffect[] beepSound = new SoundEffect[1]; - SoundEffect[] showMessageSound = new SoundEffect[1]; - SoundEffect[] clickSound = new SoundEffect[1]; - SoundEffect addconsoleline; - SoundEffect comeOn; - Song menuMusic;
Metódusok: public void LoadSound(ContentManager Content)
Hangok betöltése public void PlayHit(float power)
Ütés hang lejátszása. public void PlayHitAir(float power)
Mellé ütés hang lejátszása. public void PlayBallBounce(float power)
Labda pattanás hang lejátszása. public void PlayBeepSound(float power)
Beep lejátszása. 30
public void PlayComeOn(float power)
„Come on!” lejátszása. public void PlayShowMessageSound(float power)
Felugró üzenet figyelmeztetés hang lejátszása. public void PlayClickSound(float power)
Klikk hang lejátszása. public void AddConsoleLinekSound(float power)
Konzol listához hozzáadás hang lejátszása. public void SetMusicVolume(float _musicVolume)
Zene hangerejének beállítása. public void changeMusicVolume(float _musicVolume)
Zene hangerejének halkítása. public void StartMenuMusic()
Zene indítása. (Menübe érkezéskor) public void StopMusic(GameTime gameTime)
Zene leállítása. (Menüből kilépéskor) public void UpdateMusicVolume(GameTime gameTime)
Menü hangerejének frissítése
TextInput TextBox XNA-s implementációja. Attribútumok: - Texture2D border; + int x, y; - xna.Keys prevChar; - xna.Keys[] prevChars = new xna.Keys[] { }; - int equalLetters = 0; - double lastPressedTime = 0; - double smallBreak = 30; - double largeBreak = 300; - Game parentGame; - Hud parentHud; + bool isVisible = false; + bool isActive = false; - Texture2D powerBar; + string text = ""; - int cursorPos = 0; + bool cursorActive = false; - Color cursorColor = Color.White; - float cursorSize = 0.76f; - int cursorHeight = 17;
31
- double blinkTime = 400; - double lastBlinkChangeTime = 0; - bool isVisibleBlink = true; - int width; - int height; - string name;
Metódusok: public string AddCharToTextInput(string ch, int cursor)
Karakter szövegdobozhoz fűzése a cursor pozicióban. public void Update(GameTime gameTime)
Szövegdoboz frissítése. public void Activate()
Szövegdoboz aktiválása. public void DeActivate()
Szövegdoboz deaktiválása. private void DrawTextInputCursor(SpriteBatch spriteBatch)
Szövegdoboz kurzorának kirajzolása public void Draw(SpriteBatch spriteBatch)
Szövegdoboz kirajzolása
Utilities Segédfüggvények. Metódusok: public static int RandomNumber(int min, int max)
Véletlen egész szám generálása. public static float RandomFloat(float min, float max)
Véletlen valós szám generálása.
32
IV. Állapotdiagram
V.
Forráskód
A program Microsoft Visual Studio 2008 alatt készült C# nyelven. A teljes forráskód a mellékelt CD-n található meg.
33