mandag den 31. maj 2010

en spildt dag

Vi har spildt en dag pga. at vi efter ændrede variabler ikke kunne få AI'en til at virke.

fredag den 28. maj 2010

Powerups

Vi har besluttet os for at lave powerupsklassen.

Powerupsne skal have fælles collision detection på player og skal allesammen random smides af zombierne. Vi har besluttet at lægge instantieringen af powerupsne i den funktion i Level, der holder styr på hvor mange zombier, der er på scenen. Dette kommer af at hvis vi instantierer den fra den zombie, der dør mister vi parent.

3. iteration påbegyndt

Vi har nu påbegyndt 3. iteration, og er startet med det grafiske UI. Vi har brugt os selv som modeller til Player og Zombie, ved at tage billeder af os selv oppe fra et punkt og lodret ned. På billederne står vi og stikker armene ud(Zombie) eller holder et objekt der kan fungere som våben(Player), og med skiftende ben fremme, så vi kan skabe en animeret gang i spillet ved en gif-fil. Vi har fået implementeret grafikken til player, men vi vurderer stadigvæk hvorvidt Zombiens grafik skal implementeres i den nuværende Zombie-klasse, eller om der skal laves tre forskellige under-klasser hvori grafikken ligger i, mens fællesfunktionaliteterne ligger i den overordende klasse.

Efter vi har implementeret grafik på Player, er vi stødt på det problem at vores collision-detection ikke fungerer optimalt. Dette er fordi at playeren nu ikke mere blot er en cirkel, og derfor skal vi have fundet en matematisk måde at udregne punkterne på Playeren i hans nuværende form.

UPDATE:
Vi har nu implementeret grafik på de tre typer zombier og oplever en form for lag omkring lvl 25. Vi vil forsøge at udbedre dette ved at foretage trashcollection, da vores kode ikke bare glemmer de zombier fra forrige levels og derfor holder styr på alt for meget.

UPDATE 2.0:
Vi har nu lavet weak references på de eventlisteners, der tilgår zombieklassen. Lag = no more.

onsdag den 26. maj 2010

Tredje iteration

Anden iteration:

Vi har afsluttet denne, dog med et tilbagevendende kasseproblem, hvor de stadig lægger sig oveni hinanden. Vi vil forsøge at komme dette til livs ved at kigge tjekpunkterne igennem igen, da det højst sandsynligt er her fejlen ligger. Vi vil endvidere forsøge at kondensere tjeksne på kugler vs. kasser.


Tredje iteration:

I denne vil vi forsøge at implementere de sidste af opgavens krav:

  • Powerups: Ekstra liv, et supervåben over en lille periode eller et bestemt antal skud og speedboost.
  • Vi laver det så at spilleren bliver flyttet ned i hjørnet når han dør, samtidigt med at zombierne bliver flyttet lidt op på banen for at de ikke står og dræber spilleren oveni spawn-zonen.
  • Score-, liv- og levelcounter oppe i hjørnet.
  • Tekstur og grafik: Stengulv og trækasser/containere samt billeder i fugleperspektiv af os som zombier såvel som helten med en stor skyder.
Denne iteration forventes afsluttet d. 28. maj.

søndag den 9. maj 2010

For at spillet skal have nogen grad af sværhed, er det nødvendigt at fjenderne følger efter spilleren. Selve bevægelsen af zombierne er identisk med den hos Player, da denne udregnes ud fra en hastighed og en retning.
For at bestemme zombiens retning imod Player, fandt vi den indbyggede funktion Math.atan2(y,x):Number, som beregner vinklen fra (0,0) til (y,x). Funktionen returnerer en radian, som kan omregnes til grader med radian*180/Math.PI. Punktet som vi ønskede at finde vinklen til, var (zombieX-playerX , zombieY-PlayerY), og zombiens retning kunne altså findes ved:
Math.atan2(this.y-_player.y, this.x-_player.x)*180/Math.PI;

Zombierne ville således altid søge at bevæge sig imod players position, hvilket giver et problem idét de ofte vil "sætte sig fast" på den modsatte side af en kasse i forhold til playeren. Det virker heller ikke super "troværdigt" at zombierne altid ved nøjagtig hvor player er - uanset om de kan se ham eller ej (Overnaturlig lugtesans?). Behovet for en kunstig intelligens implementeret på zombierne er derfor nødvendig.

Dette har vi løst ved at implementere et check hver frame, som afgør hvorvidt zombierne kan se player, eller om han er skjult bag en eller flere kasser. Figuren nedenfor viser hvordan dette check forløber:



















Der checkes hver frame på hver femte pixel i en lige linje mellem zombien og player, om koordinatsættet befinder sig indenfor en af kasserne i banen. Hvis der er klart udsyn, vil zombien sætte efter Player, og hvis udsynet er blokeret, vil zombien gå tilfældigt rundt.
Vi har yderligere implementeret en "glemme-timer", som gør at zombierne vil "glemme" at de følger efter Player hvis de mister den visuelle kontakt i seks sekunder, hvorefter de igen stener rundt og kigger efter player.

Klassediagram


Som en ny ting har vi implementeret MovingObject og Zombie i vores klassediagram. Vi har jf. tidligere blog indlæg samlet alt funktionalitet for bevægelse i MovingObject, og det ses fra nedarvningen at MovingObject er superclass for Zombie og Player. Vi har endvidere tillføjet en association mellem Zombie og Level, da et level indeholder et bestemt antal zombier, afhængig af variablen currentLevel.

Zombie apocalypse

LOL

Ahab

Skydefunktion
Vi har nu ligeledes fået implementeret en skydefunktion til spilleren. Vi er blevet inspireret meget af vores tidligere Astroids projekt, og er arbejdet ud fra samme principper med, at skyde den vej spilleren vender. Player bliver sendt med som parameter i Bullet klassen. ’Check impact’ funktionen er næsten den samme, som den der findes i Player klassen. Den tjekker på x og y koordinator på kuglen, og tjekker på om den er indenfor scenen eller inden i en kasse. Hvis dette er tilfældet, så dør kuglen! Kuglen har yderligere en levetid på 1½ sekund, hvilket tjekkes op på af en timer, som kører funktionen ’timeisup’.
I controlleren tilføjes mellemrumstasten som skydefunktion til spilleren.

Kasserne på scenen


Kasseproblemet:

Vi har løst kasseproblemet ved at sætte flere tjekpunkter ind. Som det var før blev der kun tjekket for overlapninger af andre kasser i øverste venstre hjørne. Dette har vi udvidet sådan at der bliver tjekket i alle hjørner, midten og midten af alle sider på kasserne. På denne måde tjekker den alle mulige scenarier for overlapning. De mulige scenarier på nær et ses på billedet nedenfor. Tjekpunktet i midten er i tilfælde af at en mindre kasse genereres oven i en større.

Dette fungerer kodemæssigt således, at hver ny kasses position tjekkes af Level-klassen. Hvis den nye kasse overlapper en anden, tjekkes et nyt tilfældigt sted der ingen overlapninger er. Efter et succesfuldt tjek oprettes kassen på scenen.

I teorien kan dette tjek gentage sig i en uendelighed, men sandsynligheden for dette problem er så lav at, det tæt på ingen risiko udgør.

mandag den 3. maj 2010

Afslutning af første iteration og planlægning for næste

Vi har i dag afsluttet første iteration uden dog helt at nå målet. Vi har ikke fundet en løsning på problemet med kasserne, der overlapper hinanden. Vi har imidlertid fået implementeret en spiller med fungerende styresystem via piltasterne. Vi har ligeledes lavet collision detection således at spilleren ikke kan gå igennem kasserne eller uden for banens sider.


Plan for næste iteration

Planen for næste iteration er at implementere en skydefunktion til vores player. Vi vil endvidere forsøge at få forskellige typer zombier ind på scenen, som ligeledes har collision detection i forhold til kasserne samt banens sider. Zombierne skal efterfølgende gerne kunne skydes til døde af spilleren.

Vi forestiller os at lave tre typer zombier, med varierende hastighed, hit points og farve.

Vi vil sideløbende med denne iteration forsøge at løse problemet med kasserne.

onsdag den 21. april 2010

SCRUM-meeting

SCRUM-meeting

Næste møde forventer vi at afslutte vores kasseproblem og revurdere vores klassediagram i forhold til vores fornyede kode.

Omstrukturering i koden

Vi har fundet ud af at vi for at løse problemet med kassernes overlapninger, vil gå fra tekstbaserede kasser til objektorienterede kasser. På denne måde kan vi bruge den funktion der hedder hitTestObject, og dermed forhåbentligt få en lettere tilgang til kasseproblemet.

Keep it real
Group 3

Godmode on (kodeproblemer og løsninger)

Vi har nu fået implementeret collision detection i spillet, og har derefter påtaget os rollen som brugere og testet det at spillet generer en masse baner(nye levels), altså level-designet.
Vi har hermed fundet ud af, at de tilfældigt generede kasser kan skabe gameplaymæssige problemer, idet playeren kan blive fanget imellem kasserne når der påbegyndes en ny level. Samtidigt bliver vores level-design ikke særlig spændende hvis de tilfældigt oprettede kasser oprettes oven i hinanden i en stor klump.

Pt. har vi kun halvdelen af løsningen klar. Dette indebærer at playeren spawner i det nederste venstre hjørne, og at kasserne generes minimum playerens diameter væk fra det nederste venstre hjørne. Det andet problem vedrørende kassernes klyngedannelser, har vi endnu ikke en løsning på rent kodemæssigt, men vi går efter at få spredt kasserne fra hinanden med en minimum afstand på playerens diameter fra hinanden, så playeren kan bevæg sig imellem alle kasserne. Midlertidigt ser vores kode til at løse det sådan her ud, den er dog ikke ikke tilfredstillende endnu:

c.beginFill(Math.random()*0xFFFFFF);
xLevelArray[0] = Math.random()*50+14
yLevelArray[0] = Math.random()*50+15
widthLevelArray[0] = Math.random()*70+30
heightLevelArray[0] = Math.random()*70+30
for (var i:int = 0; i < int =" 0;"> xLevelArray[l] && xLevelArray[i] <> yLevelArray[l] && yLevelArray[i] < yLevelArray[l]+heightLevelArray[l]){yLevelArray[i] = yLevelArray[l] + heightLevelArray[l] + 20}

}
c.drawRect(xLevelArray[i], yLevelArray[i], widthLevelArray[i], heightLevelArray[i])
}

Når man rammer et hjørne har tests endvidere vist, at kassen ikke helt ved hvor den skal sende playeren ud, og ender derfor med at lade playeren gå igennem kassen.

Let there be light(GUI)



GUI

Vi er nu i gang med kodningen og indtil videre har vi formået at skabe første udkast til vores level- og player-klasse.

I vores første iteration vil vi som sagt gerne have styr på vores player- og level-klasse. Vi vil gerne strukturere vores level-design, således at level spawner en player samtidigt med at den spawner banens fysiske objekter i form af kasser, genereret tilfældigt på banen. For at være tilfredse med vores første iteration, vil vi gerne have implementeret colission detection mellem player og kasserne, samt scenens rammer. Det kodemæssige perspektiv blev taget op til diskussion i gruppen. Det matematiske aspekt ved udregningen af colission detection viste sig at være en stor mundfuld. For at påbegynde udregningen tager vi udgangspunkt i scenen som et koordinatsystem, med en x og y akse. Kassens afgrænsning kan dermed beskrives som ses på figuren på billedet:


Hvis h og w er henholdsvis højden og bredden på en tilfældig kasse, kan hjørnerne koordinatsæt findes som vist på tegningen. Playerens midtpunkt har vi som Px, Py, og han har samtidigt radius 10 i koden som vi kalder Pr. Med disse informationer kan der opsættes if-sætninger der tjekker om spillerens koordinater kollidere med kassen koordinater. Og hvis dette er tilfældet bliver spilleren skubbet ud til kanten af kassen. Vi forestiller os ligeledes at kassen skal deles op i 4 for at spillet ved hvilken side spilleren skal rykkes ud til.

mandag den 19. april 2010

Klassediagram

Vi har påbegyndt vores første iteration som beskrevet under Genesis. Vi har efter overvejelser med kun en level- og en player-klasse fundet frem til, at det bedre kan betale sig at holde styresystemet i sin egen klasse, navnlig Controller jf. princippet om lav kobling. Dette kommer sig af inspiration fra et tidligere projekt, Astroids, hvor opbygningen er den samme. Det giver endvidere logisk mening at holde controller for sig selv, da dette giver lettere mulighed for at ændre de forskellige klasser uafhængigt af hinanden. Derudover er det lettere at implementere styresystemer i senere projekter, da vi på denne måde får en skabelon for dette.























I vores klassediagram har vi indsat en Level-klasse. Under level-klassen har vi indsat variablen +ZombieAmount:Number. Det er meningen et denne variabel skal bestemme hvor mange zombier der er i banen, og dermed ligeledes at der kommer flere zombier jo højere level spilleren er i. Ydermere er ideen at vores level-klasse skal genere tilfældige baner i spillet hver gang der skiftes level. Dette har vi implementeret i vores klassediagram under disse variabler:

public var xLevelArray:Array;
public var yLevelArray:Array;
public var widthLevelArray:Array;
public var heightLevelArray:Array

Ideen med dette er at vi vil oprette 4 arrays der hver især indeholder et parameter for drawrect funktionen. Level-klassen henter så nogle tilfældige værdier fra hvert array, og drawmap tegner så ti tilfældige kasser derudfra, som så udgør banen.

Anden klasse i vores klassediagram er vores Player-klasse, herunder har vi valgt at indsætte følgende variabler:

-xCoordinate:Number

-yCoordinate:Number

+LifeCount:Number
+Name:string
+PlayerDeath()

Og disse funktioner:
+Move()
+Shoot()

Vi forestiller os herudfra at playerklassen skal indeholde styrefunktioner, i forhold til at playeren skal kunne bevæge sig, samt skyde(+Move() og +Shoot()). Derudover indeholder playeren også en LifeCount funktion(+LifeCount:Number), som holder styr på hvor mange liv playeren har tilbage, hertil forestiller vi os også funktionen PlayerDeath( +PlayerDeath()) der skal sørge for at playeren dør når han ikke har flere liv tilbage. Name funktionen(+Name:string) tænker vi skal gøre det muligt at brugeren kan give sin player et navn.

Den sidste klasse i vores klassediagram er Controller-klassen, der består af disse variabler og funktioner:
-_forward:Boolean
-_back:Boolean
-_left:Boolean
-_right:Boolean

+keyReleased()
+keyPressed()
+enterFrame()

Denne klasse er bygget op ud fra det princip at der er nogle Booleans, som bliver sat til true når der trykkes på en knap og så længe denne knap holdes inde. enterFrame() tjekker hele tiden om der trykkes på noget. Dette administreres af funktionerne keyPressed() og keyReleased(), der sørger for de rigtige værdier på vores booleans og dermed sikrer den rigtige bevægelse.

Sammenhængen mellem klasserne er som angivet på klassediagrammet. Controller-klassen står for at fortælle Player-klassen hvilke x- og y-koordinater spilleren skal have i hvert frame.

Level sørger for at få Player ind på scenen.

torsdag den 15. april 2010

Domain model

Nedenfor ses vores domænemodel, der viser den forløbelige arkitektur af vores spil.
Vi har Player med et navn, hp og et x-antal liv. Han kan blive opgraderet via powerups.

Både powerups og player befinder sig i det pågældende level, som endvidere bestemmer antallet af zombier, samt det antal point, som gives pr. nedlagte fjende. Zombierne varierer i sværhedsgrad jf. deres hp og fart.

Vi har valgt at balancere sværhedsgraden vha. antallet af zombier pr. level istedet for sværere enkelte zombier.






Glossary:

NPC:
Non player character (computerstyret karakter). Disse kan besidde en vis form for kunstig intelligens, herunder evnen til at forfølge spilleren.

HP:
Engelsk forkortelse for hit points, som er en betegnelse for, hvor meget liv man har tilbage.

Zombie-shooter:
Betegnelsen for et skydespil, der går ud på at skyde zombier

Kollision:
- Eller kollision detection er et element i spillet, der forhindrer både spilleren og fjenderne i at gå igennem banens rammer og forhindringer.

Powerups:
En genstand spilleren kan samle op for derved at forbedre sine egenskaber.

mandag den 12. april 2010

Genesis

Efter at have diskuteret frem og tilbage om rammerne for vores spil, har vi valgt en zombie-shooter. Helten i spillet er udstyret med en skyder og skal bekæmpe horder bestående af 3 forskellige typer zombier, der varierer i sværhedsgrad i forhold til fart og hp.

Der er endvidere 3 forskellige powerups, hvor vi tænker henholdsvis momentær udødelighed, point og bedre våben.

Spillet indeholder levels, der slutter når alle zombierne er døde. Næste level starter derefter med flere zombier end den foregående.



I foreliggende use case ses det centrale element i spillet, tilintetgørelsen af en zombie. Brugeren trykker på en ikke defineret knap, der udløser et skud fra et ikke defineret våben. Hvis dette skud rammer zombien mister den x ud af y antal hit points og dør når y rammer 0, hvorefter spilleren bliver belønnet med point.

Vi forestiller os flere iterationer, som hver især implementerer enkelte nye elementer til spillet:
-scenen
-Spilleren med styresystem
-Kollision på spilleren således at han ikke kan gå uden for scenen eller gå igennem de kasser, der er på den
-Zombieimplementering
I første omgang skal vi bare kunne få en enkelt zombie ind på scenen og førsøge at få den til at forfølge spilleren. Herefter oprettes de andre zombier.
-Skydesystem
-Powerups

Hver iteration vil indholde tests og efterfølgende diskussion i forhold til eventuelle ændringer.

I første iteration, som vi afslutter d. 29. april, forsøger vi at få lavet spillets UI, samt en funktionel spiller, der kan styres rundt på scenen.

Opgavevalg

Vi har valgt at beskæftige os med opgave 1: Computerspil i vores eksamensprojekt.

Grunden til dette valg er, at denne opgave lægger mest op til en kreativ proces, idet opgavebeskrivelsen er mindre fastlåst end de to andre. Vi påbegynder nu inceptionsfacen... so stay tuned for more action! Keep it real!

Gruppen består af:
Anders Lassen
Matti Bugge
Klaus Wrensted Jensen
Martin Bach Kristensen