1 \documentclass[titlepage,
a4paper,
12pt
]{article
}
2 \usepackage[swedish
]{babel
}
3 \usepackage[utf8
]{inputenc}
14 % Include pdf with multiple pages ex \includepdf[pages=-, nup=2x2]{filename.pdf}
15 \usepackage[final
]{pdfpages
}
16 % Place figures where they should be
20 \definecolor{keywordcolor
}{rgb
}{0.5,
0,
0.75}
25 basicstyle=
\scriptsize\ttfamily,
26 stringstyle=
\color{blue
},
27 commentstyle=
\color{red
},
30 numberblanklines=true,
32 showstringspaces=false,
33 keywordstyle=
\color{keywordcolor
}
34 % identifierstyle=\color{identifiercolor}
39 \newfloat{kod
}{H
}{lop
}
40 \floatname{kod
}{Kodsnutt
}
44 \def\preTitle{Laboration
4}
45 \def\kurs{Applikationsprogrammering i Java, HT-
08}
47 \def\namn{Andreas Jakobsson
}
48 \def\mail{dit06ajs@cs.umu.se
}
49 \def\namnTva{Anton Johansson
}
50 \def\mailTva{dit06ajn@cs.umu.se
}
52 \def\pathtocode{$
\sim$dit06ajn/edu/apjava/lab4
}
54 \def\handledareEtt{Johan Eliasson, johane@cs.umu.se
}
55 \def\handledareTva{Tor Sterner-Johansson, tors@cs.umu.se
}
56 \def\handledareTre{Daniel Henriksson, danielh@cs.umu.se
}
57 \def\handledareFyra{Johan Granberg, johang@cs.umu.se
}
59 \def\inst{datavetenskap
}
60 \def\dokumentTyp{Laborationsrapport
}
66 \begin{tabular
}{@
{}p
{\textwidth}@
{}}
67 UMEÅ UNIVERSITET
\hfill \today \\
68 Institutionen för
\inst \\
75 \huge{\textbf{\kurs}} \\
85 \large{\textbf{Handledare
}}\\
86 \mbox{\large{\handledareTre}}
87 \mbox{\large{\handledareTva}}
88 \mbox{\large{\handledareEtt}}
89 \mbox{\large{\handledareFyra}}
97 % Dedication goes here
104 \lhead{\footnotesize{\namn,
\mail\\
\namnTva,
\mailTva}}
115 \fancyfoot[LE,RO
]{\thepage}
116 \pagenumbering{arabic
}
118 \section{Problemspecifikation
}\label{Problemspecifikation
}
119 % Beskriv med egna ord vad uppgiften gick ut på. Är det någonting som
120 % varit oklart och ni gjort egna tolkningar så beskriv dessa.
121 Uppgiften för denna laboration är att implementera spelet
\textit{Anti-Tower Defence
} i Java. Kortfattat går ett typiskt sådant spel ut på släppa ut enheter med olika egenskaper på en bana på ett sådant sätt att de överlever till ett mål på banan. När ett antal enheter kommit i mål vinner man banan.
123 Kraven från specifikationen är uppdelade i tre nivåer där den första nivån är grundnivån. Här ska spelet implementeras med en uppdateringsfrekvens oberoende av datorns hastighet. Två stycken enheter med olika egenskaper ska finnas. En bana innehåller zoner där datorn kan placera ut torn och zoner där enheter kan röra sig. Vid vinst eller förlust ska användaren ha möjlighet att spela igen eller att avsluta applikationen. Alla renderingar ska ske med dubbelbuffring för att undvika flimmer.
125 I nivå två tillkommer ytterligare krav utöver de i grundnivån. Flera banor ska finnas och laddas från fil
\textit{''levels.xml''
}. Denna fil ska valideras mot en egen specifierad standard. Varje bana ska ha egna regler för hur många trupper i mål som krävs för att klara banan. Banor ska kunna ha flera alternativa vägar till mål. Slutligen ska highscores sparas och visas i applikationen med hjälp av servicen från laboration
3
127 I den sista nivån ska banan utökas med ''växlar'' där användaren kan påverka vilket håll trupperna rör sig i svängar. Dessutom ska enheter kunna påverkas av zoner de går över genom att zoner implementerar ett gränssnitt med en metod med t.ex. namnet
\textit{landOn()
}. En truppmedlem ska implementeras med egenskapen att den kan lägga ut teleporterplattor som andra enheter sedan kan landa på och förflyttas mellan. Till sist ska projektet finnas i JAR-filen
\textit{AnitTD.jar
} och gå att köra genom kommandot:
129 \verb!> java -jar AntiTD.jar!
132 Problemspecifikation finns i original på sidan:\\
134 \verb!http://www.cs.umu.se/kurser/
5DV085/HT08/labbar/lab4.html/! (kontrollerad
090112)
% DONE check
137 \subsection{Antaganden om problemspecifikationen
}
138 I samtliga nivåer nämns i originalspecifikationen hur menyradens funktionalitet ska utvecklas. Specifika riktlinjer ges om hur menyalternativ ska byta namn beroende på applikationens tillstånd. Eftersom lösningen som presenteras i denna rapport hanterar namnbyten för de menyalternativ som för författarna känns relevant, görs antagandet att detta räcker för att visa att tekniken behärskas.
140 Vidare nämns ett gränssnitt som innehåller metod
\textit{landOn()
}. I denna lösning antas denna metod få förändras enligt tycke, t.ex. genom att låta metoden ta paramterar.
142 \section{Användarhandledning
}\label{Anvandarhandledning
}
143 % Förklara var programmet och källkoden ligger samt hur man kompilerar,
144 % startar och använder det. Förklara även översiktligt vad som händer
145 % när man använder de olika kommandona. Det räcker alltså inte att
146 % skriva "man skriver 'ant' för att kompilera", utan det måste även ingå
147 % en liten förklaring om vad som egentligen händer när man kör ant och
148 % varför det fungerar. Använd Internet eller litteratur för att själva
149 % ta reda på den information ni tycker känns relevant, dels för
150 % rapportens skull och dels för er egen. Kom ihåg att skriva tydliga
151 % (vetenskapliga) referenser!
153 Programmet ligger i katalogen:\\
156 Källkoden ligger i underkatalogen
\verb!src!.
158 Följande kommandon förutsätter att programmet
\textit{Apache
159 Ant
}\footnote{http://ant.apache.org/
} är installerat. Verktyget
160 \textit{Ant
} är ett byggverktyg som använder sig av specifikationen
161 lagrad i en XML-fil, oftast
\textit{build.xml
}, för att automatisera alla
162 nödvändiga operationen vid kompilering av ett projekt. Detta kan
163 innefatta all typ av filhantering, det vill säga kopiering,
164 borttagning och flyttning, men även själva kompileringen av
165 projektet. Verktyget kan ses som ett specialanpassat skript för att
166 kompilera hela projekt.
168 Programmet kompileras med kommandot:\\
170 \verb!salt:~/edu/apjava/lab3> ant!
173 Det som händer vid anrop av kommandot ovan är att
\textit{Ant
} läser
174 av filen
\textit{build.xml
} och letar efter standardkommandona att
175 köra. I det här fallet är det operationerna som är definierade i
176 XML-elementet
\verb!<target />! med attributet
177 \verb!name="compile"!. Oftast har taggarna i
\textit{build.xml
}
178 relativt självförklarande namn, de motsvarar i många fall direkta
179 kommandon som går att köra i en terminal.
181 \subsection{Att använda det grafiska gränssnittet
}
182 Ett spel startas automatiskt vid start men när som helst kan ett helt nytt spel startas genom att i menyraden välja
\textit{AntiTD
} och därefter
\textit{New Game
}. I menyn
\textit{AntiTD
} finns också andra självförklarande funktioner som
\textit{Restart Level, Paus/Resume, Mute/unMute
} och
\textit{Quit
}, se skärmdumpar från avsnitt
\ref{Testkorningar
}, sida
\pageref{Testkorningar
}. Till höger om spelplanen tillhandahålls en kontrollpanel där enheter markeras genom att klicka på dem i listan. Därefter, kontrollera att en lämplig startruta är markerad. En markerad startruta visas genom att ett grönt sträck ritas ut under startrutans bild. Tryck på knappen
\textit{Release Unit
} för att nu släppa ut enheten på banan. Manipulera enhetens frammarsch på banan genom att snurra på riktningspilarna i kurvor och korsningar. Detta görs genom att klicka på pilarna och dessa snurrar då runt till nästa giltiga riktning.
184 \section{Systembeskrivning
}\label{Systembeskrivning
}
185 % Beskriv översiktligt hur programmet är uppbyggt och hur det löser
190 \includegraphics[width=
110mm
]{images/Paintables.pdf
}
191 \caption{UML klassdiagram
}
192 \label{fig:image/Paintable
}
196 \subsection{Resurser
}
197 Resurser som används av programmet men som inte är Java-filer ligger i
198 katalogen
\verb!src/resources!. Nedan avsnitt beskriver de filer och
199 mappar som ligger i denna katalog.
201 \subsubsection{Filen levels.xml
}\label{sec:levels.xml
}
202 Filen
\textit{levels.xml
} innehåller standarduppsättningen av banor
203 spelet använder. Filen följer schemat
\textit{levels.xsd
} och kan
204 exempelvis vara utformad enligt kodsnutt
\ref{kod:levels.xml
}.
209 <level name="MegaMap" unitsToWin="
5">
211 <tower type="BasicTower" />
212 <tower type="BasicTower" />
215 <square type="BlockedSquare" />
216 <square type="StartSquare direction="RIGHT" />
217 <square type="PathSquare" />
218 <square type="BlockedSquare" />
221 <square type="BlockedSquare" />
222 <square type="BlockedSquare" />
223 <square type="GoalSquare" />
224 <square type="BlockedSquare" />
229 \caption{Exempel XML
}\label{kod:levels.xml
}
232 \subsubsection{Filen levels.xsd
}\label{sec:levels.xsd
}
233 Filer
\textit{levels.xsd
} innehåller ett XML-Schema
234 \footnote{http://www.w3.org/XML/Schema
} som definierar hur giltiga
235 XML-dokument till spelet ska vara utformade. Se kodsnutt
236 \ref{kod:levels.xml
} för exempel på ett giltigt dokument.
238 \subsubsection{Katalogen sounds
}\label{sec:sounds
}
239 Katalogen
\textit{sounds
} innehåller ljud som spelas upp i spelet.
241 \subsubsection{Katalogen map-images
}\label{sec:map-images
}
242 Katalogen
\textit{map-images
} innehåller bilder som används av klasser av
243 typen
\textit{MapSquare
} (se avsnitt
\ref{sec:MapSquare
}).
245 \subsubsection{Katalogen tower-images
}\label{sec:tower-images
}
246 Katalogen
\textit{tower-images
} innehåller bilder som används av klasser
247 av typen
\textit{Tower
} (se avsnitt
\ref{sec:Tower
}).
249 \subsubsection{Katalogen unit-images
}\label{sec:unit-images
}
250 Katalogen
\textit{unit-images
} innehåller bilder som används av klasser av typen
\textit{Unit
} (se avsnitt
\ref{sec:Unit
}).
252 \subsection{Paketet se.umu.cs.dit06ajnajs
}
253 Paketet
\textit{se.umu.cs.dit06ajnajs
} är huvudpaket som används i
254 programmet. I detta paket ligger de klasser som startar och
255 kontrollerar körningen av hela programmet.
257 \subsubsection{AntiTD
}\label{sec:AntiTD
}
258 Klassen
\textit{AntiTD
} används för att en användare ska kunna starta
259 programmet. Här kan ett argument skickas med vid start som ska hänvisa
260 till en XML-fil som innehåller information om banorna som ska spelas i
261 spelet. Om inget argument anges kommer en förinställd fil att
262 användas, se
\textit{levels.xml
} sida
263 \pageref{sec:levels.xml
}. XML-filerna ska följa schemat
264 \textit{levels.xsd
}, se sida
\pageref{sec:levels.xsd
}.
266 \subsubsection{ATDController
}\label{sec:ATDController
}
267 Klassen
\textit{ATDController
} är programmets huvudklass. Enligt
268 design-mönstret
\textit{Model-View-Controller
} motsvarar denna klass
269 \textit{Controllern
}, alltså den klass som kontrollerar hela
270 programmets exekvering. Från denna klass konstruktor skapas
271 motsvarande
\textit{Model
} och
\textit{View
}.
273 Det startas två viktiga trådar när denna klass skapas,
274 \textit{AnimationThread
} och
\textit{CreditThread
}.
277 \subsubsection{ATDModel
}\label{sec:ATDModel
}
278 Klassen
\textit{ATDModel
} hanterar informationen som behövs för varje
279 spel. Här finns en spelare (
\textit{Player
}), en lista med banor
280 (
\textit{Level
}), en lista med alla enheter (
\textit{Unit
})som är ute
281 på den aktiva banan, och så vidare. Denna information använder och
282 ändrar
\textit{ATDController
} och
\textit{ATDView
} läser
285 \subsubsection{ATDView
}\label{sec:ATDView
}
286 Klassen
\textit{ATDView
} är spelets grafiska gränssnitt. Här ritas en
287 komponent ut som innehåller själva spelplanen och ett antal
288 komponenter för att styra spelets flöde finns. Metoder för att fästa
289 lyssnare på specifika komponenter finns för att
\textit{ATDController
}
290 ska kunna fästa lyssnare på dem.
292 \subsubsection{NoActiveStartSquareException
}\label{sec:NoActiveStartSquareException
}
293 \subsubsection{Paintable
}\label{sec:Paintable
}
294 \subsubsection{Player
}\label{sec:Player
}
296 \subsection{Paketet se.umu.cs.dit06ajnajs.agent
}
297 \subsubsection{Agent
}\label{sec:Agent
}
298 Gränssnittet
\textit{Agent
}, implementeras av alla klasser som ska
299 agera under spelets gång, detta gäller för närvarande instanser av
300 underklasser till
\textit{Unit
} och
\textit{Tower
}. Gränssnittet
301 utökar gränssnitten
\textit{Paintable
},
\textit{Clickable
} och
304 \subsubsection{AgentPrototypeFactory
}\label{sec:AgentPrototypeFactory
}
305 Klassen
\textit{AgentPrototypeFactory
} används för att skapa instanser
306 av underklasser till de abstrakta klasserna
\textit{Tower
} och
307 \textit{Unit
}. Klassen är implementerad enligt designmönstret
308 \textit{Singleton
}, det vill säga det får enbart finnas en instans av
309 denna klass under programmets körning. För att få tag på denna instans
310 används den statiska metoden
\textit{getInstance()
}.
312 I konstruktorn instansieras och sätts variabler som definierar de
313 olika enheterna, se beskrivning av
\textit{Unit
}, sida
314 \pageref{sec:Unit
}, och
\textit{Tower
}, sida
\pageref{sec:Tower
}, för
315 vilka variabler som finns och vad de gör. Detta innebär att det inte
316 behöver skapas en ny klass för varje ny typ av enhet eller torn som
317 ska skapas, det går dock alltid att skapa unika beteenden genom att
318 göra en ny klass som utökar klassen
\textit{Unit
} och överlagrar någon
319 av dess metoder, till exempel
\textit{act()
}.
321 En positiv effekt som fås genom kloning av enheter är att många av
322 dess resurser delas för varje enhet. Varje enhet som finns i spelet
323 har gemensamma referenser till bilder och ljud de ritar upp och
326 \subsubsection{Tower
}\label{sec:Tower
}
327 Den abstrakta klassen
\textit{Tower
} ska utökas av underklasser för
328 att skapa representationer av torn som ska kunna agera i ett spel. Ett
329 torn består av ett flertal attribut som kommer att definiera stora
330 delar av dess utseende och beteende.
332 Klassen implementerar gränssnitten
\textit{Agent
},
\textit{Observer
},
333 \textit{Cloneable
}. Torn observerar de rutor av typen
334 \textit{PathSquare
}, som är inom dess räckvid, för att få information
335 om det kommer enheter (av typen
\textit{Unit
}) att möjligtvis skjuta
336 på.
% TODO: Algobeskr
338 Metoder med logik för att flytta enheten finns implementerade, bland
339 dessa är
\textit{act()
} och
\textit{collision()
} viktiga.
341 \subsubsection{BasicTower
}\label{sec:BasicTower
}
342 Klassen
\textit{BasicTower
} utökar den abstrakta klassen
343 \textit{Tower
} och representerar det enklast möjliga tornet som finns
344 implementerat i detta spel. Klassen innehåller inga egna
345 implementationer utan ärver metoderna i
\textit{Tower
} rakt av.
347 \subsubsection{Unit
}\label{sec:Unit
}
348 Den abstrakta klassen
\textit{Unit
} ska utökas av underklasser för att
349 skapa representationer av enheter som ska kunna agera i ett
350 spel. En enhet består av ett flertal attribut som kommer att definiera
351 stora delar av dess utseende och beteende. Exempelvis finns en tabell
352 som innehåller olika bilder för varje rikting enheter har, en annan
353 tabell innehåller ljud för olika tillfällen.
355 Metoder med logik för att flytta enheten finns implementerade, bland
356 dessa är
\textit{act()
} och
\textit{collision()
} viktiga.
357 % TODO algobeskrivning nånstans här?
359 \subsubsection{FootmanUnit
}\label{sec:FootmanUnit
}
360 Klassen
\textit{FootmanUnit
} utökar den abstrakta klassen
361 \textit{Unit
} och representerar den enklast möjliga enheten som finns
362 implementerat i detta spel. Klassen innehåller inga egna
363 implementationer utan ärver metoderna i
\textit{Unit
} rakt av.
365 \subsubsection{Direction
}\label{sec:Direction
}
366 Uppräkningen (''Enumeration'')
\textit{Direction
} innehåller olika
367 riktningar som är giltiga i spelet. Giltiga värden är
\textit{UP,
368 DOWN, LEFT, RIGHT, NONE
}. Riktningen
\textit{NONE
} finns med för att
369 hantera skapande av rutor i banredigeraren som ännu inte har någon
372 \subsection{Paketet se.umu.cs.dit06ajnajs.level
}
373 Paketet
\textit{level
} innehåller en samling klasser som har en
374 koppling till en bana i spelet. En bana är uppbyggd utav rutor av
375 olika karaktär. Se klassdiagram över de olika kartrutorna i figur
376 \ref{fig:kartrutor-uml
}.
380 \includegraphics[width=
110mm
]{images/level.pdf
}
381 \caption{Klassdiagram över kartrutor
}
382 \label{fig:kartrutor-uml
}
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{Traversable
}\label{sec:Traversable
}
392 Gränssnittet
\textit{Traversable
}, är ett gränssnitt med metod
393 \textit{landOn()
} vilket tar emot en
\textit{Unit
} som parameter och
394 manipulerar denna beroende av tillståndet av instansen av
395 \textit{Traversible
}.
397 \subsubsection{Level
}\label{sec:Level
}
398 Klassen
\textit{Level
}, motsvarar en bana tänkt att användas i ett
399 rutbaserat spel. Klassen implementerar gränsnitten
\textit{Paintable,
400 Cloneable, Clickable
}. Banan kan alltså bland annat representeras
401 grafiskt genom
\textit{Paintable
} och kan reagera på musklick genom
402 \textit{Clickable
}. Klassen innehåller en två-dimensionell lista
403 vilket innehåller instanser av typen
\textit{MapSquare
}. Listor finns
404 även med pekare till de rutor som representerar start- och målrutor.
406 \subsubsection{MapSquare
}\label{sec:MapSquare
}
407 Klassen
\textit{Level
}, är en abstrakt klass som motsvarar en ruta
408 tänkt att användas för att kombineras till en bana i ett rutbaserat
409 spel. Gränsnitten
\textit{Paintable, Cloneable, Clickable
}
410 implementeras. Rutan kan alltså bland annat representeras grafiskt
411 genom
\textit{Paintable
} och kan reagera på musklick genom
412 \textit{Clickable
}. Dessutom ärver klassen från
\textit{Observable
}
413 för att kunna registrera lyssnare som sedan notifieras när en enhet
414 går på rutan. Ett objekt av typen
\textit{MapSquare
} kan vara av typen
415 \textit{PathSquare, TurnSquare, BlockedSquare, TowerSquare,
416 BlockedSquare, StartSquare
} och
\textit{GoalSquare
}. Typernas
417 egenskaper beskrivs nedan.
419 \subsubsection{MapSquareFactory
}\label{sec:MapSquareFactory
}
420 Klassen
\textit{MapSquareFactory
}, används för att skapa nya instanser
421 av olika implementationer av
\textit{MapSquareFactory
} från en
422 sträng. Detta för att underlätta skapandet av nya sorters
423 rutor. Designmönstret
\textit{Singelton
} implementeras för att
424 säkerställa att en och endast en instans finns tillgänglig.
426 \subsubsection{PathSquare
}\label{sec:PathSquare
}
427 Klassen
\textit{PathSquare
}, representerar en vägruta och
428 implementerar därför gräns\-snittet
\textit{Traversible
}. Enheter kan
429 alltså befinna sig och färdas framåt på en ruta av denna typ. Klassen
430 implementerar designmönstret
\textit{Observer/Observable
} tillsammans
431 med klassen
\textit{Tower
} ur paketet
\textit{agent
}. När en enhet
432 anropar en rutas
\textit{landOn()
}-metod notifieras kringliggande torn
433 och pekaren till den anropande enheten skickas vidare till tornen (se
434 \pageref{sec:Tower
}).
436 \subsubsection{TurnSquare
}\label{sec:TurnSquare
}
437 Klassen
\textit{PathSquare
}, representerar en sväng och ärver från
438 \textit{PathSquare
}. Klassen innehåller en lista med giltiga
439 riktningar samt ett attribut för den nuvarande vald riktning. När en
440 enhet anropar metoden
\textit{landOn()
} som kontrollerar om enheten
441 har passerat mittlinjen av rutan relativt enhetens riktning. Om det är
442 sant tilldelas enheten rutans nuvarande valda riktning. Metoden
443 \textit{click()
} byter den nuvarande valda riktningen till nästa
444 giltiga riktning samt roterar bilden till den nya riktningen.
446 \subsubsection{BlockedSquare
}\label{sec:BlockedSquare
}
447 Klassen
\textit{PathSquare
}, representerar en blockerad ruta. I
448 nuvarande version innehåller klassen inga implementationer och
449 fungerar enbart som en utfyllnad.
451 \subsubsection{TowerSquare
}\label{sec:TowerSquare
}
452 Klassen
\textit{PathSquare
}, representerar en ruta där torn kan
453 placeras ut. Rutan kan innehålla en referens till ett torn och
454 markeras då som upptagen.
456 \subsubsection{StartSquare
}\label{sec:StartSquare
}
457 Klassen
\textit{PathSquare
}, representerar en startruta som enheter
458 kan släppas ut på. Den innehåller en kö där enheter lagras och släpper
459 ut en efter en då detta inte skapar kollisioner mellan enheter. En
460 startruta kan markeras med metoden
\textit{click()
} och detta sätter
461 boolean
\textit{active
} till sann och i den grafiska representationen
462 läggs en grön ram till runt rutan.
464 \subsubsection{GoalSquare
}\label{sec:GoalSquare
}
465 Klassen
\textit{PathSquare
}, representerar en målruta där enheter
466 samlas in
% TODO is something lost here?
471 % \subsubsection{MapSquarePrototypeFactory}\label{sec:MapSquarePrototypeFactory}
473 \subsection{Paketet se.umu.cs.dit06ajnajs.util
}
474 Paketet
\textit{se.umu.cs.dit06ajnajs.util
} innerhåller främst klasser
475 för att hantera läsning och skrivning av XML, från och till filerna
476 där banor sparas. De flesta av dessa klasser är deklarerade som
477 \textit{final
} och innehåller enbart statiska metoder.
479 \subsubsection{SoundPlayer
}\label{sec:SoundPlayer
}
480 Klassen
\textit{SoundPlayer
} används för att spela upp allt ljud som
481 finns i spelet. En variabel håller reda på om ljuden ska spelas eller
482 inte, det vill säga om användaren vill höra ljud till spelet eller om
483 spelet ska vara helt tyst.
485 \subsubsection{LevelEditor
}\label{sec:LevelEditor
}
486 Klassen
\textit{LevelEditor
} är ett litet program i sig. Klassen har
487 en
\textit{main(String
[]~args)-metod
} vilket innebär att den kan
488 startas. Startas
\textit{LevelEditor
} kommer ett gränssnitt att visas
489 där användaren kan välja bland de olika typer av kartrutor (av typen
490 \textit{MapSquare
}) och sedan klicka på en component för att ''rita''
491 ut och skapa en ny bana. Det finns en knapp
\textit{Save map
} för att
492 spara kartan som är gjord. Denna karta sparas till katalogen
493 \textit{resources
} i root-katalogen från vilken programmet körs och
494 kommer att heta
\textit{temp-levels.xml
}. För att denna karta ska gå
495 att använda i spelet måste det läggas till information om vilken
496 riktning startrutor ska släppa ut nya enheter, hur många enheter som
497 behövs för vinst och vilka torn som ska finnas vid start.
499 \subsubsection{LevelsXMLOutputter
}\label{sec:LevelsXMLOutputter
}
500 Klassen
\textit{LevelsXMLOutputter
} är deklarerad som
\textit{final
}
501 och har en statisk metod för att skriva och konvertera en
502 \textit{Level
} (
\ref{sec:Level
}) till en
\textit{java.io.Writer
}. I
503 den nuvarande implementationen sparas inte all nödvändig information
504 undan, enbart informationen som
\textit{LevelEditorn
} kan skapa
507 \subsubsection{LevelsXMLParser
}\label{sec:LevelsXMLParser
}
508 Klassen
\textit{LevelsXMLParser
} har två metoder för att tolka
509 XML-dokument som följer XML-schemat i avsnitt
\ref{sec:levels.xsd
} och
510 bygga upp kompletta ban-instanser
\textit{Level
} (
\ref{sec:Level
}).
512 \subsubsection{XMLUtil
}\label{sec:XMLUtil
}
513 Klassen
\textit{XMLUtil
} har metoder för att ladda en fil, via
514 \textit{java.net.URL
} eller
\textit{java.io.File
}, och returnera ett
515 validerat dokument,
\textit{org.jdom.Document
}.
517 \subsection{Algoritmbeskrivning
}
518 Följande avsnitt förklarar några av algoritmerna som finns
519 implementerade i spelet i mer detalj.
521 \subsubsection{Tråden AnimationThread
}
522 Tråden
\textit{AnimationThread
} är aktiv under hela applikationens livstid. Följande steg genomförs för varje iteration.
525 \item Starta tidtagning.
526 \item Är spelet pausat?
528 \item Om ja, gå till en inre oändlig loop som fortsätter snurra tills dess att spelet går ur pausläget.
529 \item Om nej, gå till nästa steg.
531 \item För varje enhet på bana, kontrollera kollisioner och säg till enhet att agera (se algoritmbeskrivning
\textit{Kollisionshantering
} samt algoritmbeskrivning
\textit{Enheternas act()
}).
532 \item Samla upp döda enheter och meddela
\textit{ATDController
} att dessa ska tas bort från modellen.
533 \item För varje torn på banan, säg till torn att agera (se algoritmbeskrivning
\textit{Tornens act()
}).
534 \item För varje målruta, samla in enheter och räkna mängden tjänade krediter.
535 \item Är spelet redan vunnit?
537 \item Om ja, gör inget av krediterna och gå vidare.
538 \item Om nej, tilldela spelaren (
\textit{Player
}) krediterna och gå vidare.
540 \item För varje startruta, släpp ut enheter från kö om utsläppet inte innebär en kollision
541 \item För varje
\textit{Agent
}, anropa dess metod
\textit{Paint()
}.
542 \item Uppdatera spelkomponenten i
\textit{ATDView
} (se algoritmbeskrivning
\textit{Utritning av spelet
}).
543 \item Stoppa tidtagning och sov tråden den kvarvarande tiden av det förinställda tidssteget för att sedan börja om från steg
1.
548 \subsubsection{Tråden CreditThread
}
549 Tråden
\textit{CreditThread
} är aktiv under hela applikationens livstid. Följande steg genomförs för varje iteration.
552 \item Är spelet pausat?
554 \item Om ja, gå till en inre oändlig loop som fortsätter snurra tills dess att spelet går ur pausläget.
555 \item Om nej, gå till nästa steg.
557 \item Beräkna antalet tjänade krediter genom att kontrollera hur många enheter som finns ute på spelplanen. Lägg dessa till spelaren (
\textit{Player
}).
558 \item Är målet för banan uppnått?
560 \item Om ja, sluta räkna poäng och meddela
\textit{ATDController
} att banan är avklarad.
561 \item Om nej, gå till nästa steg.
563 \item Är banan förlorad?
565 \item Om ja, meddela
\textit{ATDControllern
} att banan är avklarad.
566 \item Om nej, gå till nästa steg.
568 \item Sov ett förinställt intervall och börja sedan om.
571 \subsubsection{Kollisionshantering
}
572 För att inte enheter ska gå över varandra är kollisionshantering
573 implementerat. Innan varje enhet rör sig kollas enhetens framtida
574 position med alla andra enheters nuvarande position för att se om det
575 kommer att bli någon kollision.
577 Om det inträffar en kollision och enheterna har motsatt riktning, det
578 vill säga ena enheten rör sig med riktning
\textit{UP
} och andra
579 \textit{DOWN
} eller
\textit{LEFT
} mot
\textit{RIGHT
}, sätts båda
580 enheternas riktning till den motsatta de för närvarande färdas i och
581 första enheten flyttar sig. Om det inträffa kollision där enheterna
582 inte har motsatt riktning får enheten som kollen gjordes för inte
583 förflytta sig denna omgång.
585 % TODO ALgoritm besk vis
586 \subsubsection{Krediträkning
}
587 I nuläget beräknas spelarens intjänade krediter på ett mycket enkelt sätt och kan ses som en tillfällig implementation. För varje iteration i tråden
\textit{CreditThread
} baseras den intjänade krediten av antalet enheter på kartan multiplicerat med
10. För varje iteration i tråden
\textit{AnimationThread
} samlas enheter in från målrutor och totala antalet multipliceras med
100.
589 \subsubsection{Tornens act()
}
591 \subsubsection{Enheternas act()
}
593 \subsubsection{Svängar
}
595 \subsubsection{Utritning av spelet
}
596 Spelplanen ritas ut på en komponent i
\textit{ATDView
}. Denna
597 komponent är en inre klass som utökar Javas
\textit{JComponent
} och är
598 döpt till
\textit{GameComponent
}. När denna komponent skapas hämtas en
599 bild från
\textit{ATDModel
} och sparas undan i ett attribut.
601 Metoden
\textit{paintComponent(Graphics g)
} överlagras för att rita ut
602 spelet i gräns\-snittet. Vid varje uppdatering av spelplanen körs denna
603 metod enligt kodsnutt
\ref{kod:paintComponent
}.
608 public void paintComponent(Graphics g)
{
609 logger.fine("paintComponent: " + Thread.currentThread().toString());
611 // Draw backgroundImage
612 g.drawImage(backgroundImage,
0,
0, null);
614 // Draw gameImage which should contain updated information from
616 g.drawImage(gameImage,
0,
0, null);
618 // Clear gameImage image with a big transparent rectangle.
619 Color transparent = new Color(
0,
0,
0,
0);
620 gameGraphics.setColor(transparent);
621 gameGraphics.setComposite(AlphaComposite.Src);
622 gameGraphics.fill(new Rectangle2D.Double(
0,
0, width, height));
626 \caption{Metoden paintComponent(Graphics g)
}\label{kod:paintComponent
}
629 För att få en uppdaterad bild där alla enheter ritar ut sig själv
630 sparas tillhörande
\textit{Graphics
}-objekt som ett attribut i
631 \textit{ATDView
} som sedan kan hämtas av animationstråden för att låta
632 varje aktuell instans av
\textit{Paintable
} (se avsnitt
633 \ref{sec:Paintable
} på sida
\pageref{sec:Paintable
}) rita ut sig själv
634 på bilden, se kodsnutt
\ref{kod:paint
}. Nedersta raden,
635 \verb!view.repaintGame();!, ritar om hela spelkomponenten, se kodsnutt
636 \ref{kod:paintComponent
};
641 // Repaint all agents
642 Graphics g = view.getGameGraphics();
643 for (Unit unit : units)
{
646 for (Tower tower : towers)
{
650 // Refresh the game view
654 \caption{Utsnitt ur AnimationThread i ATDController
}\label{kod:paint
}
657 \section{Begränsningar
}\label{Begransningar
}
658 % Vilka problem och begränsningar har din lösning av uppgiften? Hur
659 % skulle de kunna rättas till?
661 % 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
663 \section{Reflektioner
}\label{Reflektioner
}
664 % Reflektioner - Var det något som var speciellt krångligt? Vilka
665 % problem uppstod och hur löste ni dem? Vilka verktyg använde ni? Hur
666 % upplevde ni de verktygen? + Allmänna synpunkter. Om ni har upplevt
667 % problem på grund av olika miljöer (i termer av operativsystem och
668 % liknande) så kan det även vara intressant att nämna det, samt motivera
671 \section{Testkörningar
}\label{Testkorningar
}
672 % Noggranna testkörningar där man ser att programmet fungerar som det
674 I denna sektion presenteras några skärmdumpar från körningar av applikationen.
678 \includegraphics[width=
110mm
]{images/ingame1.png
}
679 \caption{Skärmdump av applikationen
}
686 \includegraphics[width=
110mm
]{images/ingame2.png
}
687 \caption{Skärmdump av applikationen
}
692 Figur
\ref{fig:ingame1
} och figur
\ref{fig:ingame2
} visar hela applikationen under ett pågående spel.
696 \includegraphics[width=
110mm
]{images/promptWinIngame.png
}
697 \caption{Skärmdump av dialogruta ''Level completed''
}
704 \includegraphics[width=
110mm
]{images/promptLose.png
}
705 \caption{Skärmdump av dialogruta ''Level lost''
}
710 Efter att användaren vunnit eller förlorat en bana låses
711 användargränssnittet och användaren får upp alternativ för fortsatt
712 spel i dialogrutor så som figur
\ref{fig:win
} och figur
713 \ref{fig:lose
} visar. Enheter som fortfarande är ute på banan
714 fortsätter att gå runt och kan dö eller gå i mål. Dock slutar
719 \includegraphics[width=
110mm
]{images/promptHighscore.png
}
720 \caption{Skärmdump av dialogruta ''Input highscore''
}
721 \label{fig:highscore
}
725 När inga fler banor finns att spela får användaren möjlighet att skicka in sin ihoptjänade poäng till en highscore lista. Denna funktionalitet drivs av en webservice som ingick i den laboration som gjordes innan denna laboration.
729 \includegraphics[width=
110mm
]{images/menu_AntiTD.png
}
730 \caption{Skärmdump av meny ''AntiTD''
}
731 \label{fig:menu_antitd
}
737 \includegraphics[width=
110mm
]{images/menu_Help.png
}
738 \caption{Skärmdump av meny ''Help''
}
739 \label{fig:menu_help
}
743 Figur
\ref{fig:menu_antitd
} och figur
\ref{fig:menu_help
} visar de alternativ som döljer sig i menyraden. I figur
\ref{fig:menu_antitd
} syns det tredje alternativet
\textit{Resume
} vilket vid start heter
\textit{Paus
} men är nu i ett annat tillstånd eftersom applikationen vid detta tillfälle var pausat. Detsamma gäller för fjärde alternativet
\textit{unMute
} vilket börjar som
\textit{Mute
}. Figur
\ref{fig:menu_help
} visar menyalternativen
\textit{Help
} och
\textit{About
}. Dessa innehåller en kort beskrivning av spelets regler och mål respektive en kort beskrivning om vilka som skapat applikationen.
747 \includegraphics[width=
110mm
]{images/leveleditor1.png
}
748 \caption{Skärmdump ''LevelEditor'', applikationen har just startat
}
755 \includegraphics[width=
110mm
]{images/leveleditor2.png
}
756 \caption{Skärmdump ''LevelEditor'', ''MapSquares'' av typen ''BlockedSquare''
}
763 \includegraphics[width=
110mm
]{images/leveleditor3.png
}
764 \caption{Skärmdump ''LevelEditor'', ''Mapsquares'' av typen ''PathSquare'', ''StartSquare'' och ''GoalSquare''
}
771 \includegraphics[width=
110mm
]{images/leveleditor4.png
}
772 \caption{Skärmdump ''LevelEditor'', ''Mapsquares'' av typen ''TurnSquare''
}
777 I figur
\ref{fig:editor1
} till figur
\ref{fig:editor4
} visas skärmdumpar av testapplikationen för att skapa banor. En hel bana har skapats genom att klicka ut rutor av olika typ.
779 \section{Diskussion
}\label{Diskussion
}
780 % Diskutera om laborationen samt allmänt kring Web services och om hur
781 % och när det är användbart (och inte användbart). Saker som kan vara
782 % trevliga att ta upp är interoperabilitet, lite om prestanda, koncepten
783 % lös koppling och så vidare. Den här sektionen ska vara en betydande
784 % del av rapporten. Det är upp till er själva att ta reda på den
785 % information ni behöver, även om föreläsningsmaterialet kan vara
786 % väldigt användbart. Kom även här ihåg att referera till era källor
787 % (även om det är från föreläsningsmaterialet).
788 Projektet är implementerat enligt design-mönstret
\textit{Model-View-Controller
}. Resultatet diskuteras under rubriken
\textit{Model-View-Controller
}. I detta stadie finns en bra grund för att lägga till funktionalitet så som nya enheter och nya banrutor med speciella egenskaper samt att utveckla användargränssnittet. I nedanstående avsnitt
\textit{Vidareutveckling
} diskuteras olika möjligheter till vidareutveckling av spelet.
790 \subsection{Model-View-Controller
}
791 % TODO Fill this section
792 Detta projekt har från inledning
794 \subsection{Vidareutveckling
}
795 Nedan följer förslag på förändringar för att vidareutveckla spelet.
797 \subsubsection{Klass Item
}
798 I inledningar av projektet planerades en abstrakt klass
\textit{Item
}
799 som skulle representera en pryl vilken skulle kunna lagras i ett
800 attribut i en MapSquare. Objekt av typen
\textit{Item
} skulle
801 t.ex. kunna vara
\textit{HealtItem, SpeedItem, CreditItem
} som kan
802 representera prylar som ger mer hälsa, ökad fart respektive ett antal
803 crediter att handla med. Dessa prylar skulle användas genom att
804 slumpmässigt läggas till i objekt av typen
\textit{PathSquare
} och
805 alltså representeras grafiskt genom att rutan ritar ut prylen ovanpå
806 sig. En ruta med en pryl på skulle sedan skicka vidare en inkommande
807 enhets referens till prylen som i sin tur skulle manipulera enhetens
808 attribut. En pryl med teleporterbeteende diskuteras under rubrik
809 \textit{Unit av typen TeleportUnit
} (se
\pageref{TeleportUnit
}).
811 \subsubsection{Unit av typen TeleportUnit
}\label{TeleportUnit
}
812 För att uppfylla nivå tre av denna laborations kravspecifikation krävs
813 en enhet med möjlighet att placera ut så kallade
814 teleport-plattor. Detta kan uppnås i detta projekt genom att skapa
815 subklasser av
\textit{Item
} kallad t.ex.
\textit{TeleportStartItem
}
816 och
\textit{TeleportEndItem
}. Prylen
\textit{TeleportStartItem
} skulle
817 kunna bäras av en
\textit{Unit
} av typen
\textit{TeleporterUnit
} och
818 kunna läggas ut på nuvarande ruta genom t.ex. musklick på
819 enheten. Attribut som behövs i
\textit{TeleportStartItem
} är x- och
820 y-koordinater till den tillhörande prylen
\textit{TeleportEndItem
}
821 vilket i sin tur innehåller attribut för aktuell riktning som
822 utsläppta enheter ska ha samt en kö där uppsamlade enheter läggs till
823 för att sedan släppas ut en efter en då positionen är ledig. Algoritm
824 för kollisionsdetektering skulle fungera på samma sätt som algoritmen
825 som används när enheter släpps ut ur startrutor (se
826 \pageref{sec:StartSquare
});
828 \subsubsection{Gränssnitt
}
829 I nuläget startas första banan direkt när applikationen startar. Att få se en så kallad splash-screen (introduktionsbild) kan vara önskvärt och åtgärdas enkelt genom att i konstruktor för
\textit{ATDController
} lägga till ett metodanrop till metod i
\textit{ATDView
} som visar något och väntar på att användaren ska välja ett nytt spel.
831 I kontrollpanelen finns stora möjligheter till vidareutveckling då den nuvarande just täcker den funktionalitet som behövs för att köra spelet. Till en början skulle listan med tillgängliga units kunna bytas ut mot ikoner som visar enhetens grafiska representation. För att lättare kunna få en översikt över en enhets egenskaper skulle hälsa och hastighet kunna förmedlas med staplar istället för med text. Om listan byts mot ikoner finns även möjligheten att ta bort knappen
\textit{Release Units
} och låta användaren skicka ut önskad enhet genom att direkt klicka på enhetens ikon.
833 \bibliographystyle{alpha
}
834 \bibliography{books.bib
}
838 \pagenumbering{arabic
}
839 \section{Källkod
}\label{sec:kallkod
}
840 % Källkoden ska finnas tillgänglig i er hemkatalog
841 % ~/edu/apjava/lab1/. Bifoga även utskriven källkod.
842 Härefter följer utskrifter från källkoden och andra filer som hör till
846 \subsection{AntiTD.java
}\label{AntiTD.java
}
847 \lstinputlisting{../src/se/umu/cs/dit06ajnajs/AntiTD.java
}
848 % \begin{footnotesize}
849 % \verbatiminput{../src/se/umu/cs/dit06ajnajs/AntiTD.java}