04 maj 2010

Modeller!

Domænemodel

Vi har fået præciseret vores domænemodel på baggrund af vores nylige overvejelser (se bilag). Modellen viser de overordnede bestanddele i spillet og sammenhængen mellem disse. Den viser, at både ’Monster’ og ’Player’ er characters og at det hele bliver samlet i en overordnet ’World’. I world er der levels, som består af tiles, hvoraf nogle er specialiserede tiles, som ikke kan passeres af characters. På udvalgte tiles ligger der ’Items’, som player skal samle op. I de første tre levels er der en gate, som ligeledes er placeret på et tile.

Domænemodellens primære funktion er at tydeliggøre de respektive elementer i spillet, hvorfor vi ikke vil uddybe nærmere her. I følgende klassediagram vil vi udspecificere og forklare de enkelte klasser.


Designmodel

Klassediagrammet har udviklet sig fra iteration til iteration og dette illustreres vha. farverne blå, grøn og rød, hvor rød viser processen i første iteration, grøn viser anden iteration og blå viser tredje iteration. Det skal dog tilføjes, at vi har ændret i klasserne efterhånden som der har været behov for det.



Tredje iteration - a work in progress

Denne iteration har vi endnu ikke overstået. MVC strukturen har gjort det forholdsvis simpelt at implementere en AI, dvs. Fjender. MoveableModel er forsåvidt ligeglad med, hvilken controller kalder dens metoder, og derfor kan vi nøjedes med at konstruere en ny controller klasse som kan interface med modellen. I stedet for at have en tastaturstyret controller, brugte vi timere som gennem hvert andet frame vurderede fjendens næste træk. Først handlede det blot om at give fjenden mulighed for at bevæge sig tilfældigt rundt. Derefter gjorde vi controlleren opmærksom på spillerens position, og udbyggede dens egenskaber til at kunne forfølge spilleren. Dette krævede implementeringen af path-finding som gør AI’en i stand til at finde rundt om forhindringer. I et forsøg på tydeliggøre ansvarsområder valgte vi at placere pathfinding funktionaliteten i en seperat klasse. Derudover måtte den enkelte pathfinding klasse danne sig et selvstændigt billede af kortet, for at sikre at flere monstre på samme tid kan benytte sig af pathfinding (det nytter ikke noget at flere monstre redigerer i de samme variabler i forbindelse med algoritmens udførsel). Vores use-cases beskrev yderligere at fjender skal kunne spotte spilleren. Dette blev løst ved at beregne afstanden fra det enkelte monster til spilleren, og på baggrund af retningen monstret vender i forhold til spilleren, vurdere om spilleren er spottet. Er dette tilfælde ophøre fjendens tilfældige spanguleren rundt på kortet, og pathfinding funktionaliteten tages i brug.
Det næste skridt i denne iteration, bliver at spiller og monster mulighed for at angribe hinanden, hvilket vil kræve nye modeller for player og monster, som naturligvis kan benytte funktionaliteten i MoveableModel. Derudover bliver monstre placeret tilfældigt på scenen på nuværende tidspunkt, hvorfor de altså også kan blive placeret midt i et træ – giver lidt sjove fejl, men dette er kun midlertidigt for at teste vores AI.

Anden iteration

Ved at bruge MVC fra starten har vi sikret at koden er let at udbygge og ansvarsområder for de enkelte klasser er tydeligt definerede. For at begynde at skabe en egentlig tilebaseret verden lavede vi en level klasse som kunne håndtere flere statiske tiles, hvis funktion er at styre hvorvidt de kan betrædes, og derudover hvilken type de er (græs/sten/træ osv). Derudover ønskede vi at sikre at det var let at lave nye levels uden at ændre direkte i koden, ved at loade dem fra en xml-fil. MoveableModel klassen måtte derfor udbygges således at man ikke kan bevæge sig hen på en tile som ikke kan betrædes.
Tilslut tilføjede vi View klasser som kunne vise vores kort således som det var defineret i et Level objekt, og lavede en klasse som kan vise vores nye MoveableModel. Dermed havde vi nu et simpelt grafisk interface, hvor vi kunne følge vores bevægelige objekt idet vi interagerede med det gennem tastaturet.
Til næste iteration besluttede vi at det nu var på tide at få fjender på banen, og evt. et begyndende kampsystem.

Første iteration

I denne iteration implementerede vi den grundlæggende struktur i spillet. Vi tog udgangspunkt i MVC mønstret og startede med at lave grundlæggende klasser som understøttede MVC strukturen. BaseModel, BaseView og BaseController er således abstrakte klasser som udelukkende er til for at facilitere de grundlæggende egenskaber ved MVC mønstret. Dernæst konstruerede vi klasser som understøttede den tile-baserede struktur vi ønskede spillet skulle have. TileModel klassen har således et meget afgrænset ansvarsområder, nemlig at holde styr på en tiles placering på kortet (det grid af tiles som tilsammen udgør det level som spilleren kan bevæge sig på), og dens faktiske placering på scenen i pixels. Det skal med det samme nævnes at TileModel ikke udtrykker et statisk ”felt” som enkelte felter på et skakbræt, men blot et objekt som placerer sig i et grid som ikke nødvendigvis svarer til pixels på en scene.
Vi gjorde os det klart fra starten at målet med denne iteration ikke var at få noget grafisk, men blot en grundstruktur og muligheden for at ændre placering på banen med tastaturet. View-delen i MVC strukturen blev derfor udbygget med egentlig grafik, men tracede blot væsentlige attributter i modellerne.
Vi ønskede at tilføre vores model en mulighed for at flytte placering på vores grid. Ved at nedarve fra TileModel fik vi den grundlæggende funktionalitet til at holde styr på vores færden i en tile-baseret verden. Klassen fik fra start kun få metoder som gjorde os i stand til at ændre placering på baggrund af en retning som var statisk definerede strings (”up”, ”down”, ”left”, ”right”). Dernæst oprettede vi en controller klasse som kunne modtage tastetryk og fortolke disse til instruktioner til modellen om at ændre placering i en bestemt retning. Tilslut ønskede vi at vise ændringer i placering ved at forbinde en Viewklasse til vores MoveableModel som kunne trace ændringer når vores model ændrer placering.
Med denne grundlæggende funktionalitet havde vi nu overstået en væsentlig del af spillets grundstruktur. Vi havde eksekverbar kode som uden videre ville kunne viderebygges til at understøtte grafisk elementer på en scene. Vi havde imidlertid ikke noget kort at bevæge os rundt på endnu og derfor ingen mulighed for at begrænse spilleren (og eventuelle fjender) i at bevæge sig på. Dette, og en simpel grafisk repræsentation, vurderede vi var de vigtigste elementer at få med i næste iteration.

Usecases

Usecase 1 – At vinde spillet

For at vinde spillet skal player på de første tre levels samle en nøgle op, som er adgangsgivende til næste level. Når spilleren når til 4. level, skal den kæmpe mod et monster og dræbe dette for at vinde spillet.

Usecase 2 – At komme videre til næste level

Spilleren navigerer hen til nøglen og idet den bliver samlet op, skifter farven på gaten, som indikerer at det er muligt for spilleren at komme videre til næste level. Spilleren går hen til gaten og kommer videre til næste level.

Usecase 3 – Kampsituation

Spilleren når op ved siden af monstret og angriber monstret hvorved den påfører monstret skade. Spilleren angriber igen indtil monstret har mistet alle sine HP. Monstret er nu dræbt og forvinder fra banen.