1 \documentclass[titlepage,
a4paper,
12pt
]{article
}
2 \usepackage[swedish
]{babel
}
3 \usepackage[utf8
]{inputenc}
13 % Include pdf with multiple pages ex \includepdf[pages=-, nup=2x2]{filename.pdf}
14 \usepackage[final
]{pdfpages
}
15 % Place figures where they should be
19 \definecolor{keywordcolor
}{rgb
}{0.5,
0,
0.75}
24 basicstyle=
\scriptsize\ttfamily,
25 stringstyle=
\color{blue
},
26 commentstyle=
\color{red
},
29 numberblanklines=true,
31 showstringspaces=false,
32 keywordstyle=
\color{keywordcolor
}
33 % identifierstyle=\color{identifiercolor}
38 \newfloat{kod
}{H
}{lop
}
39 \floatname{kod
}{Kodsnutt
}
43 \def\preTitle{Laboration
4}
44 \def\kurs{Applikationsprogrammering i Java, HT-
08}
46 \def\namn{Andreas Jakobsson
}
47 \def\mail{dit06ajs@cs.umu.se
}
48 \def\namnTva{Anton Johansson
}
49 \def\mailTva{dit06ajn@cs.umu.se
}
51 \def\pathtocode{$
\sim$dit06ajn/edu/apjava/lab4
}
53 \def\handledareEtt{Johan Eliasson, johane@cs.umu.se
}
54 \def\handledareTva{Tor Sterner-Johansson, tors@cs.umu.se
}
55 \def\handledareTre{Daniel Henriksson, danielh@cs.umu.se
}
56 \def\handledareFyra{Johan Granberg, johang@cs.umu.se
}
58 \def\inst{datavetenskap
}
59 \def\dokumentTyp{Laborationsrapport
}
65 \begin{tabular
}{@
{}p
{\textwidth}@
{}}
66 UMEÅ UNIVERSITET
\hfill \today \\
67 Institutionen för
\inst \\
74 \huge{\textbf{\kurs}} \\
84 \large{\textbf{Handledare
}}\\
85 \mbox{\large{\handledareTre}}
86 \mbox{\large{\handledareTva}}
87 \mbox{\large{\handledareEtt}}
88 \mbox{\large{\handledareFyra}}
96 % Dedication goes here
103 \lhead{\footnotesize{\namn,
\mail\\
\namnTva,
\mailTva}}
114 \fancyfoot[LE,RO
]{\thepage}
115 \pagenumbering{arabic
}
117 \section{Problemspecifikation
}\label{Problemspecifikation
}
118 % Beskriv med egna ord vad uppgiften gick ut på. Är det någonting som
119 % varit oklart och ni gjort egna tolkningar så beskriv dessa.
120 Uppgiften för denna laboration är att implementera spelet
121 \textit{Anti-Tower Defence
} i Java. Kortfattat går ett typiskt sådant
122 spel ut på släppa ut enheter med olika egenskaper på en bana på ett
123 sådant sätt att de överlever till ett mål på banan. När ett antal
124 enheter kommit i mål vinner man banan.
126 Kraven från specifikationen är uppdelade i tre nivåer där den första
127 nivån är grundnivån. Här ska spelet implementeras med en
128 uppdateringsfrekvens oberoende av datorns hastighet. Två stycken
129 enheter med olika egenskaper ska finnas. En bana innehåller zoner där
130 datorn kan placera ut torn och zoner där enheter kan röra sig. Vid
131 vinst eller förlust ska användaren ha möjlighet att spela igen eller
132 att avsluta applikationen. Alla renderingar ska ske med dubbelbuffring
133 för att undvika flimmer.
135 I nivå två tillkommer ytterligare krav utöver de i grundnivån. Flera
136 banor ska finnas och laddas från fil
\textit{''levels.xml''
}. Denna
137 fil ska valideras mot en egen specifierad standard. Varje bana ska ha
138 egna regler för hur många trupper i mål som krävs för att klara
139 banan. Banor ska kunna ha flera alternativa vägar till mål. Slutligen
140 ska highscores sparas och visas i applikationen med hjälp av servicen
143 I den sista nivån ska banan utökas med ''växlar'' där användaren kan
144 påverka vilket håll trupperna rör sig i svängar. Dessutom ska enheter
145 kunna påverkas av zoner de går över genom att zoner implementerar ett
146 gränssnitt med en metod med t.ex. namnet
\textit{landOn()
}. En
147 truppmedlem ska implementeras med egenskapen att den kan lägga ut
148 teleporterplattor som andra enheter sedan kan landa på och förflyttas
149 mellan. Till sist ska projektet finnas i JAR-filen
\textit{AnitTD.jar
}
150 och gå att köra genom kommandot:
152 \verb!> java -jar AntiTD.jar!
155 Problemspecifikation finns i original på sidan:\\
157 \verb!http://www.cs.umu.se/kurser/
5DV085/HT08/labbar/lab4.html/!
158 (kontrollerad
090112)
% DONE check
161 \subsection{Antaganden om problemspecifikationen
}
162 I samtliga nivåer nämns i originalspecifikationen hur menyradens
163 funktionalitet ska utvecklas. Specifika riktlinjer ges om hur
164 menyalternativ ska byta namn beroende på applikationens
165 tillstånd. Eftersom lösningen som presenteras i denna rapport hanterar
166 namnbyten för de menyalternativ som för författarna känns relevant,
167 görs antagandet att detta räcker för att visa att tekniken behärskas.
169 Vidare nämns ett gränssnitt som innehåller metod
\textit{landOn()
}. I
170 denna lösning antas denna metod få förändras enligt tycke, t.ex. genom
171 att låta metoden ta paramterar.
173 \section{Användarhandledning
}\label{Anvandarhandledning
}
174 % Förklara var programmet och källkoden ligger samt hur man kompilerar,
175 % startar och använder det. Förklara även översiktligt vad som händer
176 % när man använder de olika kommandona. Det räcker alltså inte att
177 % skriva "man skriver 'ant' för att kompilera", utan det måste även ingå
178 % en liten förklaring om vad som egentligen händer när man kör ant och
179 % varför det fungerar. Använd Internet eller litteratur för att själva
180 % ta reda på den information ni tycker känns relevant, dels för
181 % rapportens skull och dels för er egen. Kom ihåg att skriva tydliga
182 % (vetenskapliga) referenser!
183 Nedan följer en beskrivningar om hur spelet kompileras, startas och
186 \subsection{Att kompilera och starta spelet
}
188 Alla filer som behövs för att kompilera och köra detta spel ligger på
189 servrar som tillhandahålls av institutionen för datavetenskap i Umeå i katalogen:\\
192 Denna katalog innehåller i sin tur några kataloger:
194 \item Katalogen
\verb!src! innehåller källkoden.
195 \item Katalogen
\verb!test! innehåller testkod.
196 \item Katalogen
\verb!bin! innehåller vid kompilering alla .class
197 filer och andra filer, såsom bilder och ljud.
198 \item Katalogen
\verb!lib! innehåller olika bibliotek som behövs för
199 att köra och kompilera programmet. En sådan jar-fil är
200 \verb!jdom.jar!, som används för att spara och läsa XML-filer. Alla
201 andra filer rör sparande av poäng till en webbtjänst, det vill säga
202 jar-filer från webbtjänstbiblioteket
\textit{Apache
203 Axis2
}\footnote{http://ws.apache.org/axis2
}.
204 \item Katalogen
\verb!doc! innehåller Javadoc API-dokumentation.
207 Följande kommandon förutsätter att programmet
\textit{Apache
208 Ant
}\footnote{http://ant.apache.org/
} är installerat. Verktyget
209 \textit{Ant
} är ett byggverktyg som använder sig av specifikationen
210 lagrad i en XML-fil, oftast
\textit{build.xml
}, för att automatisera
211 alla nödvändiga operationen vid kompilering av ett projekt. Detta kan
212 innefatta all typ av filhantering, det vill säga kopiering,
213 borttagning och flyttning, men även själva kompileringen av
214 projektet. Verktyget kan ses som ett specialanpassat skript för att
215 kompilera hela projekt.
217 Programmet kompileras med kommandot:\\
219 \verb!salt:~/edu/apjava/lab4> ant!
222 Det som händer vid anrop av kommandot ovan är att
\textit{Ant
} läser
223 av filen
\textit{build.xml
} och letar efter standardkommandona att
224 köra. I det här fallet är det operationerna som är definierade i
225 XML-elementet
\verb!<target />! med attributet
226 \verb!name="compile"!. Oftast har taggarna i
\textit{build.xml
}
227 relativt självförklarande namn, de motsvarar i många fall direkta
228 kommandon som går att köra i en terminal. Nu ska programmet vara
229 kompilerat och ligga i katalogen
\verb!bin/main!.
231 \subsection{Att använda det grafiska gränssnittet
}
232 Ett spel startas automatiskt vid start men när som helst kan ett helt
233 nytt spel startas genom att i menyraden välja
\textit{AntiTD
} och
234 därefter
\textit{New Game
}. I menyn
\textit{AntiTD
} finns också andra
235 självförklarande funktioner som
\textit{Restart Level, Paus/Resume,
236 Mute/unMute
} och
\textit{Quit
}, se skärmdumpar från avsnitt
237 \ref{Testkorningar
}, sida
\pageref{Testkorningar
}. Till höger om
238 spelplanen tillhandahålls en kontrollpanel där enheter markeras genom
239 att klicka på dem i listan. Därefter, kontrollera att en lämplig
240 startruta är markerad. En markerad startruta visas genom att ett grönt
241 sträck ritas ut under startrutans bild. Tryck på knappen
242 \textit{Release Unit
} för att nu släppa ut enheten på
243 banan. Manipulera enhetens frammarsch på banan genom att snurra på
244 riktningspilarna i kurvor och korsningar. Detta görs genom att klicka
245 på pilarna och dessa snurrar då runt till nästa giltiga riktning.
247 \section{Systembeskrivning
}\label{Systembeskrivning
}
248 % Beskriv översiktligt hur programmet är uppbyggt och hur det löser
251 Följande avsnitt beskriver de olika delarna av programmet uppdelat
252 paketvis med beskrivningar över vad de olika klasserna har för
253 funktion. Även en kort beskrivning över resurserna programmet använder
254 när det gäller filer som inte är Java-kod.
258 \includegraphics[width=
110mm
]{images/Paintables.pdf
}
259 \caption{UML klassdiagram
}
260 \label{fig:image/Paintable
}
264 \subsection{Resurser
}
265 Resurser som används av programmet men som inte är Java-filer ligger i
266 katalogen
\verb!src/resources!. Nedan avsnitt beskriver de filer och
267 mappar som ligger i denna katalog.
269 \subsubsection{Filen levels.xml
}\label{sec:levels.xml
}
270 Filen
\textit{levels.xml
} innehåller standarduppsättningen av banor
271 spelet använder. Filen följer schemat
\textit{levels.xsd
} och kan
272 exempelvis vara utformad enligt kodsnutt
\ref{kod:levels.xml
}.
277 <level name="MegaMap" unitsToWin="
5">
279 <tower type="BasicTower" />
280 <tower type="BasicTower" />
283 <square type="BlockedSquare" />
284 <square type="StartSquare direction="RIGHT" />
285 <square type="PathSquare" />
286 <square type="BlockedSquare" />
289 <square type="BlockedSquare" />
290 <square type="BlockedSquare" />
291 <square type="GoalSquare" />
292 <square type="BlockedSquare" />
297 \caption{Exempel XML
}\label{kod:levels.xml
}
300 \subsubsection{Filen levels.xsd
}\label{sec:levels.xsd
}
301 Filer
\textit{levels.xsd
} innehåller ett XML-Schema
302 \footnote{http://www.w3.org/XML/Schema
} som definierar hur giltiga
303 XML-dokument till spelet ska vara utformade. Se kodsnutt
304 \ref{kod:levels.xml
} för exempel på ett giltigt dokument.
306 \subsubsection{Katalogen sounds
}\label{sec:sounds
}
307 Katalogen
\textit{sounds
} innehåller ljud som spelas upp i spelet.
309 \subsubsection{Katalogen map-images
}\label{sec:map-images
}
310 Katalogen
\textit{map-images
} innehåller bilder som används av klasser av
311 typen
\textit{MapSquare
} (se avsnitt
\ref{sec:MapSquare
}).
313 \subsubsection{Katalogen tower-images
}\label{sec:tower-images
}
314 Katalogen
\textit{tower-images
} innehåller bilder som används av klasser
315 av typen
\textit{Tower
} (se avsnitt
\ref{sec:Tower
}).
317 \subsubsection{Katalogen unit-images
}\label{sec:unit-images
}
318 Katalogen
\textit{unit-images
} innehåller bilder som används av
319 klasser av typen
\textit{Unit
} (se avsnitt
\ref{sec:Unit
}).
321 \subsection{Paketet se.umu.cs.dit06ajnajs
}
322 Paketet
\textit{se.umu.cs.dit06ajnajs
} är huvudpaket som används i
323 programmet. I detta paket ligger de klasser som startar och
324 kontrollerar körningen av hela programmet. Se diagram i figur
325 \ref{fig:dit06ajnajs-uml
} för en översiktlig beskrivning över hur
326 klasserna använder varandra.
330 \includegraphics[width=
110mm
]{images/mvc.pdf
}
332 \label{fig:dit06ajnajs-uml
}
336 \subsubsection{AntiTD
}\label{sec:AntiTD
}
337 Klassen
\textit{AntiTD
} används för att en användare ska kunna starta
338 programmet. Här kan ett argument skickas med vid start som ska hänvisa
339 till en XML-fil som innehåller information om banorna som ska spelas i
340 spelet. Om inget argument anges kommer en förinställd fil att
341 användas, se
\textit{levels.xml
} sida
342 \pageref{sec:levels.xml
}. XML-filerna ska följa schemat
343 \textit{levels.xsd
}, se sida
\pageref{sec:levels.xsd
}.
345 \subsubsection{ATDController
}\label{sec:ATDController
}
346 Klassen
\textit{ATDController
} är programmets huvudklass. Enligt
347 design-mönstret
\textit{Model-View-Controller
} motsvarar denna klass
348 \textit{Controllern
}, alltså den klass som kontrollerar hela
349 programmets exekvering. Från denna klass konstruktor skapas
350 motsvarande
\textit{Model
} och
\textit{View
}.
352 Det startas två viktiga trådar när denna klass skapas,
353 \textit{AnimationThread
} och
\textit{CreditThread
}, se
354 algoritmbeskrivning på sida
\pageref{sec:Algoritmbeskrivning
}.
356 \subsubsection{ATDModel
}\label{sec:ATDModel
}
357 Klassen
\textit{ATDModel
} hanterar informationen som behövs för varje
358 spel. Här finns en spelare (
\textit{Player
}), en lista med banor
359 (
\textit{Level
}), en lista med alla enheter (
\textit{Unit
})som är ute
360 på den aktiva banan, och så vidare. Denna information använder och
361 ändrar
\textit{ATDController
} och
\textit{ATDView
} läser
364 Denna klass agerar som ett mellansteg för informationen som finns
365 sparade i många av de klasser som finns i de paketen
366 \textit{se.umu.cs.dit06ajnajs.agent
} och
367 \textit{se.umu.cs.dit06ajnajs.level
}. Bland annat finns det metoder
368 för att lägga till torn och enheter i spelet.
370 \subsubsection{ATDView
}\label{sec:ATDView
}
371 Klassen
\textit{ATDView
} är spelets grafiska gränssnitt. Här ritas en
372 komponent ut som innehåller själva spelplanen och ett antal
373 komponenter för att styra spelets flöde finns. Metoder för att fästa
374 lyssnare på specifika komponenter finns för att
\textit{ATDController
}
375 ska kunna fästa lyssnare på dem.
377 Metoder för att rita om spelplanen finns tillgängliga för att
378 \textit{ATDController
} ska kunna uppdatera gränssnittet efter varje
379 uppdatering av speldatan.
381 \subsubsection{Paintable
}\label{sec:Paintable
}
382 Gränssnittet
\textit{Paintable
} ska implementeras av allt som ska
383 kunna ritas upp på spelplanen. Detta görs då med metoden
384 \textit{paint(Graphics g)
}.
386 \subsubsection{Clickable
}\label{sec:Clickable
}
387 Gränssnittet
\textit{Clickable
}, är ett gränssnitt med metod
388 \textit{click()
}. Instanser av
\textit{Clickable
} reagerar på
389 metodanropet på olika sätt beroende på implementation.
391 \subsubsection{Player
}\label{sec:Player
}
392 Klassen
\textit{Player
} representerar en spelare av spelate. Här
393 sparas poäng, krediter och vilken nivån användaren spelar.
395 \subsection{Paketet se.umu.cs.dit06ajnajs.agent
}
396 Klasserna i paket
\textit{dit06ajnajs.agent
} representerar agenter i
397 spelet som ska kunna agera på kartan. Se klassdiagrammet i figur
398 \ref{fig:agent-uml
} för en överblick hur de olika agentera beror av
403 \includegraphics[width=
110mm
]{images/agent.pdf
}
405 \label{fig:agent-uml
}
409 \subsubsection{Agent
}\label{sec:Agent
}
410 Gränssnittet
\textit{Agent
}, implementeras av alla klasser som ska
411 agera under spelets gång, detta gäller för närvarande instanser av
412 underklasser till
\textit{Unit
} och
\textit{Tower
}. Gränssnittet
413 utökar gränssnitten
\textit{Paintable
},
\textit{Clickable
} och
414 \textit{Cloneable
}. Det vill säga varje agent i spelat ska kunna rita
415 ut sig själv, det ska gå att klicka på dem och det ska gå att klona
416 dem se avsnitt
\ref{sec:AgentPrototypeFactory
}.
418 \subsubsection{AgentPrototypeFactory
}\label{sec:AgentPrototypeFactory
}
419 Klassen
\textit{AgentPrototypeFactory
} används för att skapa instanser
420 av underklasser till de abstrakta klasserna
\textit{Tower
} och
421 \textit{Unit
}. Klassen är implementerad enligt designmönstret
422 \textit{Singleton
}, det vill säga det får enbart finnas en instans av
423 denna klass under programmets körning. För att få tag på denna instans
424 används den statiska metoden
\textit{getInstance()
}.
426 I konstruktorn instansieras och sätts variabler som definierar de
427 olika enheterna, se beskrivning av
\textit{Unit
}, sida
428 \pageref{sec:Unit
}, och
\textit{Tower
}, sida
\pageref{sec:Tower
}, för
429 vilka variabler som finns och vad de gör. Detta innebär att det inte
430 behöver skapas en ny klass för varje ny typ av enhet eller torn som
431 ska skapas, det går dock alltid att skapa unika beteenden genom att
432 göra en ny klass som utökar klassen
\textit{Unit
} och överlagrar någon
433 av dess metoder, till exempel
\textit{act()
}.
435 En positiv effekt som fås genom kloning av enheter är att många av
436 dess resurser delas för varje enhet. Varje enhet som finns i spelet
437 har gemensamma referenser till bilder och ljud de ritar upp och
440 \subsubsection{Tower
}\label{sec:Tower
}
441 Den abstrakta klassen
\textit{Tower
} ska utökas av underklasser för
442 att skapa representationer av torn som ska kunna agera i ett spel. Ett
443 torn består av ett flertal attribut som kommer att definiera stora
444 delar av dess utseende och beteende.
446 Klassen implementerar gränssnitten
\textit{Agent
},
447 \textit{Observer
}. Torn observerar de rutor av typen
448 \textit{PathSquare
}, som är inom dess räckvid, för att få information
449 om det kommer enheter (av typen
\textit{Unit
}) att möjligtvis skjuta
450 på, se algoritmbeskrivning på sida
\pageref{sec:algo-tower
}.
452 Metoder med logik för att flytta enheten finns implementerade, bland
453 dessa är
\textit{act()
} och
\textit{collision()
} viktiga.
455 \subsubsection{BasicTower
}\label{sec:BasicTower
}
456 Klassen
\textit{BasicTower
} utökar den abstrakta klassen
457 \textit{Tower
} och representerar det enklast möjliga tornet som finns
458 implementerat i detta spel. Klassen innehåller inga egna
459 implementationer utan ärver metoderna i
\textit{Tower
} rakt av.
461 \subsubsection{Unit
}\label{sec:Unit
}
462 Den abstrakta klassen
\textit{Unit
} ska utökas av underklasser för att
463 skapa representationer av enheter som ska kunna agera i ett
464 spel. En enhet består av ett flertal attribut som kommer att definiera
465 stora delar av dess utseende och beteende. Exempelvis finns en tabell
466 som innehåller olika bilder för varje rikting enheter har, en annan
467 tabell innehåller ljud för olika tillfällen.
469 Viktiga attribut är x- och y-position på kartan, dessa används för att
470 enheten ska kunna rita ut sig själv på rätt plats. Vid förflyttning av
471 en enhet ändras x- y-position.
473 En centerpunkt räknas även ut för varje ändring av x- och
474 y-position. Denna punkt används bland annat för att räkna avstånd
475 mellan torn och enhet.
477 Varje enhet har även metoder för att returnera en rektangel som
478 definierar dess nuvarande och framtida yttre gränser på en bana. Denna
479 rektangel används vid kollisionsuträkning se algoritmbeskrivning på
480 sida
\pageref{sec:alog-kollision
}.
482 Metoder med logik för att flytta enheten finns implementerade, bland
483 dessa är
\textit{act()
} och
\textit{collision()
} viktiga.
484 % TODO algobeskrivning nånstans här?
486 \subsubsection{FootmanUnit
}\label{sec:FootmanUnit
}
487 Klassen
\textit{FootmanUnit
} utökar den abstrakta klassen
488 \textit{Unit
} och representerar den enklast möjliga enheten som finns
489 implementerat i detta spel. Klassen innehåller inga egna
490 implementationer utan ärver metoderna i
\textit{Unit
} rakt av.
492 \subsubsection{Direction
}\label{sec:Direction
}
493 Uppräkningen (''Enumeration'')
\textit{Direction
} innehåller olika
494 riktningar som är giltiga i spelet. Giltiga värden är
\textit{UP,
495 DOWN, LEFT, RIGHT, NONE
}. Riktningen
\textit{NONE
} finns med för att
496 hantera skapande av rutor i banredigeraren som ännu inte har någon
499 \subsection{Paketet se.umu.cs.dit06ajnajs.level
}
500 Paketet
\textit{level
} innehåller en samling klasser som har en
501 koppling till en bana i spelet. En bana är uppbyggd utav rutor av
502 olika karaktär. Se klassdiagram över de olika kartrutorna i figur
503 \ref{fig:kartrutor-uml
}.
507 \includegraphics[width=
110mm
]{images/level.pdf
}
508 \caption{Klassdiagram över kartrutor
}
509 \label{fig:kartrutor-uml
}
513 \subsubsection{Clickable
}\label{sec:Clickable
}
514 Gränssnittet
\textit{Clickable
}, är ett gränssnitt med metod
515 \textit{click()
}. Instanser av
\textit{Clickable
} reagerar på
516 metodanropet på olika sätt beroende på implementation.
518 \subsubsection{Traversable
}\label{sec:Traversable
}
519 Gränssnittet
\textit{Traversable
}, är ett gränssnitt med metod
520 \textit{landOn()
} vilket tar emot en
\textit{Unit
} som parameter och
521 manipulerar denna beroende av tillståndet av instansen av
522 \textit{Traversible
}.
524 \subsubsection{Level
}\label{sec:Level
}
525 Klassen
\textit{Level
}, motsvarar en bana tänkt att användas i ett
526 rutbaserat spel. Klassen implementerar gränsnitten
\textit{Paintable,
527 Cloneable, Clickable
}. Banan kan alltså bland annat representeras
528 grafiskt genom
\textit{Paintable
} och kan reagera på musklick genom
529 \textit{Clickable
}. Klassen innehåller en två-dimensionell lista
530 vilket innehåller instanser av typen
\textit{MapSquare
}. Listor finns
531 även med pekare till de rutor som representerar start- och målrutor.
533 \subsubsection{MapSquare
}\label{sec:MapSquare
}
534 Klassen
\textit{Level
}, är en abstrakt klass som motsvarar en ruta
535 tänkt att användas för att kombineras till en bana i ett rutbaserat
536 spel. Gränsnitten
\textit{Paintable, Cloneable, Clickable
}
537 implementeras. Rutan kan alltså bland annat representeras grafiskt
538 genom
\textit{Paintable
} och kan reagera på musklick genom
539 \textit{Clickable
}. Dessutom ärver klassen från
\textit{Observable
}
540 för att kunna registrera lyssnare som sedan notifieras när en enhet
541 går på rutan. Ett objekt av typen
\textit{MapSquare
} kan vara av typen
542 \textit{PathSquare, TurnSquare, BlockedSquare, TowerSquare,
543 BlockedSquare, StartSquare
} och
\textit{GoalSquare
}. Typernas
544 egenskaper beskrivs nedan.
546 \subsubsection{MapSquareFactory
}\label{sec:MapSquareFactory
}
547 Klassen
\textit{MapSquareFactory
}, används för att skapa nya instanser
548 av olika implementationer av
\textit{MapSquareFactory
} från en
549 sträng. Detta för att underlätta skapandet av nya sorters
550 rutor. Designmönstret
\textit{Singelton
} implementeras för att
551 säkerställa att en och endast en instans finns tillgänglig.
553 \subsubsection{PathSquare
}\label{sec:PathSquare
}
554 Klassen
\textit{PathSquare
}, representerar en vägruta och
555 implementerar därför gräns\-snittet
\textit{Traversible
}. Enheter kan
556 alltså befinna sig och färdas framåt på en ruta av denna typ. Klassen
557 implementerar designmönstret
\textit{Observer/Observable
} tillsammans
558 med klassen
\textit{Tower
} ur paketet
\textit{agent
}. När en enhet
559 anropar en rutas
\textit{landOn()
}-metod notifieras kringliggande torn
560 och pekaren till den anropande enheten skickas vidare till tornen (se
561 \pageref{sec:Tower
}).
563 \subsubsection{TurnSquare
}\label{sec:TurnSquare
}
564 Klassen
\textit{PathSquare
}, representerar en sväng och ärver från
565 \textit{PathSquare
}. Klassen innehåller en lista med giltiga
566 riktningar samt ett attribut för den nuvarande vald riktning. När en
567 enhet anropar metoden
\textit{landOn()
} som kontrollerar om enheten
568 har passerat mittlinjen av rutan relativt enhetens riktning. Om det är
569 sant tilldelas enheten rutans nuvarande valda riktning. Metoden
570 \textit{click()
} byter den nuvarande valda riktningen till nästa
571 giltiga riktning samt roterar bilden till den nya riktningen.
573 \subsubsection{BlockedSquare
}\label{sec:BlockedSquare
}
574 Klassen
\textit{PathSquare
}, representerar en blockerad ruta. I
575 nuvarande version innehåller klassen inga implementationer och
576 fungerar enbart som en utfyllnad.
578 \subsubsection{TowerSquare
}\label{sec:TowerSquare
}
579 Klassen
\textit{PathSquare
}, representerar en ruta där torn kan
580 placeras ut. Rutan kan innehålla en referens till ett torn och
581 markeras då som upptagen.
583 \subsubsection{StartSquare
}\label{sec:StartSquare
}
584 Klassen
\textit{PathSquare
}, representerar en startruta som enheter
585 kan släppas ut på. Den innehåller en kö där enheter lagras och släpper
586 ut en efter en då detta inte skapar kollisioner mellan enheter. En
587 startruta kan markeras med metoden
\textit{click()
} och detta sätter
588 boolean
\textit{active
} till sann och i den grafiska representationen
589 läggs en grön ram till runt rutan.
591 \subsubsection{GoalSquare
}\label{sec:GoalSquare
}
592 Klassen
\textit{PathSquare
}, representerar en målruta där enheter
593 samlas in
% TODO is something lost here?
595 \subsubsection{NoActiveStartSquareException
}\label{sec:NoActiveStartSquareException
}
596 Klassen
\textit{NoActiveStartSquareException
} är ett undantag som
597 utökar
\textit{RuntimeException
}. Detta undantag kan kastas om det
598 skulle vara så att ingen aktiv startruta är aktiv när en användare
599 försöker sätta ut en ny enhet.
601 \subsection{Paketet se.umu.cs.dit06ajnajs.util
}
602 Paketet
\textit{se.umu.cs.dit06ajnajs.util
} innerhåller främst klasser
603 för att hantera läsning och skrivning av XML, från och till filerna
604 där banor sparas. De flesta av dessa klasser är deklarerade som
605 \textit{final
} och innehåller enbart statiska metoder.
607 \subsubsection{SoundPlayer
}\label{sec:SoundPlayer
}
608 Klassen
\textit{SoundPlayer
} används för att spela upp allt ljud som
609 finns i spelet. En variabel håller reda på om ljuden ska spelas eller
610 inte, det vill säga om användaren vill höra ljud till spelet eller om
611 spelet ska vara helt tyst.
613 \subsubsection{LevelEditor
}\label{sec:LevelEditor
}
614 Klassen
\textit{LevelEditor
} är ett litet program i sig. Klassen har
615 en
\textit{main(String
[]~args)-metod
} vilket innebär att den kan
616 startas. Startas
\textit{LevelEditor
} kommer ett gränssnitt att visas
617 där användaren kan välja bland de olika typer av kartrutor (av typen
618 \textit{MapSquare
}) och sedan klicka på en component för att ''rita''
619 ut och skapa en ny bana. Det finns en knapp
\textit{Save map
} för att
620 spara kartan som är gjord. Denna karta sparas till katalogen
621 \textit{resources
} i root-katalogen från vilken programmet körs och
622 kommer att heta
\textit{temp-levels.xml
}. För att denna karta ska gå
623 att använda i spelet måste det läggas till information om vilken
624 riktning startrutor ska släppa ut nya enheter, hur många enheter som
625 behövs för vinst och vilka torn som ska finnas vid start.
627 Denna klass implementerades för att på ett snabbt och enkelt sätt
628 kunna skapa flera olika kartor till spelet.
630 \subsubsection{LevelsXMLOutputter
}\label{sec:LevelsXMLOutputter
}
631 Klassen
\textit{LevelsXMLOutputter
} är deklarerad som
\textit{final
}
632 och har en statisk metod för att skriva och konvertera en
633 \textit{Level
} (
\ref{sec:Level
}) till en
\textit{java.io.Writer
}. I
634 den nuvarande implementationen sparas inte all nödvändig information
635 undan, enbart informationen som
\textit{LevelEditorn
} kan skapa
638 \subsubsection{LevelsXMLParser
}\label{sec:LevelsXMLParser
}
639 Klassen
\textit{LevelsXMLParser
} har två metoder för att tolka
640 XML-dokument som följer XML-schemat i avsnitt
\ref{sec:levels.xsd
} och
641 bygga upp kompletta ban-instanser
\textit{Level
} (
\ref{sec:Level
}).
643 \subsubsection{XMLUtil
}\label{sec:XMLUtil
}
644 Klassen
\textit{XMLUtil
} har metoder för att ladda en fil, via
645 \textit{java.net.URL
} eller
\textit{java.io.File
}, och returnera ett
646 validerat dokument,
\textit{org.jdom.Document
}.
648 \subsection{Algoritmbeskrivning
}\label{sec:Algoritmbeskrivning
}
649 Följande avsnitt förklarar några av algoritmerna som finns
650 implementerade i spelet i mer detalj.
652 \subsubsection{Tråden AnimationThread
}
653 Tråden
\textit{AnimationThread
} är aktiv under hela applikationens
654 livstid. Följande steg genomförs för varje iteration.
657 \item Starta tidtagning.
658 \item Är spelet pausat?
660 \item Om ja, gå till en inre oändlig loop som fortsätter snurra
661 tills dess att spelet går ur pausläget.
662 \item Om nej, gå till nästa steg.
664 \item För varje enhet på bana, kontrollera kollisioner och säg till
665 enhet att agera (se algoritmbeskrivning
\textit{Kollisionshantering
}
666 samt algoritmbeskrivning
\textit{Enheternas act()
}).
667 \item Samla upp döda enheter och meddela
\textit{ATDController
} att
668 dessa ska tas bort från modellen.
669 \item För varje torn på banan, säg till torn att agera (se
670 algoritmbeskrivning
\textit{Tornens act()
}).
671 \item För varje målruta, samla in enheter och räkna mängden tjänade
673 \item Är spelet redan vunnit?
675 \item Om ja, gör inget av krediterna och gå vidare.
676 \item Om nej, tilldela spelaren (
\textit{Player
}) krediterna och
679 \item För varje startruta, släpp ut enheter från kö om utsläppet
680 inte innebär en kollision
681 \item För varje
\textit{Agent
}, anropa dess metod
\textit{Paint()
}.
682 \item Uppdatera spelkomponenten i
\textit{ATDView
} (se
683 algoritmbeskrivning
\textit{Utritning av spelet
}).
684 \item Stoppa tidtagning och sov tråden den kvarvarande tiden av det
685 förinställda tidssteget för att sedan börja om från steg
1.
690 \subsubsection{Tråden CreditThread
}
691 Tråden
\textit{CreditThread
} är aktiv under hela applikationens
692 livstid. Följande steg genomförs för varje iteration.
695 \item Är spelet pausat?
697 \item Om ja, gå till en inre oändlig loop som fortsätter snurra
698 tills dess att spelet går ur pausläget.
699 \item Om nej, gå till nästa steg.
701 \item Beräkna antalet tjänade krediter genom att kontrollera hur
702 många enheter som finns ute på spelplanen. Lägg dessa till spelaren
704 \item Är målet för banan uppnått?
706 \item Om ja, sluta räkna poäng och meddela
707 \textit{ATDController
} att banan är avklarad.
708 \item Om nej, gå till nästa steg.
710 \item Är banan förlorad?
712 \item Om ja, meddela
\textit{ATDControllern
} att banan är
714 \item Om nej, gå till nästa steg.
716 \item Sov ett förinställt intervall och börja sedan om.
719 \subsubsection{Kollisionshantering
}\label{sec:alog-kollision
}
720 För att inte enheter ska gå över varandra är kollisionshantering
721 implementerat. Innan varje enhet rör sig kollas enhetens framtida
722 position med alla andra enheters nuvarande position för att se om det
723 kommer att bli någon kollision.
725 Om det inträffar en kollision och enheterna har motsatt riktning, det
726 vill säga ena enheten rör sig med riktning
\textit{UP
} och andra
727 \textit{DOWN
} eller
\textit{LEFT
} mot
\textit{RIGHT
}, sätts båda
728 enheternas riktning till den motsatta de för närvarande färdas i och
729 första enheten flyttar sig. Om det inträffa kollision där enheterna
730 inte har motsatt riktning får enheten som kollen gjordes för inte
731 förflytta sig denna omgång.
733 % TODO ALgoritm besk vis
734 \subsubsection{Krediträkning
}
735 I nuläget beräknas spelarens intjänade krediter på ett mycket enkelt
736 sätt och kan ses som en tillfällig implementation. För varje iteration
737 i tråden
\textit{CreditThread
} baseras den intjänade krediten av
738 antalet enheter på kartan multiplicerat med
10. För varje iteration i
739 tråden
\textit{AnimationThread
} samlas enheter in från målrutor och
740 totala antalet multipliceras med
100.
742 \subsubsection{Tornens act()
}\label{sec:algo-tower
}
744 \subsubsection{Enheternas act()
}
746 \subsubsection{Svängar
}
748 \subsubsection{Utritning av spelet
}
749 Spelplanen ritas ut på en komponent i
\textit{ATDView
}. Denna
750 komponent är en inre klass som utökar Javas
\textit{JComponent
} och är
751 döpt till
\textit{GameComponent
}. När denna komponent skapas hämtas en
752 bild från
\textit{ATDModel
} och sparas undan i ett attribut.
754 Metoden
\textit{paintComponent(Graphics g)
} överlagras för att rita ut
755 spelet i gräns\-snittet. Vid varje uppdatering av spelplanen körs denna
756 metod enligt kodsnutt
\ref{kod:paintComponent
}.
761 public void paintComponent(Graphics g)
{
762 logger.fine("paintComponent: " + Thread.currentThread().toString());
764 // Draw backgroundImage
765 g.drawImage(backgroundImage,
0,
0, null);
767 // Draw gameImage which should contain updated information from
769 g.drawImage(gameImage,
0,
0, null);
771 // Clear gameImage image with a big transparent rectangle.
772 Color transparent = new Color(
0,
0,
0,
0);
773 gameGraphics.setColor(transparent);
774 gameGraphics.setComposite(AlphaComposite.Src);
775 gameGraphics.fill(new Rectangle2D.Double(
0,
0, width, height));
779 \caption{Metoden paintComponent(Graphics g)
}\label{kod:paintComponent
}
782 För att få en uppdaterad bild där alla enheter ritar ut sig själv
783 sparas tillhörande
\textit{Graphics
}-objekt som ett attribut i
784 \textit{ATDView
} som sedan kan hämtas av animationstråden för att låta
785 varje aktuell instans av
\textit{Paintable
} (se avsnitt
786 \ref{sec:Paintable
} på sida
\pageref{sec:Paintable
}) rita ut sig själv
787 på bilden, se kodsnutt
\ref{kod:paint
}. Nedersta raden,
788 \verb!view.repaintGame();!, ritar om hela spelkomponenten, se kodsnutt
789 \ref{kod:paintComponent
};
794 // Repaint all agents
795 Graphics g = view.getGameGraphics();
796 for (Unit unit : units)
{
799 for (Tower tower : towers)
{
803 // Refresh the game view
807 \caption{Utsnitt ur AnimationThread i ATDController
}\label{kod:paint
}
810 \section{Begränsningar
}\label{Begransningar
}
811 % Vilka problem och begränsningar har din lösning av uppgiften? Hur
812 % skulle de kunna rättas till?
814 % NOTE Antingen skriver vi bara om buggar här och låter icke-uppfyllda specpunkter ligga i diskussion eller så skiver vi båda och låter diskussion ta upp saker vi skulle vilja göra
816 \section{Reflektioner
}\label{Reflektioner
}
817 % Reflektioner - Var det något som var speciellt krångligt? Vilka
818 % problem uppstod och hur löste ni dem? Vilka verktyg använde ni? Hur
819 % upplevde ni de verktygen? + Allmänna synpunkter. Om ni har upplevt
820 % problem på grund av olika miljöer (i termer av operativsystem och
821 % liknande) så kan det även vara intressant att nämna det, samt motivera
824 \section{Testkörningar
}\label{Testkorningar
}
825 % Noggranna testkörningar där man ser att programmet fungerar som det
827 I denna sektion presenteras några skärmdumpar från körningar av applikationen.
831 \includegraphics[width=
110mm
]{images/ingame1.png
}
832 \caption{Skärmdump av applikationen
}
839 \includegraphics[width=
110mm
]{images/ingame2.png
}
840 \caption{Skärmdump av applikationen
}
845 Figur
\ref{fig:ingame1
} och figur
\ref{fig:ingame2
} visar hela
846 applikationen under ett pågående spel.
850 \includegraphics[width=
110mm
]{images/promptWinIngame.png
}
851 \caption{Skärmdump av dialogruta ''Level completed''
}
858 \includegraphics[width=
110mm
]{images/promptLose.png
}
859 \caption{Skärmdump av dialogruta ''Level lost''
}
864 Efter att användaren vunnit eller förlorat en bana låses
865 användargränssnittet och användaren får upp alternativ för fortsatt
866 spel i dialogrutor så som figur
\ref{fig:win
} och figur
867 \ref{fig:lose
} visar. Enheter som fortfarande är ute på banan
868 fortsätter att gå runt och kan dö eller gå i mål. Dock slutar
873 \includegraphics[width=
110mm
]{images/promptHighscore.png
}
874 \caption{Skärmdump av dialogruta ''Input highscore''
}
875 \label{fig:highscore
}
879 När inga fler banor finns att spela får användaren möjlighet att
880 skicka in sin ihoptjänade poäng till en highscore lista. Denna
881 funktionalitet drivs av en webservice som ingick i den laboration som
882 gjordes innan denna laboration.
886 \includegraphics[width=
110mm
]{images/menu_AntiTD.png
}
887 \caption{Skärmdump av meny ''AntiTD''
}
888 \label{fig:menu_antitd
}
894 \includegraphics[width=
110mm
]{images/menu_Help.png
}
895 \caption{Skärmdump av meny ''Help''
}
896 \label{fig:menu_help
}
900 Figur
\ref{fig:menu_antitd
} och figur
\ref{fig:menu_help
} visar de
901 alternativ som döljer sig i menyraden. I figur
\ref{fig:menu_antitd
}
902 syns det tredje alternativet
\textit{Resume
} vilket vid start heter
903 \textit{Paus
} men är nu i ett annat tillstånd eftersom applikationen
904 vid detta tillfälle var pausat. Detsamma gäller för fjärde
905 alternativet
\textit{unMute
} vilket börjar som
\textit{Mute
}. Figur
906 \ref{fig:menu_help
} visar menyalternativen
\textit{Help
} och
907 \textit{About
}. Dessa innehåller en kort beskrivning av spelets regler
908 och mål respektive en kort beskrivning om vilka som skapat
913 \includegraphics[width=
110mm
]{images/leveleditor1.png
}
914 \caption{Skärmdump ''LevelEditor'', applikationen har just startat
}
921 \includegraphics[width=
110mm
]{images/leveleditor2.png
}
922 \caption{Skärmdump ''LevelEditor'', ''MapSquares'' av typen ''BlockedSquare''
}
929 \includegraphics[width=
110mm
]{images/leveleditor3.png
}
930 \caption{Skärmdump ''LevelEditor'', ''Mapsquares'' av typen ''PathSquare'', ''StartSquare'' och ''GoalSquare''
}
937 \includegraphics[width=
110mm
]{images/leveleditor4.png
}
938 \caption{Skärmdump ''LevelEditor'', ''Mapsquares'' av typen ''TurnSquare''
}
943 I figur
\ref{fig:editor1
} till figur
\ref{fig:editor4
} visas
944 skärmdumpar av testapplikationen för att skapa banor. En hel bana har
945 skapats genom att klicka ut rutor av olika typ.
947 \section{Diskussion
}\label{Diskussion
}
948 % Diskutera om laborationen samt allmänt kring Web services och om hur
949 % och när det är användbart (och inte användbart). Saker som kan vara
950 % trevliga att ta upp är interoperabilitet, lite om prestanda, koncepten
951 % lös koppling och så vidare. Den här sektionen ska vara en betydande
952 % del av rapporten. Det är upp till er själva att ta reda på den
953 % information ni behöver, även om föreläsningsmaterialet kan vara
954 % väldigt användbart. Kom även här ihåg att referera till era källor
955 % (även om det är från föreläsningsmaterialet).
956 Projektet är implementerat enligt design-mönstret
957 \textit{Model-View-Controller
}. Resultatet diskuteras under rubriken
958 \textit{Model-View-Controller
}. I detta stadie finns en bra grund för
959 att lägga till funktionalitet så som nya enheter och nya banrutor med
960 speciella egenskaper samt att utveckla användargränssnittet. I
961 nedanstående avsnitt
\textit{Vidareutveckling
} diskuteras olika
962 möjligheter till vidareutveckling av spelet.
964 \subsection{Model-View-Controller
}
965 % TODO Fill this section
966 Detta projekt har från inledning
968 \subsection{Vidareutveckling
}
969 Nedan följer förslag på förändringar för att vidareutveckla spelet.
971 \subsubsection{Klass Item
}
972 I inledningar av projektet planerades en abstrakt klass
\textit{Item
}
973 som skulle representera en pryl vilken skulle kunna lagras i ett
974 attribut i en MapSquare. Objekt av typen
\textit{Item
} skulle
975 t.ex. kunna vara
\textit{HealtItem, SpeedItem, CreditItem
} som kan
976 representera prylar som ger mer hälsa, ökad fart respektive ett antal
977 crediter att handla med. Dessa prylar skulle användas genom att
978 slumpmässigt läggas till i objekt av typen
\textit{PathSquare
} och
979 alltså representeras grafiskt genom att rutan ritar ut prylen ovanpå
980 sig. En ruta med en pryl på skulle sedan skicka vidare en inkommande
981 enhets referens till prylen som i sin tur skulle manipulera enhetens
982 attribut. En pryl med teleporterbeteende diskuteras under rubrik
983 \textit{Unit av typen TeleportUnit
} (se
\pageref{TeleportUnit
}).
985 \subsubsection{Unit av typen TeleportUnit
}\label{TeleportUnit
}
986 För att uppfylla nivå tre av denna laborations kravspecifikation krävs
987 en enhet med möjlighet att placera ut så kallade
988 teleport-plattor. Detta kan uppnås i detta projekt genom att skapa
989 subklasser av
\textit{Item
} kallad t.ex.
\textit{TeleportStartItem
}
990 och
\textit{TeleportEndItem
}. Prylen
\textit{TeleportStartItem
} skulle
991 kunna bäras av en
\textit{Unit
} av typen
\textit{TeleporterUnit
} och
992 kunna läggas ut på nuvarande ruta genom t.ex. musklick på
993 enheten. Attribut som behövs i
\textit{TeleportStartItem
} är x- och
994 y-koordinater till den tillhörande prylen
\textit{TeleportEndItem
}
995 vilket i sin tur innehåller attribut för aktuell riktning som
996 utsläppta enheter ska ha samt en kö där uppsamlade enheter läggs till
997 för att sedan släppas ut en efter en då positionen är ledig. Algoritm
998 för kollisionsdetektering skulle fungera på samma sätt som algoritmen
999 som används när enheter släpps ut ur startrutor (se
1000 \pageref{sec:StartSquare
});
1002 \subsubsection{Gränssnitt
}
1003 I nuläget startas första banan direkt när applikationen startar. Att
1004 få se en så kallad splash-screen (introduktionsbild) kan vara önskvärt
1005 och åtgärdas enkelt genom att i konstruktor för
\textit{ATDController
}
1006 lägga till ett metodanrop till metod i
\textit{ATDView
} som visar
1007 något och väntar på att användaren ska välja ett nytt spel.
1009 I kontrollpanelen finns stora möjligheter till vidareutveckling då den
1010 nuvarande just täcker den funktionalitet som behövs för att köra
1011 spelet. Till en början skulle listan med tillgängliga units kunna
1012 bytas ut mot ikoner som visar enhetens grafiska representation. För
1013 att lättare kunna få en översikt över en enhets egenskaper skulle
1014 hälsa och hastighet kunna förmedlas med staplar istället för med
1015 text. Om listan byts mot ikoner finns även möjligheten att ta bort
1016 knappen
\textit{Release Units
} och låta användaren skicka ut önskad
1017 enhet genom att direkt klicka på enhetens ikon.
1019 \subsubsection{Observer–Obervable
}
1020 Eftersom Javas
\textit{Observalbe
} är en klass som måste utökas för
1021 att användas kan inte
\textit{MapSquares
} klonas utan att alla får en
1022 gemensam lista med
\textit{Observers
}. En egen implementation av
1023 \textit{Observer–Observalbe
} skulle behövas för att kunna klona
1024 kartrutor på ett användbart sätt. Med en sådan implementation hade det
1025 varit lättare i ett senare skede läsa in alla konfigurationsdetaljer
1026 för att skapa både kartrutor och enheter utifrån XML-dokument.
1028 \subsubsection{LevelEditor
}
1029 Klassen
\textit{LevelEditor
} hade behövt vidareutvecklas för att kunna
1030 användas för att skapa kompletta banor och redigera tillgängliga
1031 banor. Några punkter som hade behövts:
1034 \item Möjlighet att sätta riktning på en
\textit{StartSquare
}
1035 \item Möjlighet att skapa flera banor och spara dem i en gemensam XML-fil.
1036 \item Möjlighet att välja bilder som ska användas för rutorna.
1037 \item Möjlighet att sätta antal enheter som krävs i mål för att vinna en bana.
1038 \item Möjlighet att sätta ut torn.
1041 \bibliographystyle{alpha
}
1042 \bibliography{books.bib
}
1046 \pagenumbering{roman
}
1047 \section{Källkod
}\label{sec:kallkod
}
1048 % Källkoden ska finnas tillgänglig i er hemkatalog
1049 % ~/edu/apjava/lab1/. Bifoga även utskriven källkod.
1050 Härefter följer utskrifter från källkoden och andra filer som hör till
1054 \subsection{AntiTD.java
}\label{AntiTD.java
}
1055 \lstinputlisting{../src/se/umu/cs/dit06ajnajs/AntiTD.java
}
1056 % \begin{footnotesize}
1057 % \verbatiminput{../src/se/umu/cs/dit06ajnajs/AntiTD.java}
1058 % \end{footnotesize}