War In Europe. Een RTS netwerkspel op macro niveau



Vergelijkbare documenten
Vakgroep CW KAHO Sint-Lieven

1. Over LEVIY 5. Openen van de activiteit 2. Algemene definities 6. Inloggen op het LEVIY dashboard 3. Inloggen 6.1 Overzichtspagina 3.

Datatypes Een datatype is de sort van van een waarde van een variabele, veel gebruikte datatypes zijn: String, int, Bool, char en double.

Oefeningen Jaarproject I

Software Design Document

HANDLEIDING PROGRAMMEREN IN PASCAL (LAZARUS)

Vraag 1. Vraag 1a TERUGKOPPELING PROEFTENTAMEN. Software architecture

Katholieke Hogeschool Kempen ASP

Labo 2 Programmeren II

Handleiding CMS. Auteur: J. Bijl Coldfusion Consultant

Naam project Lost And Found Animals Lokaal gehost Percentage van het totaal geleverde werk 1 Cindy Jansen 50% 2 Eline Steyvers 50%

Sparse columns in SQL server 2008

Website van het openbaar ministerie Korte gebruikershandleiding voor Content Managers

icafe Project Joeri Verdeyen Stefaan De Spiegeleer Ben Naim Tanfous

Web applicatie Tolk- en vertaalaanvragen: Handleiding voor aanvragers SVBBO

Handleiding digitaal dossier

5. Documenten Wat kan ik met Documenten? 1. Over LEVIY. 5.1 Documenten terugvinden Uitleg over vinden van documenten.

NACSPORT TAG&GO HANDLEIDING Eigenschappen knop

ProjectHeatmap. Onderzoeksrapport v Dennis Wagenaar

Software Design Document

BLReactions. Copyright 2016 by B-Logicx. All Rights Reserved.

Inhoudsopgave. Hoofdstuk 1.RMI...2

Elbo Technology BV Versie 1.1 Juni Gebruikershandleiding PassanSoft

Klassen & objecten, overerving, abstracte klassen, debuggen, interfaces, formulieren, polymorfie, statische methoden, event-handlers

HANDLEIDING PROGRAMMEREN IN PASCAL (LAZARUS)

Handleiding voor het gebruik van de community website van OBS t Padland

Swhite bvba Frankrijklei 104 bus Antwerpen. flux.be. Flux webdesign. Versie 1.0.2

Quickstart. Browser instellingen

Zorgmail handleiding. Inhoud

Temperatuur logger synchronisatie

Handleiding DEMO Digitaal Wedstrijd Formulier (DWF)

Les 15 : updaten van gegevens in de database (deel2).

Berichtenbox. Auteur : Rakesh Poeran Datum : 19 mei 2015 Versie : Documentnaam : Berichtenbox

Hoofdstuk 16: Grafieken en diagrammen: hoe

4.4 Voeg ruimtes toe Hoe ga jij te werk? 1. Over LEVIY. 4.5 Aanwezigen Zijn er aanwezigen bij de DKS-controle? 2. Algemene definities. 3.

Handleiding uitwisseling Tekla Structures RFEM versie: Dlubal RFEM Tekla Structures 19.1

Xelion ESPA koppeling Handleiding Beheer V1.6

1. Over LEVIY. 5. Meldingen Wat zijn meldingen? 5.1 Technische melding toevoegen Hoe voeg ik een melding toe?

Planbord installatie instructies

Projectdocument Airport Suite. The Wright Company: Zehna van den Berg Steven Both Reinier Maas Adolfo Ochagavía Bas Ouwerkerk Thijs van der Zaan

De controlekaart volledige werkloosheid

HANDLEIDING DMS Plugin Installatie, configuratie & werking

Elektronisch factureren

AFO 142 Titel Aanwinsten Geschiedenis

Technische nota AbiFire Rapporten maken via ODBC

API...1 Identificatie...1 Opties...2 Acties...3 Webserver...6 Heartbeat...6 Buffer groottes...8

WEBSHOPKOPPELING. Flexibel, efficiënt & accuraat

HANDLEIDING. coachtool

MOTUS- APP: De gebruikersgids

Inhoudsopgave. GlinQ: BattleField2 beheertool, Handleiding versie 1.0

Automatisering voor Financiële Dienstverleners. Werken met Queries en Merge Documenten. For more information visit our website at

AAN DE SLAG L O G I S T I E K G E D E E LT E i

Handleiding. Opslag Online voor Windows Phone 8. Versie augustus 2014

Software Engineering Groep 4

v.1.11 Verenigingenweb handleiding Genkgo koppeling: Exact Online

Voor de database wordt een Access 2000 bestand gebruikt, met voorlopig 1 tabel:

Software Design Document

1. Milieuklacht Handleiding opladen XML in mkros Werken met Refertes... 5

1. Introductie 2. Omschrijving 2 Omschrijving van de onderdelen (voorzijde) Algemeen 3

Gebruikers Toevoegen. EasySecure International B.V. +31(0) Support.EasySecure.nl. v

IMP Uitwerking week 13

case: use-case-diagram

Fuel. Handleiding voor installatie en gebruik

SportCTM 2.0 Sporter

Hoe "PO Omzetten" gebruiken om een factuur te maken van een purchase order

Netwerk Interfacing Data Logging.

INFITT01 - Internettechnologie WEEK 8

Puntjes op de I. Baris Firat

Ons privacybeleid. Persoonsgegevens

10. BEHEER MODULAIR KWARTAAL

Variabelen en statements in ActionScript

Getting-started tutorial. Versie 1.0

Informatica. Objectgeörienteerd leren programmeren. Van de theorie met BlueJ tot een spelletje met Greenfoot... Bert Van den Abbeele

SportCTM 2.0 Startscherm trainer

Landelijk Indicatie Protocol (LIP)

Spraakmakers 1 Handleiding Multimedia voor docenten Pagina 1-1 van 17. Handleiding voor docenten bij Spraakmakers Multimedia

HANDLEIDING TRACK & 1. Track & Trace s bewerken Algemeen s s bewerken Triggers Beschikbare Tags 5

Een eerste applicatie

Werkwijze Licenties Use2Day

Ten opzichte van de vorige versie zijn er een aantal functionaliteiten verbeterd, ook zijn er een aantal functionaliteiten toegevoegd:

GEBRUIKERSHANDLEIDING MAAKJETRAINING.NL 1

Ontwerp van Informatiesystemen

Xampp Web Development omgeving opzetten onder Windows.

DrICTVoip.dll v 2.1 Informatie en handleiding

Inhoudsopgave. Hoofdstuk 1.JMS...2

Session Beans.

Software Test Plan. Yannick Verschueren

Handleiding DigiRecord.nl

Versturen van vanuit een Delphi VCL toepassing

Object Oriented Programming

HANDLEIDING FLEXI-SMS

Starterskit begeleiders ONLI

case: toestandsdiagrammen

QUESTI OPSTARTGIDS ALGEMENE INSTELLINGEN EN LVS

References. Handleiding. Intelly B.V. En nu verder (documentmanager)

DAVE. Migratie Cockpit A BUSINESS INTELLIGENCE ODYSSEY. Inleiding. Voorbereiding

Quickstart. 1 Inleiding Welkom bij projectadministratie.nl. 2 Browser en instellingen. 2.1 Browsers. 2.2 Instellingen

Chris de Kok TDI 3. Vak: Software Architectuur Datum: Docent: Fons van Kesteren

Schoolmail. Handleiding voor het gebruik van je Snorduffel-adres. Druk deze handleiding NIET af. Ze is 25 pagina s lang en je hebt niet alles nodig.

Transcriptie:

War In Europe Een RTS netwerkspel op macro niveau Jennick Scheerlinck, Pieter Vancoillie, Jelle De Weerdt Vakoverschrijdend Eindproject Academiejaar 2007-2008 3de jaar Bachelor in de industriële wetenschappen informatica Hogeschool Gent

Inhoud Het spelconcept... 3 Gamestructuur... 3 Het prototype... 6 De kaart... 6 Ontwikkeling van de kaart... 6 De kaart en het spel... 12 Het DTO pattern... 14 Design pattern voor de client... 16 De implementatie van het DTO... 17 Dataflow binnen het DTO pattern... 18 Communicatie... 20 DTO en XML... 20 Server... 21 Gameserver... 22 Overzicht van DTO-berichten... 25 Timers en delay... 27 Databank... 28 Tekortkomingen... 28 Uitbreidingen... 29 Besluit... 30 Taakverdeling... 30 Installatiegids... 31 Handleiding... 32 Bijlage :... 34 2

War In Europe Een RTS netwerkspel op macro niveau Het spelconcept Het spel is gebaseerd op risk met een RTS (real time strategy) invloed. (we nemen hier risk als voorbeeld omdat dit gekend is maar het gaat hier om het genre afgeleid van het historische kriegspiele, het had even goed ridderstrijd of panzer generaal kunnen zijn) Dit geeft een aantal belangrijke concept veranderingen: Er zal gespeeld worden met verschillende individuele eenheden, dit verschilt met het risk concept van waar de eenheid een soldaat is in elk leger (cfr 5,10,100 soldaten op een vakje). Er zal de mogelijkheid zijn om met verschillende legers te spelen. Legers verschillen in grote en individuen. De stap naar real-time verschilt met het risk concept de turn based is. Hier schuilt de uitdaging van het goed synchroniseren. Maar geeft het spel wel een extra drive omdat je niet op je beurt moet wachten. De uitbreiding naar het second life concept is dan niet ver weg. Zo kan een spel op een server blijven doorgaan. Gamestructuur Elke speler regeert over een koninkrijk (Kingdom), dit koninkrijk beschikt over 1 leger (Army) bestaande uit meerdere divisies. Elke divisie (Division) is gestationeerd in een stad (City) en elke stad is het centrum van een gebied (Area). Een divisie kan bestaan uit meerdere eenheden (Unit). Er bestaan 3 soorten eenheden: cavalerie (Cavalry), infanterie (Infantry) en artillerie (Artillery). Elk type eenheid heeft een bepaalde sterkte en snelheid. Wanneer een divisie uit verschillende types eenheden bestaat dan wordt de snelheid bepaald door het traagste type. Een divisie verplaatst zich dus steeds in groep. De sterkte van een divisie is de som van de sterktes van alle eenheden apart. Ook bevat elke eenheid een moraal. Wij hebben dit geïmplementeerd met het idee om hier later op verder te bouwen, bijvoorbeeld na een gewonnen gevecht stijgt de moraal van de gewonnen divisie. Ook dachten we aan een rust -actie, zodat een divisie enkele uren kan uitrusten waardoor hun moraal stijgt maar tijdens hun rust zouden ze wel kwetsbaarder zijn voor vijandelijke aanvallen. Deze functies zijn nog niet geïmplementeerd maar zijn ideale uitbreidingen voor ons spel. Wij hebben ons spel zo geïmplementeerd dat er in de toekomst redelijk eenvoudig uitbreidingen kunnen toegevoegd worden. Zo zijn alle eenheden afgeleid van een ouderklasse Unit. Ook is er een hoofdstad (Capital) geïmplementeerd. Die afgeleid is van de klasse City en momenteel dezelfde functie heeft. Maar op deze manier is het later eenvoudig om extra karakteristieken toe te voegen aan de hoofdstad zoals versterkingen, beter beveiligt of andere extra eigenschappen. Elk game object houdt een hashmap bij van alle kingdoms, en telkens worden dan via enkele iteraties alle divisies of alle areas behorende tot de kingdoms overlopen. 3

Wanneer er een nieuw spel gestart wordt dan kan de speler een kingdomnaam, een kleur en een gebied op de map kiezen. De map (Map) is onderverdeeld in 20 delen elk bestaande uit 10 areas waarvan 1 de capital is. Bij initialisatie krijgt elke speler per area 1 divisie bestaande uit 10 infantery-, 5 cavalery- en 2 artillery-eenheden. Zijn army bestaat dus uit 10 van deze divisies. Een gevecht wordt steeds uitgevochten in een City en wordt steeds uitgevochten door 2 divisies. De divisie die gestationeerd is op de city, de verdediger en de divisie die vanuit een buurgebied is overgekomen, de aanvaller. De battle functie laat de divisies unit tegen unit vechten, steeds gebaseerd op de sterkte van de unit, de moraal en een factor geluk. De sterkste divisie wint het grootste deel van de tijd maar soms kan een zwakkere divisie met geluk, een sterkere tegenstander verslaan. Wanneer de aanvaller wint dan wordt de area van die city nu een area van de aanvaller en heeft hij dus zijn kingdom uitgebreid. Naast aanvallen kan een divisie ook gewoon verplaatst worden (move) naar een ongecontroleerde area. Deze area wordt dan automatisch nieuw grondgebied van het kingdom. Een divisie kan ook opgesplitst worden (split) in 2 delen. Het nieuwe deel verplaatst zich naar een andere city en de overgebleven units van de ouderdivisie blijven gestationeerd op de city waar ze stonden. Natuurlijk kunnen 2 divisies dan ook samengevoegd (merge) worden tot 1 grote divisie. De sterkte, snelheid en moraal worden dan automatisch aangepast aan de nieuwe samenstelling. Nog even iets over een divisie. Elke divisie heeft een Start en End attribuut die een city voorstelt, wanneer de start- en end-city dezelfde zijn dan is de divisie in deze city gestationeerd. Wanneer beide verschillend zijn dan is de divisie onderweg van de start-city naar de end-city. De progression teller houdt bij hoever hij al gevorderd is. Tenslotte heeft elk kingdom ook resources maar dit concept is nog niet uitgewerkt wegens tijdsgebrek. Het was de bedoeling dat elk kingdom nieuwe units kan aanmaken tegen een bepaalde kost. Het kingdom moest dus over voldoende resources beschikken om een unit te kunnen aanmaken. Dit kingdom zou dan na elk gewonnen gevecht een bepaalde hoeveelheid resources bij krijgen. Ook zou elke kingdom per gecontroleerd gebied een bepaald aantal resources krijgen. Een kingdom wordt dus gecontroleerd door de speler. Zijn gegevens zitten in een account (Account) die in de database bijgehouden wordt. Naast het aantal accounts heeft een game ook nog een GameInfo object nodig om een Game te starten. Dit GameInfo object houdt een aantal parameters bij zoals de tijdsmodus, het aantal spelers en het ip van de gameserver. Samen met de accounts kan dan een nieuw spel gestart worden. 4

Hieronder het vereenvoudigde klassendiagram van de game structuur: Figuur 1 - Klassendiagram gamestructuur 5

Het prototype Als vorm van analyse kiezen we ervoor een snel prototype te maken. Zo worden onze ideeën snel vastgelegd en weten we in welke richting we werken. Het geeft een idee van de opvolging van de gui s. Ook de lay-out als de functionaliteit van elke gui kan dan bekeken worden. Figuur 2 - Prototype gamegui De kaart Ontwikkeling van de kaart De basis van de kaart wordt gemaakt met behulp van een grafische editor. Dit is de kaart waarvan we vetrekken: Figuur 3 - De originele kaart Deze wordt als volgt bewerkt: - Alle namen van de gebieden worden verwijderd. - Alle gebieden krijgen een unieke grijswaarde toegewezen. 6

- Grenzen en punten voor steden worden zwart gekleurd (grijswaarde (0,0,0)). - Buren overzee worden verbonden door middel van een stippellijn. Aanpassingen die niet noodzakelijk zijn, maar het spel wel ten goede komen: - De indeling van de landen wordt zo aangepast dat er 10 gebieden zijn per land. - De zee wordt met een textuurfilter aangepast om het mooier te maken. Bij dit proces wordt een begeleidend bestand aangemaakt. Dit bestand bevat voor elk gebied een naam en een id en groepeert de gebieden in naties. Vormvereiste voor dit bestand is dat het id van een gebied overeenstemt met de grijswaarde van het gebied in het grafische bestand (id 1 = rgb(1,1,1)). Dit bestand wordt het map.dat-bestand genoemd en ziet er nu zo uit: NATION Great Britain PROVINCES 1 Belfast 2 Dublin 3 Highlands 4 Edinburgh 5 Umbria 6 Wales 7 Birmingham //(enzovoort voor alle provincies en naties). De map ziet er nu zo uit: Figuur 4 - De herwerkte kaart in finale vorm Dit is de finale toestand van het grafische bestand. De grafsiche bewerkingen worden gemaakt in Photoshop. Deze versie bevat nog een aantal tekortkomingen: - Het uitvoerformaat van de kaart is van belang omdat vele bestandsformaten een compressie impliceren waardoor niet alle pixels hun oorspronkelijke rgb-waarde behouden. Onze voorkeur gaat uit naar het PNG-formaat, aangezien we hiermee het beste resultaat verkrijgen. 7

- Vele grafische editors passen ongevraagd anti-aliasing technieken toe. Meestal wordt dit door de ontwikkelaar geapprecieerd, maar hier zorgt dit voor het vormen van vele artefact pixels rond de randen van de gebieden. Vooral deze tekortkoming was moeilijk weg te werken. Aangezien geen enkel teamlid een ervaren Photoshop-gebruiker is was het niet mogelijk de kaart op te slaan zonder interferentie van anti-aliasing effecten. Het begeleidende bestand map.dat wordt verder aangepast met een nevenprogramma dat geen deel uitmaakt van het project. Het kan gezien worden als de map editor voor dit project. Bij het uitbreiden naar een spel met meerdere kaarten is deze editor heel goed te gebruiken. Het is dan wel een must deze nog op punt stellen. Niet elke code van elke iteratie van deze editor werd bewaard, sommige stukken werden overschreven om sneller te kunnen werken. Om map.dat te voltooien, zijn er verschillende iteraties nodig. Elke iteratie zal het map.dat-bestand inlezen van de vorige iteratie en hieraan informatie toevoegen. In de eerste iteratie krijgt elke natie een kleur toegewezen. Dit gebeurt door de standaardkleuren bepaald in de java api als circulaire lijst te doorlopen (deze lijst werd opgesteld voor de editor). Manueel wordt aan het bestand de locatie van het grafische bestand met de natievlag toegevoegd. Dit kan in een latere versie deel uitmaken van de editor. Figuur 5 Mapeditor, eerste iteratie Het map.dat-bestand ziet er nu als volgt uit: NATION Great Britain NATIONCOLOR -16776961 NATIONFLAG uk.gif PROVINCES 1 Belfast (.) Voor het tekenen van de divisies is het noodzakelijk de coördinaten van de steden te kennen. In de tweede iteratie kan er op elk gebied geklikt worden. Daarna wordt er geklikt op de stad van het gebied. Deze coördinaten worden onthouden en uitgeschreven naar de nieuwe versie van map.dat. Na het aanklikken van de stad wordt de id van het gebied weergegeven op de kaart ter hoogte van de stad. 8

Figuur 6 Mapeditor, met steden coördinaten Het map.dat-bestand ziet er nu als volgt uit: NATION Great Britain NATIONCOLOR -16776961 NATIONFLAG uk.gif PROVINCES 1 Belfast 138 507 // coördinaten 2 Dublin 90 576 3 Highlands 225 441 4 Edinburgh 241 500 5 Umbria 271 581 6 Wales 239 662 7 Birmingham 320 629 8 London 301 679 9 Denmark 528 558 10 Halland 609 552 ( ) De derde iteratie zorgt voor het inlezen van de burenlijsten. Buren werden aangeduid door te klikken op de kaart. Met een toggle-knop wordt duidelijk gemaakt of we een nieuw startgebied gaan selecteren of een bijkomende buur. Het map.dat-bestand ziet er na afloop zo uit : NATION Great Britain NATIONCOLOR -16776961 NATIONFLAG uk.gif PROVINCES 1 Belfast 138 507 2 6 // buren 2 Dublin 90 576 1 6 21 3 Highlands 225 441 4 31 32 4 Edinburgh 241 500 3 5 5 Umbria 271 581 9

4 6 7 6 Wales 239 662 1 2 7 8 7 Birmingham 320 629 5 6 8 9 31 8 London 301 679 6 7 12 13 9 Denmark 528 558 7 10 156 157 10 Halland 609 552 9 36 37 158 ( ) Een laatste iteratie werd toegevoegd aan de map editor om de omschreven rechthoeken van elk gebied te berekenen. Dit werd gedaan om het zoeken en het tekenen te versnellen omdat dit vertraagd wordt door artefact pixels die tot het gebied worden gerekend maar het helemaal niet zijn. Deze omschreven rechthoeken werden eerst in runtime berekend maar dit kostte te veel initialisatietijd. Eerste berekening van omschreven rechthoeken toont dat foute pixels ervoor zorgen dat ook omschreven rechthoeken veel te groot worden genomen. Figuur 7 - Mapeditor, omschreven rechthoeken Hierop ziet men dat deze omschreven rechthoeken niet zullen helpen. De veel te grote rechthoeken zijn te groot en overlappen te veel om bruikbaar te zijn, het is zelfs niet te zien welke rechthoek bij welk gebied hoort. Een oplossing voor dit probleem is een buddysysteem te gebruiken als filter. Enkel pixels die grenzen aan genoeg buddy s komen in aanmerking om de omschreven rechthoek te bepalen. De grens wordt streng gelegd op 8 buddy s. Pixel (x,y) is een geldige pixel: (x-1,y-1) (x,y-1) (x+1,y-1) (x-1,y) (x,y) (x+1,y) (x-1,y+1) (x,y+1) (x+1,y+1) Pixel (x,y) is geen geldige pixel: (x-1,y-1) (x,y-1) (x+1,y-1) (x-1,y) (x,y) (x+1,y) (x-1,y+1) (x,y+1) (x+1,y+1) Het resultaat van het buddysysteem: 10

Figuur 8 - Mapeditor, omschreven rechthoeken met buddy filter Deze manier van berekenen geeft een goed resultaat. Het is duidelijk te zien welke rechthoek bij welk gebied hoort. In het spel geeft dit als voordeel als enkel pixels binnen de rechthoek van een gebied tot een gebied kunnen behoren dat er minder artefact pixels aanwezig zijn. Ook een voordeel is dat er een behoorlijke snelheidswinst wordt geboekt door het niet meer overlopen en hertekenen van artefact pixels. Nadeel is dat sommige landen hierdoor een dikkere grens krijgen en de kromming van de grens minder goed is dan ervoor. Deze selectie kost snel enkele minuten berekeningstijd voor een map van 200 gebieden en is daardoor niet geschikt om tijdens runtime te worden uitgevoerd. Het toevoegen van dit proces aan de map editor is dus een goede keuze. De rechthoek wordt uitgeschreven tussen de rij met id en naam en de rij met de burenlijst. De parameter zijn de x- en y-coördinaten van de linker bovenhoek en de breedte en de hoogte van de rechthoek. Het map.dat bestand ziet er nu als volgt uit: NATION Great Britain NATIONCOLOR -16776961 NATIONFLAG uk.gif PROVINCES 1 Belfast 138 507 70 496 112 85 2 6 2 Dublin 90 576 56 546 106 100 1 6 21 3 Highlands 225 441 182 411 63 60 4 31 32 4 Edinburgh 241 500 182 473 79 65 3 5 5 Umbria 271 581 226 504 82 94 4 6 7 6 Wales 239 662 199 591 72 94 1 2 7 8 11

7 Birmingham 320 629 279 573 63 77 5 6 8 9 31 8 London 301 679 201 625 182 101 6 7 12 13 9 Denmark 528 558 510 512 61 115 7 10 156 157 10 Halland 609 552 571 512 94 70 9 36 37 158 (...) Dit is de finale versie van het map.dat-bestand. Zo is de kaart en het begeleidende bestand klaar voor de applicatie. De kaart en het spel Tijdens het initialiseren van het spel wordt de kaart ingelezen. Eerst wordt het begeleidende bestand map.dat ingelezen. Zo kunnen de nodige hashes en lijsten worden opgemaakt die de informatie van de van de kaart zoals gebieden en buren zullen bijhouden. Als tweede stap wordt het grafische bestand ingelezen. Alle rechthoeken gedefinieerd in de begeleidende file worden bekeken. Zo wordt er per gebied een lijst aangelegd van pixels die tot het gebied behoren. Alles wat buiten de unie van deze gebieden valt wordt gezien als achtergrond. Deze achtergrond is voor het overgrote deel van de tijd statisch. Toch blijkt dat deze achtergrond soms opnieuw moet getekend worden, bijvoorbeeld als een divisie zich verplaatst over zee. Als oplossing hiervoor kunnen we de achtergrond als een extra gebied zien en hiervoor ook een lijst van pixels bijhouden. Deze oplossing volstaat echter niet, aangezien deze lijst veel te lang is en telkens aanleiding geeft tot heapspace overflow. Ook het terug inladen van het grafische bestand als basis voor de Image waarop er wordt getekend zorgt overschrijding van de java heapspace. In de laatste iteratie van de map editor schuilt er echter een mogelijke oplossing. Hier wordt de omschreven rechthoek bepaald. Als we deze rechthoek nu verder gaan opdelen in driehoeken, krijgt men een veel compactere voorstelling. Zodra een driehoek volledig tot het gebied behoort, wordt hij niet verder gedeeld en wordt de driehoek toegevoegd aan de lijst van beschrijvende driehoeken. Zo verkrijgen we een veel compactere voorstelling dan de lijst met pixels. Stap 1: Stap 2: Stap 3: 12

Stap 4: Stap 5: Stap 6: Stap 7: Stap 8: Stap 9: Sicilië wordt hier verdeeld in 14 driehoeken. Elke driehoek is te beschrijven door drie punten. Dit zorgt in totaal voor 42 integers die Sicilië beschrijven in plaats van op pixelbasis ongeveer 1000 integers. Het terugschroeven van deze hoeveelheid data moet heapspace problemen kunnen tegengaan. Hier blijft keuze in de manier van onderverdelen. Men kan verdelen in rechthoeken of driehoeken. Als er bijvoorbeeld verdeeld wordt in driehoeken, zijn er verschillende keuzes hoe te verdelen, men kan bijvoorbeeld de hoogtelijn of deellijn kiezen. Aan de omschreven rechthoek kan ook nog gewerkt worden. Zo kan het zijn dat bij minder strenge voorwaarden de grenzen beter zullen benaderd worden. Het is hier een evenwicht vinden tussen artefact pixels verwijderen en anderzijds zo goed mogelijk de grenzen benaderen. Om deze techniek te implementeren was er geen tijd meer. Zo blijft het spel werken met lijsten met pixels. Verder onderzoek is hier mogelijk en nuttig. Met een timer wordt de refreshrate van het model ingesteld. Bij elke update van het model wordt de kaart opnieuw getekend. Hiervoor wordt een object opgebouwd van de klasse Image. Als basis voor deze image nemen we het grafische bestand dat de kaart voorstelt. Dit wordt gedaan tijdens het initialiseren van de kaart. Nadien wordt deze image tijdens elke update bijgewerkt en naar het scherm geschreven. Het herwerken van de kaart verloopt in verschillende stappen. Eerst worden de gebieden gekleurd. De manier waarop is afhankelijk van welke kleurenmodus er geselecteerd is. Na het kleuren van de gebieden wordt de view van de speler bepaald. De view wil zeggen het gebied dat zichtbaar is voor de speler. Binnen dit gebied kan de speler de aanwezige divisies zien en er informatie over opvragen. Gebieden die worden geselecteerd en die niet behoren tot de view van de speler zullen enkel info geven over het gebied en niet over wie zich in het gebied bevindt. Na het bepalen van de view worden alle divisies binnen dit gebied getekend met de iconen overeenstemmend met hun koninkrijk. Wanneer de gebruiker over de kaart beweegt met de muis zullen de gebieden oplichten. Hier wordt slechts het gebied dat de focus verliest en het gebied dat de focus krijgt inclusief de eventuele divisies die er zich op bevinden opnieuw getekend. Dit is nodig om het spel niet te vertragen. Er wordt immers geluisterd naar de mousemove-event en de frequentie van het optreden van dit event ligt te hoog. Zo blijft er te weinig tijd over om de map volledig opnieuw te tekenen. 13

De speler bekijkt altijd slechts een deel van de kaart tegelijkertijd. Het is mogelijk gebruik te maken van de pijltjestoetsen om het venster te verplaatsen en zo een ander deel van de kaart te bekijken. Dit maakt het mogelijk van eenzelfde niveau van detail te hebben onafhankelijk van de grootte van de kaart. Zo geeft dit de gebruiker een blik die voor hem overzichtelijk is. Dit wordt praktisch gerealiseerd door het uitsnijden van een stuk uit de image die de grootte heeft van de kaart. Deze snede heeft dan de grootte van het venster en met de linkerbovenhoek als referentie. Op de coördinaten van een punt dat wordt aangeklikt in het venster, wordt dan een translatie toegepast om hetzelfde punt in het assenstelsel van de kaart te beschrijven. Er wordt de speler ook de mogelijkheid gegeven om in en uit te zoomen op de kaart. Hiervoor herschalen we eerst de image van de kaart voor we het venster er uit snijden. Het aantal maal dat er kan worden ingezoomd of uitgezoomd is beperkt. Zo worden performantieproblemen vermeden. Men kan de vraag stellen of verder in- of uitzoomen nuttig is. De speler beschikt over verschillende kleurenmodi om de situatie van het spel te verduidelijken. Zo is er als basis de native colormode. In deze kleurenmodus wordt de kaart ingekleurd zodat alle gebieden van eenzelfde natie dezelfde kleur hebben. Zo krijgt de speler ook de vlag van de natie te zien bij het selecteren van een gebeid. Een tweede kleurenmodus is player colormode. Hier krijgen de gebieden de kleur van het koninkrijk waartoe ze behoren. Zo krijgt de speler de vlag van het koninkrijk te zien waartoe het geselecteerde gebied behoort. Als laatste modus is er de friend or foe colormode. Deze modus dient ervoor om heel snel vijandig, neutraal en bevriend gebied te onderscheiden. Vijandelijk gebied wordt rood gekleurd, neutraal geel en bevriend groen. Het idee voor een extra kleurenmodus dringt zich op. Waneer een divisie geselecteerd wordt, kan deze verplaatst worden door gebruik te maken van het commandopaneel rechtsonder. Doch zou het spel beter speelbaar zijn mocht na selectie de kaart overgaan in select colormode. Select colormode toont dan welke gebieden er bereikbaar zijn met deze divisie. Het geeft de mogelijkheid dat de speler een doelgebied aanklikt om de geselecteerde divisie te verplaatsen. Deze modus is nog niet geïmplementeerd maar lijkt wel een waardevolle uitbreiding. Het DTO pattern Het Data Transfer Object is een pattern voor het uitwisselen van gegevens tussen tiers in een multitier toepassing of tussen componenten in een gedistribueerde toepassing. De toegang tot gegevens via een remote component impliceert vaak verzamelen van gegevens uit meer dan één informatiebron. Het aantal berichten dat wordt verstuurd om aan een verzoek te voldoen kan de prestaties van de vragende toepassing of van de client beïnvloeden. Het doel van het DTO pattern is de prestatieproblemen op te lossen verbonden aan gedistribueerde componenten die remote toegang hebben tot data van businessobjecten. Per definitie is een DTO een object dat uitsluitend voor het transport van data wordt gecreëerd. De gegevens, die uit één of meerdere informatiebronnen kunnen voortkomen, worden ingepakt in een Java bean. De bean reist dan plaatselijk door de toepassing, of (wat nog belangrijker is) wordt serialized en over het netwerk verzonden. Serialization van de Java bean laat clients toe om toegang te hebben tot modelinformatie van één enkel object met enkel één call. 14

Omdat een DTO een Java bean is, verstrekt het gewoonlijk geen business logica of validatie logica. Het geeft slechts toegang tot de dataleden van de bean. Sommige ontwikkelaars beklemtonen dat de bean in een DTO patroonimplementatie onveranderlijk (immutable) moet zijn omdat zijn veranderingen niet worden weerspiegeld in het systeem. Dit botst duidelijk met de JavaBeans specificatie, die vereist dat alle private attributen set en get methodes hebben. Het is de verantwoordelijkheid van de ontwikkelaar om in te staan van de onveranderlijkheid van de DTO-objecten. DTO-objecten moeten beschouwd worden als deel van het model omdat ze onveranderlijke kopijen zijn van businessobjecten. Ik vermeldde kort het serializing van objecten in het DTO design pattern. Serializing is het proces om een object in een bytestroom om te zetten alvorens het over een netwerk te verzenden. Voor aankomst wordt de bytestroom opnieuw samengebracht in een object en plaatselijk gebruikt. Java se voorziet de java.io.serializable inteface. Klassen die deze interface implementeren kunnen serialized worden. In de opdracht van het project is gespecificeerd dat de serialization moest gebeuren naar xml. Hierdoor wordt in het project deze interface niet gebruikt aangezien de java api een eigen standaard 1 voorziet voor serialization. Naast het feit dat een object-xml-object mechanisme niet veel verschilt van de serialization die de java api voorziet, is het leesbaar door zowel computers als mensen, in tegenstelling tot een serialized object. De menselijke leesbaarheid vereenvoudigt het proces van debuggen van de code omdat het produceren van verschillende instanties van hetzelfde object enkel een kwestie is van een XMLbestand aanpassen. Voorts kan men om het even welke browser gebruiken om een verzoek te verzenden naar de server en zijn reactie waar te nemen. Tot slot betekent het gebruiken van XML voor gegevensuitwisseling dat er mogelijkheid is voor communicatie tussen clients gebouwd uit verschillende technologieën, niet alleen Java maar ook van Java ME en.net, bijvoorbeeld. Anderzijds is het nadeel van het gebruiken van XML voor gegevensuitwisseling is het parsingproces en de syntactische analyse die erbij komt kijken. Voor het project werd gekozen voor de KXML library 2. Een licht gewicht parser die de mogelijkheid geeft om later een gui in Java ME te maken. Zo kan het spel verder gespeeld worden op je gsm. Gedeeltelijk wegens de vereiste dat DTO s onveranderlijk moeten zijn en gedeeltelijk voor de organisatie en netheid, is het een goed idee om twee types van gegevensobjecten in de architectuur van de client-server te hebben: lokale objecten en DTO s. Bijvoorbeeld, als u intern een object van het type ChatMessage gebruikt en zijn gegevens voorbij de JVM moest verzenden, zou u een ChatMessageDTO willen creëren, die versie van ChatMessage wordt gebruikt om de data over het netwerk te transporteren. De klasse ChatMessage maakt deel uit van het project en wordt gebruikt als voorbeeld omdat dit een eenvoudig object is. Conversies voor het mechanisme: Na het ontvangen : XML --> Object Voor het verzenden : Object --> XML 1 http://java.sun.com/j2se/1.5.0/docs/guide/serialization/spec/protocol.html#8101 2 http://kxml.objectweb.org/ 15

Figuur 9 - Interactie tussen de lagen Design pattern voor de client MVC (Model-View Controler) is één van de belangrijkste patterns voor het bereiken van een stevige clientarchitectuur. Voor complexere modellen, waar verscheidene subsystemen worden gebruikt, is het soms nuttig om MVC met het Facade pattern te combineren. Het facademodel zorgt ervoor dat vragen steeds worden doorverwezen naar een geldig model. Bijvoorbeeld als het lokaal model niet meer volstaat zal het facademodel de call doorverwijzen naar een remote model. In het project wordt het lokaal model met een vaste frequentie aangepast aan het remote model. Zo wordt het lokaal model altijd als geldig beschouwd en worden vragen direct aan het lokaal model gericht. In dit project is er dus geen nood aan een facademodel. Figuur 10 - Architectuur Model: Definieert de representatie van de informatie waarmee de applicatie werkt. Aan ruwe gegevens wordt betekenis gegeven door relaties te leggen tussen data en logica toe te voegen. De daadwerkelijke opslag van data wordt gedaan met behulp van een persistent opslagmedium, zoals de accountgegevens die opgeslagen worden in de database. De applicatie zal gegevens die gebruikt worden in het model, ophalen en wegschrijven van en naar de dataopslag via een datalaag. De datalaag is geen onderdeel van het MVC-pattern. De datalaag bevindt zich hier fysiek aan de serverside van het project. Data die enkel ingelezen worden door de gui hebben ook enkel betrekking tot de representatie en vormen geen deel van het model (pixellijsten). Het model wordt voorgesteld door een object van de klasse Model en bevindt zich in het code package. Dit object bevat een object 16

van de klasse RemoteModelProxy dat zich in het netwerk package bevindt. Zo kan het lokaal model worden aangepast aan het remote model op de server. View: Informatie wordt weergegeven via de View. Userinterface-elementen zullen gedefinieerd zijn in dit onderdeel. Controller: De Controller verwerkt en reageert op events, die meestal het gevolg zijn van handelingen van de gebruiker. Zowel de View als de Controller bevinden zich in de klasse GuiGame. De implementatie van het DTO Gegeven de objecten tussen lagen zullen circuleren als XML streams, DTO s moeten methodes hebben voor zowel het halen van gegevens uit het object als, omgekeerd, het geven van een staat aan het object via een reeks waarden die in een hashtabel worden ingekapseld. Het is noodzakelijk om een interface te bepalen. Het volgende is de interface voor DTO s: <IObjectDTO> public void populatefields(hashtable fields) Hashtable extractfields() Het gebruik van deze interface om DTO s te bepalen zal het terugwinnen van objecten vereenvoudigen omdat er kan gebruik gemaakt worden van polymorfisme. Als voorbeeld kunnen we hier het ChatMessage object gebruiken. Stel dat ChatMessage volgende attributen bezit: command message author dan kan de IObjectDTO interface als volgt geïmplementeerd worden: public void populatefields(hashtable fields) { } command = fields.get("command").tostring(); message=fields.get("message").tostring(); author=fields.get("author").tostring(); public Hashtable extractfields() { Hashtable fields = new Hashtable(); fields.put("message", message); fields.put("author", author); fields.put("command", command); return fields; 17

} Command is een attribuut van CommandDTO. Dit is de abstracte klasse die de Interface ICommandDTO implementeert. ChatMessage breidt de CommandDTO klasse uit. Zo kan gebruik gemaakt worden van polymorfisme in de Controller van de server bij het opvangen van het commando. Bij constructie van ChatMessage krijgt command als waarde de string chat. Dataflow binnen het DTO pattern Stel dat de client een chatbericht wil vesturen. Dan zal hij een ChatMessageDTO naar de server sturen. Hierop zal de sever antwoorden met een bericht met een Acknowledgement object. Dat zal een negatieve of positieve bevestiging geven, al naar gelang het succes van de verwerking van het chatbericht op de server. We zullen eerst bekijken hoe een binnenkomend bericht wordt verwerkt. Deze opvolging van methodes is gelijk aan server en client kant. Figuur 11 - Stappen voor transformatie van het antwoord van de server in een DTO Methode A: Aan de serverside luistert deze methode naar berichten die hij krijgt van de client. Deze XML berichten worden doorgegeven aan methode B als String object. Methode A is de run() methode van de SendAndRecieve thread. Deze methode zal na verwerking van het bericht een antwoord terugsturen naar de client. Aan de clientside is deze methode verantwoordelijk voor het openen van de verbinding met de server en het teruggeven van een String object met XML. Methode A wordt hier backendcomms genoemd. Signatuur: String backendcomms(string inputstring); Na het verkrijgen van de string met XML, moet het relevante IObjectDTO er uit worden gehaald. Dit zal in twee stappen worden gedaan: eerst zal de XML algemeen worden ontleed om een object te verkrijgen gebruik makende van de interface IObjectDTO, dan zal het object gecast worden naar het verwachte type. In dit voorbeeld is dit ChatMessage. Methode B: Hier wordt de String met xml omgezet in een IobjectDTO. Signatuur :IObjectDTO convertxmltoiobjectdto(string xml); Methode C: In theorie cast deze methode het IObjectDTO object naar naar ChatMessageDTO object. Aangezien het hier een commando betreft wordt er eerst in de SendAndRecieveThread gecast naar een ICommandDTO. Dit object wordt doorgegeven aan de Controller. Deze zal het dan casten naar een ChatMessageDTO. 18

Daarna wordt door de Controller een object van de klasse ChatMessage aangemaakt met de data gewonnen uit het ChatMessageDTO. Het object ChatMessage wordt doorgegeven aan de GameServer. Na het opnemen van het chatbericht zal de Controller antwoorden door een AcknowledgementDTO op te stellen. Zo krijgt de client informatie over het succes van zijn handeling. Bij het versturen van een DTO worden de stappen omgekeerd doorlopen met enkele wijzigingen. Methode C: Methode C komt theoretisch nu eerst aan de beurt. Deze stap is hier echter overbodig aangezien methode B een IObjectDTO object verwacht en er geen cast naar IObjectDTO nodig is (polymorfisme). Methode B: Deze methode zal nu zorgen voor de conversie van IObjectDTO naar een String met xml. Signatuur: String convertiobjectdtotoxml (IObjectDTO iodto); Methode A: Hier zien we dezelfde methode als bij het ontvangen. Nu zal de zendfunctionaliteit van de methode worden aangewend. Klassediagram DTO pattern : 19

Figuur 12 - Klassendiagram DTO pattern Communicatie DTO en XML De communicatie tussen server en clients is misschien wel de meest belangrijke schakel van dit project. De focus ligt hierbij voornamelijk op de bestuurbaarheid en structuur. De berichten worden omgezet naar een DTO-object en deze worden bijgevolg naar XML geparsed om zo doorgesluisd te worden over het netwerk waar client en server gebruik van maken. Deze technologieën werden reeds besproken in een vorig hoofdstuk. De server beschikt over een controller die alle binnenkomende DTO-berichten kan afhandelen. Aangezien de client gebaseerd is op het principe van polling, is er dus enkel een controller nodig bij 20

de server. Het is de server die interpreteert, verwerkt en antwoordt. De client zal dus op periodieke wijze naar updates vragen waarop de server zal reageren door de nieuwe waarschijnlijk gewijzigde toestand terug te sturen. Ook de andere opdrachtberichten die de spelbediening bevat (move, split,...) worden vanuit de client aan de server doorgegeven. Het komt er dus op neer dat de server enkel reageert en niet ageert. Ter illustratie even volgend schema (figuur DTO-schema) waarbij er bovenaan vanuit de client vertrokken wordt om zo na een circulair proces terug bij de client te eindigen. Client Netwerk Server Server Voor een goede controle en bestuurbaarheid is er geopteerd om een centrale server te bouwen. Deze server zal voortdurend actief zijn. De bedoeling hiervan is dat spelers zich op eender welk tijdstip kunnen aanmelden om een spel te spelen. Een speler zal via zijn client dus rechtstreeks verbinding maken met de main server (MS) om te connecteren via sockets. Het basisprincipe is eigenlijk vrij eenvoudig. De MS zit in een voortdurende lus waarin hij luistert naar clients die proberen te connecteren. Wanneer de MS een verbindingsoproep binnenkrijgt op zijn socket, zal hij deze aanvaarden en vervolgens meteen een SendAndRecieveThread opstarten. Vanaf dat moment zal deze Thread instaan voor de communicatie tussen de client en de server. Het spreekt voor zich dat er voor elke geconnecteerde client zo een SendAndRecieveThread zal opgestart worden. Eens deze communicatielijn opgesteld is, kan de client beginnen met het verzenden van berichten (DTO-objecten) over het netwerk. Het begint uiteraard allemaal door in te loggen. De logindto is hier verantwoordelijk voor. Hoe zo een logindto object er exact uitziet, kan u eventueel nagaan in de bijgeleverde code. Het komt er op neer dat elk DTO-object afgeleid is van de klasse CommandDTO met elk hun specifieke string-id. Dit is belangrijk want elke SendAndRecieveThread heeft zo een controller die binnenkomende pakketten zal verwerken. De controller zal op die manier, aan de hand van de string-id, de juiste verwerkingsprocessen kunnen aanroepen. 21

Er volgt een recapitulatie van de zonet beschreven structuur. Er is dus één continu draaiende MS waar clients op connecteren. Elke client krijgt één SendAndRecieveThread om te interageren met de MS. Elke SendAndRecieveThread bevat een controller om de berichten te verwerken. De relaties tussen de verschillende instanties worden nog even opgesomd: Server <-> Client (1...n) Server <-> Databank (1...1) Client <-> SendAndRecieveThread (1...1) SendAndRecieveThread <-> Controller (1...1) Tot slot nog even vermelden dat de MS het enige onderdeel van ons project is dat rechtstreeks in verbinding staat met onze online MySQL databank. Hij gebruikt de databank om accounts af te halen, om ervaringspunten te updaten, enz Gameserver De gameservers (GS) zijn de allerbelangrijkste componenten in ons project omdat ze elk instaan voor beheer van hun speelomgeving. De GS bevat het object Game die op zijn beurt alle speldata bevat. De gameservers zijn afgeleid van de klasse Thread met als die reden dat ze afzonderlijk van elkaar en van de MS moeten kunnen functioneren. De MS bevat een hashmap waarin alle bestaande gameservers opgeslagen zitten. Het is dan ook de MS die een gameserver initialiseert aan de hand van een GameInfo object. De invulling van dit object wordt later besproken. Het bevat simpelweg de parameters (naam, aantal spelers, tijdsmodus, poort, map, status,...) die nodig zijn om een gameserver op te starten naar eigen smaak. Even kort een illustratie van zo een gameserver initialisatie van op de MS: public void startgameserver(string gamename, int timemode, int maxplayers, Map map){ int port = 4444; boolean find = true; while (find){ port++; if(gameports.get(port)){ System.out.println("Starting Gameserver \""+ gamename + "\" on port: " + port); find=false; gameports.put(port, false); GameInfo gameinfo = new GameInfo(gameName, port, timemode, maxplayers, map); GameServer gs = new GameServer(gameinfo); gameservers.put(gameinfo.getgamename(),gs); gameservers.get(gameinfo.getgamename()).start(); } } } codefragment Server.java 22

De gameserver zelf is niet alleen een thread die zelfstandig draait, maar tevens vervult hij ook de rol van server, zoals zijn naam doet vermoeden. Het is namelijk zo dat de client een lijst van gameserver te zien krijgt van de main server die voorgesteld wordt in de GuiServerLobby (een visuele voorstelling van de MS). Deze gebruiker zal dan via zijn GuiServerLobby een nieuwe verbinding moeten leggen met de gekozen GS uit de lijst. Dit kan misschien verwarrend lijken, maar het bevordert de bestuurbaarheid immens. De GS bestaat net als de MS ook uit een voortdurende luisterlus waarbij hij de connectie van spelers gaat aanvaarden, maar deze keer toegepast op de spelerslimiet. Een gameserver laat dus net zoveel connecties toe als het aantal spelers dat beschreven staat in zijn GameInfo object. public boolean joingame(account a){ boolean joined = false; int maxplayers = gameinfo.getmaxplayers(); if (accounts.size() < maxplayers) { accounts.add(a); readychecks.put(a.getusername(), false); joined = true; } if (accounts.size() == maxplayers) { gameinfo.setstatus(full); } return joined; } codefragment Gameserver.java Opnieuw start ook dit soort server een SendAndRecieveThread om te kunnen communiceren met de clients. Deze SendAndRecieveThread bevat dan uiteraard ook weer diezelfde controller om de berichten te verwerken. Men kan hier dus opmerken dat er veel over hergebruik van code is nagedacht. Er wordt namelijk gebruik gemaakt van zowel de klasse SendAndRecieveThread als de klasse Controller bij de MS als bij de GS. Merk op dat de client op dit moment twee connecties bezit en dus ook twee communicatielijnen waarover berichten kunnen verstuurd worden. Opnieuw biedt dit tal van voordelen. Het belangrijkste voordeel hiervan is de terugkoppeling naar de MS. Wanneer een client (speler) een gameserver verlaat, sluit hij de connectie met deze GS af, maar hij behoudt de connectie met de MS waardoor hij terug in de ServerLobby terechtkomt. Op dit moment is de client nog steeds ingelogd en kan hij gewoon een nieuwe GS uitkiezen om nog een spel te spelen. Ook dit onderdeeltje wordt even gerecapituleerd. Er zijn dus verschillende continu draaiende gameservers waar een aantal clients op kunnen connecteren. Elke client krijgt opnieuw één SendAndRecieveThread om te interageren met de GS. De relaties tussen de verschillende instanties worden nog even opgesomd: Server <-> Gameserver (1...n) 23

Client <-> Gameserver (1...1) Client <-> SendAndRecieveThread (1...1) SendAndRecieveThread <-> Controller (1...1) Hieronder het Klassendiagram van de interactie tussen server en gameserver: Figuur 13 - Klassendiagram netwerklaag server 24

Overzicht van DTO-berichten Om een verstaanbaar overzicht te geven van de verschillende DTO-berichten die geïmplementeerd zijn, worden deze DTO-berichten opgesplitst in twee categorieën. Er kan namelijk een onderscheid gemaakt worden tussen DTO-berichten die bestemd zijn voor de main server (MS) en de DTOberichten die bestemd zijn voor de gameserver (GS). De klasse controller is eveneens voorzien om dit onderscheid te kunnen maken. Hoewel er maar één klasse controller geschreven is, kan deze toch zowel voor de MS en GS verwerking gebruikt worden. De klasse controller heeft namelijk twee aparte constructoren waarbij in de ene constructor de MS meegegeven wordt en in de andere de GS. Bij het verwerken van een DTO-opdracht die zowel door GS als MS kan geïnterpreteerd worden, volstaat een simpele test waarbij er getest wordt dat ofwel de MS ofwel de GS verschillend is van null. Dit is eigenlijk overbodig omdat de taken van de MS en de GS in de praktijk zo van elkaar verschillen dat verwarring onmogelijk is. Om toch een voorbeeld op te noemen waarbij er eventueel een null-test zou moeten geimplementeerd worden, kan men het voorbeeld van de chatfuncties aanhalen. Stel je voor dat je zowel in de ServerLobby als in de GameServerLobby wil kunnen chatten. Het chatdto dat de client dan verstuurt heeft op de MS een ander verwerkingsproces dan op de GS. In dit geval is het nodig om de null-test te gebruiken. Dit was even terzijde, want er is geen chatfunctie voorzien op de MS, aangezien dit ons totaal overbodig leek. public class Controller { private GameServer gameserver; private Server server; public Controller(Server server) { this.server = server; } public Controller(GameServer gs) { this.gameserver = gs; }... if (icommanddto.getcommand().equals("update")) { //handle update if (gameserver!= null) { iodto = new GameDTO(gameserver.getGame()); } else { throw new IllegalCommandException("update is not a valid command,"); } }... codefragment Controller.java 25

Het voorafgaande codefragment maakt duidelijk hoe de werking van de controller verloopt. Zoals reeds eerder aangegeven is er in de praktijk dus wel degelijk een verschil in de DTO-berichten om de MS aan te spreken met die DTO-berichten om de GS aan te spreken. Aan de hand van deze splitsing volgt er een kort overzicht van de verschillende geïmplementeerde DTO-objecten. De Client-Server interactie: deze vorm van communicatie staat voornamelijk in voor administratieve taken zoals login. Hieronder zullen alle DTO-berichten besproken worden die naar de MS kunnen gestuurd worden en hun antwoord, want elke actie zorgt voor een reactie. LoginDTO (actie) AccountDTO (reactie) De client stuurt zijn logingegevens door aan de MS. Deze laatste verifieert de gegevens en stuurt de opgehaalde account terug naar de client. Dit verifiëren en ophalen van de account omvat interactie met de databank. UpdateGameServersDTO (actie) GameServersInfoDTO (reactie) De client vraagt via polling aan de MS om de nieuwe toestand van de gameservers terug te sturen. Zo kan de client steeds de recentste status van elke GS bekijken (status: WAITING, FULL, PLAYING). NewGameDTO (actie) GameServersInfoDTO (reactie) De client maakt een nieuwe gameserver aan. Hij moet hiervoor bepaalde parameters instellen. Het antwoord van de MS is gewoon een nieuwe update van de gameservers. Op deze manier kan de client zijn lijst van gameservers direct updaten. De Client-Gameserver interactie: deze vorm van communicatie bestaat voornamelijk uit spelopdrachten. Bijgevolg bestaan er dus een pak meer DTO-berichten voor de interactie tussen client en gameserver. JoinDTO (actie) - AcknowledgementDTO (reactie) De client probeert een bepaalde GS binnen te gaan. Het AcknowledgementDTO bevat enkel een boolean. Dit bericht wordt gebruikt wanneer de client moeten laten weten of de overdracht al dan niet geslaagd is. GetLobbyDTO (actie) LobbyDTO (reactie) De client vraagt aan de GS om een nieuwe update van de GameServerLobby te sturen. Dit omvat voornamelijk nieuwe spelers die connecteren op de gameserver. Op deze manier weet de gebruiker ook onmiddellijk welke spelers toegevoegd zijn aan zijn chatomgeving. LeaveGameDTO (actie) AcknowledgementDTO (reactie) De client verlaat de GS. De gameserver laat weten of deze actie geslaagd of niet geslaagd was. ReadyDTO (actie) AcknowledgementDTO (reactie) De client laat aan de GS weten dat hij klaar is. Dit wil zeggen dat de client zijn land, naam en kleur gekozen heeft. Wanneer hij op de button Ready klikt zal hij reactie krijgt of de opdracht al dan niet geslaagd was. Indien de opdracht niet geslaagd was, ligt dit aan het feit dat twee spelers ofwel? éénzelfde kleur, éénzelfde naam of éénzelfde land gekozen hebben. 26

IsReadyDTO (actie) AcknowledgementDTO (reactie) De client gaat via polling steeds opvragen of de GS klaar is. De GS is klaar wanneer alle spelers een geslaagde ReadyDTO gestuurd hebben. De GS status wordt dan op PLAYING gezet. Als deze polling een positief resultaat oplevert, dan starten alle clients bijgevolg hun spelgui. UpdateDTO (actie) GameDTO (reactie) De client gaat via polling steeds de nieuwe toestand van het Game object opvragen. De gameserver reageert hier op door via Xstream het volledig Game object over te hevelen. Dit Game object bevat steeds de recentste speldata, aangezien enkel de GS dit object wijzigt. ChatUpdateDTO (actie) - ChatRevisionDTO (reactie) De client gaat via polling steeds de nieuwste chatberichten opvragen. De gameserver bekijkt de revisie van de client en stuurt alle chatberichten die de client nog niet heeft door. ChatDTO (actie) AcknowledgementDTO (reactie) De client verstuurt een chatbericht naar de gameserver. SplitDivisionDTO (actie) AcknowledgementDTO (reactie) De client probeert een divisie op te splitsen. De gameserver zal laten weten aan de client of dit al dan niet gelukt is. MoveDTO (actie) AcknowledgementDTO (reactie) De client probeert een divisie te verplaatsen. De gameserver zal laten weten aan de client of dit al dan niet gelukt is. Timers en delay Het project maakt uitvoerig gebruik van timers en delay-opdrachten om de speelbaarheid een niveau hoger te tillen. Zowel aan de clientside als aan de serverside was er nood aan een paar getimede opdrachten. De client gebruikt timers vooral voor polling. Dit wil zeggen dat de timers ingesteld zijn om na elke tik een bepaalde update te vragen aan de server of gameserver. Dit omvat: chat updates, game updates, updates voor gameserverlijst, updates voor de lobby's. De client zal zo na elke reactie van de server of gameserver steeds de recentste gegevens aan de gebruiker tonen. De gameserver gebruikt timeropdrachten als delay. Dit wil zeggen dat de GS bepaalde opdrachten die hij binnenkrijgt pas mag uitvoeren na verloop van tijd. We hebben hiervoor onze eigen delayqueue ontwikkeld. Een timer zal per tik steeds een progressie parameter aanpassen tot wanneer deze progressie de gewenste waarde bevat, daarna roept hij de juiste verwerkingsinstructies aan om tenslotte de opdracht uit de lijst te verwijderen. De reistijden zijn hier een voorbeeld van. 27

Databank Van bij de aanvang van ons project hadden we het idee om een community website te ontwikkelen waarop toekomstige spelers informatie over ons game kunnen vinden en waarop ze statistieken kunnen bekijken. Wij hebben dit dan ook geïmplementeerd in een ASP.net 3.5 applicatie. Nieuwe bezoekers kunnen zich registreren en reeds geregistreerde gebruikers kunnen zich dan inloggen. Op de site kunnen de bezoekers 5 pagina's bezoeken: Home, Gameinfo, Ranking, Contact en Private. Het inloggen gebeurt simpelweg door een sessievariabele bij te houden en eens ingelogd kan de bezoekers natuurlijk ook uitloggen en zijn persoonlijke informatie zien. Op de Ranking-pagina kunnen de gebruikers de huidige top 10 van de spelers vinden, gerangschikt op hun aantal experience points. Deze worden weergegeven door een ListView control uit ASP.Net 3.5. U kan screenshots van de website bekijken in de bijlagen. Deze accounts worden opgeslagen in een MySQL database en zijn tevens dezelfde accounts die in ons game zelf gebruikt worden. Figuur 14 databank In onze databank hebben we 2 tabellen. wieusers en wieranks, in wieusers hebben we de standaardvelden. We hebben er dan voor geopteerd om ene tweede tabel wieranks te maken zodat we later de ranking kunnen wijzigen, zodat we dus de naamgeving hiervan later dynamisch kunnen wijzigen. De ranking hangt dus af van de experience points die de speler opdoet tijdens het spelen en aan de hand daarvan wordt de juiste ranknaam gekozen bijv. korporaal of generaal. Na elk gewonnen spel geven we de winnaar een aantal experience points en geven we de verliezer ook enkele puntjes voor de moeite. Dit systeem is wel nog niet volledig geimplementeerd. Later kunnen we eventueel ook een uitgebreider puntensysteem implementeren dat punten toekent aan het aantal gewonnen battles of het aantal overwonnen vijanden of eventueel zelfs een tijdsgebaseerde puntenteling. Tekortkomingen Wegens tijdgebrek hebben we ons project niet voor de volle 100% kunnen afwerken. 28