\begin{intro}
I det følgende vil implementering af Blaster blive præsenteret. Blaster er opdelt i to programmer: klienten og serveren. Disse deler umiddelbart meget kode, så hvis ikke andet er angivet bruges samme kode i serveren såvel som klienten.

Yderligere er afsnittet delt op i to dele: en del der beskriver de klasser, der bruges i selve spillet, samt en del, der beskriver de klasser der bruges til netværkskommunikation.
\end{intro}

\section{Spillet}

\subsection{ClientController}
\texttt{ClientController} er indgangsklassen til klienten. \texttt{run} metoden indeholder selve programløkken som driver hele spillet indtil det afsluttes. Klassen sørger overordnet for, at beskeder bliver sendt og modtaget over netværket, at inputtet fra brugeren håndteres, at klientens spil-tilstand opdateres samt at klienten får tegnet spillet på skærmen. \texttt{run} metoden er skitseret i liste \ref{lst:clientrun}. Foruden \texttt{run} metoden indholder klassen en række af \texttt{View}s, der bruges til at tegne spillet. \texttt{ClientController} er implementeret som en singleton da der kun vil eksistere en enkelt instans af klassen på et tidspunkt.

\begin{center}
\begin{minipage}[t]{0.8\textwidth}
\begin{flushleft}
\begin{lstlisting}[caption=Pseudo-kode for klientens programløkke, label=lst:clientrun]
forbind til server
opret lokal spiller

indtil spillet afslutter:
    håndter input
    håndter beskeder fra serveren
    opdater spillets tilstand
    tegn spillet i skærmen
    send beskeder til serveren
loop
\end{lstlisting}
\end{flushleft}
\end{minipage}
\end{center}

\subsection{ServerController}
\texttt{ServerController} er indgangsklassen til serveren. Den er baseret på \texttt{ClientController}, men tager sig udelukkende af at sende og modtage beskeder samt at opdatere spillets tilstand. Serveren skal altså ikke bekymre sig om at håndtere input fra en bruger eller at tegne spillet. \texttt{ServerController}s run metode er skitseret i liste \ref{lst:serverrun}.

\begin{center}
\begin{minipage}[t]{0.8\textwidth}
\begin{flushleft}
\begin{lstlisting}[caption=Pseudo-kode for serverens programløkke, label=lst:serverrun]
start server

indtil spillet afslutter:
    check for nye klienter
    håndter beskeder fra klienter
    opdater spillets tilstand
    send beskeder til klienter
loop
\end{lstlisting}
\end{flushleft}
\end{minipage}
\end{center}

\section{GameController}
\texttt{GameController} klassen håndterer spillets tilstand. Det vil sige, at den sørger for at holde alle spillere opdaterer deres tilstand så vel som at sørge for at alle objekter opdaterer deres position og hastighed. Desuden undersøger \texttt{GameController} om forskellige objekter kolliderer med hinanden inde i spillet. \texttt{think} metoden er skitseret i liste \ref{lst:gamethink}.

\begin{center}
\begin{minipage}[t]{0.8\textwidth}
\begin{flushleft}
\begin{lstlisting}[caption=Nuværende pseudo-kode for spillogikken, label=lst:gamethink]
opdater alle spillere

opdater alle skibe, slet eventuelle døde

for alle skibe
    hvis skibet kolliderer med banen
    beskadig skibet og inverter hastighedsvektoren

opdater alle skud, slet eventuelle døde

undersøg om skud kolliderer med banen

undersøg om skud rammer skibe
\end{lstlisting}
\end{flushleft}
\end{minipage}
\end{center}

Det er vitgigt at bemærke, at \texttt{GameController} ikke blev færdigimplementeret:

\begin{itemize}
\item \texttt{GameController} mangler at blive delt op i en \texttt{ClientGameController} og \texttt{ServerGameController} klasse på samme måde som \texttt{ClientNetworkController} og \texttt{ServerNetworkController}, og ved samme lejlighed skal think metoden refaktoreres til flere mindre metoder. Årsagen er, at klienten ikke skal håndtere nogen form for kollision eller skade, den skal kun opdatere spillere, skibe og skud. Se liste \ref{lst:clientgamethink}.
\item Kollisioner bliver ikke håndteret korrekt i den nuværende implementation af \texttt{GameController}. Da den nuværende kollisionsalgoritme kun er i stand til at opdage hvis to polygoner overlapper, er det kun muligt at invertere skibets hastighedsvektor ved kollision. Havde det været muligt at finde kant på det fremmede polygon som skibet kolliderer med, havde det været trivielt at finde reflektionsvektoren ud fra skibets hastighedsvektor og kantens normal. Se liste \ref{lst:servergamethink}.
\item Spillogikken er slet ikke koblet sammen med netværksbeskederne. Det var meningen, at \texttt{think} metoden skulle sende beskeder til henholdsvis alle klienterne eller serveren når visse begivenheder fandt sted. Dette kunne f.eks. være jævnligt at sende \texttt{ShipUpdate} beskeder til alle klienter, eller at sende en \texttt{PlayerKilled} besked til alle klienter når en spiller døde i \texttt{ServerGameController}.
\end{itemize}

\begin{center}
\begin{minipage}[t]{0.8\textwidth}
\begin{flushleft}
\begin{lstlisting}[caption=Ønskede pseudo-kode for klient spillogikken, label=lst:clientgamethink]
opdater alle spillere

opdater alle skibe, slet eventuelle døde

opdater alle skud, slet eventuelle døde
\end{lstlisting}
\end{flushleft}
\end{minipage}
\end{center}

\begin{center}
\begin{minipage}[t]{0.8\textwidth}
\begin{flushleft}
\begin{lstlisting}[caption=Ønskede pseudo-kode for server spillogikken, label=lst:servergamethink]
opdater alle spillere

opdater alle skibe, slet eventuelle døde
send ændrede skibspositioner til klienterne

for alle skibe
    hvis skibet kolliderer med banen
    find den kant som skibet kolliderer med
    sæt skibets hastighedsvektor lig med reflektionsvektoren

opdater alle skud, slet eventuelle døde
send nye skud til klienterne

undersøg om skud kolliderer med banen

undersøg om skud rammer skibe
\end{lstlisting}
\end{flushleft}
\end{minipage}
\end{center}

\subsection{View}

View klassen og dens subklasser er ansvarelige for alt visualisering af spillet på klienten.

View er implementeret som en decorator\cite{patterns}, så den har

\subsubsection{GameView}

\texttt{GameView} er ansvarelig for at tegne de objekter der eksisterer i \texttt{Level}. \texttt{drawContent} metoden i \texttt{GameView} er skitseret i liste \ref{lst:gameviewdraw}

\begin{center}
\begin{minipage}[t]{0.8\textwidth}
\begin{flushleft}
\begin{lstlisting}[caption=Pseudo-kode for tegning af GameView, label=lst:gameviewdraw]
centrer kameraet på klientens skib

tegn banen

tegn alle skud

tegn alle skibe
\end{lstlisting}
\end{flushleft}
\end{minipage}
\end{center}

\subsection{Level}
Level indeholder de objekter der eksisterer inde i spillet: en liste af skibe, en liste af skud samt en bane.

\subsection{Object}

\texttt{Object} er en abstrakt baseklasse for alle objekter i banen. \texttt{Object} indeholder oplysninger om objektets placering, orientering, hastighed og acceleration. Et objekt indeholder yderligere \texttt{get} og \texttt{set} metoder til \texttt{owner} feltet, der henviser til hvilken spiller der ejer objektet i form af en spiller id, som refererer til de spillere der er gemt i \texttt{GameController}. \texttt{Object} indeholder også metoden \texttt{kill} der sætter et flag i objektet, således at det bliver slettet af \texttt{GameController}.
\texttt{think} metoden opdaterer objektets position ud fra simpel mekanisk bevægelse med konstant acceleration. Klasserne \texttt{Ship} og \texttt{Bullet} nedarver fra \texttt{Object}. \texttt{Object} har også en abstrakt \texttt{collides} metode, som \texttt{Ship} og \texttt{Bullet} implementerer hver for sig.

\begin{center}
\begin{minipage}[t]{0.8\textwidth}
\begin{flushleft}
\begin{lstlisting}[caption=Pseudo-kode for think i Object, label=lst:objectthink]
hastighed = hastighed + acceleration + $\Delta t$

begræns objektets hastighed til dens maksimumhastighed

position = position + hastighed + $\Delta t$

vinkel = vinkel + vinkelhastighed + $\Delta t$
\end{lstlisting}
\end{flushleft}
\end{minipage}
\end{center}

\subsection{Player}

Player klassen repræsenterer en spiller. En spiller har et unikt id som bruges til at identificere spilleren i netværksbeskeder og owner feltet i \texttt{Object}. \texttt{Player} indeholder også spillerens navn og score. En spiller har et skib, som think metoden sørger for at genoprette hvis spilleren mister det, som er illustreret i liste \ref{lst:playerthink}.

\begin{center}
\begin{minipage}[t]{0.8\textwidth}
\begin{flushleft}
\begin{lstlisting}[caption=Pseudo-kode for think i Player, label=lst:playerthink]
hvis spilleren ikke har noget skib
    hvis der er gået nok tid siden spilleren døde
        lav skib
        tilføj skib til bane
        sæt skibets ejer til spilleren
\end{lstlisting}
\end{flushleft}
\end{minipage}
\end{center}

\subsubsection{LocalPlayer}

\texttt{LocalPlayer} nedarver fra \texttt{Player} og overskriver dens think metode. \texttt{LocalPlayer} eksisterer kun på klienten i en enkelt instans, nemlig den som repræsenterer klientens spiller. I \texttt{LocalPlayer}s think metode læses input fra brugeren, og skibet manipuleres afhængigt af input. Dette ses i liste \ref{lst:localplayerthink}. Den egentlige styring af spillerens rumskib håndteres passivt af den grund, at der så ikke skal tages specielt hensyn til spillerens skib nogle steder. \texttt{LocalPlayer} instansen gemmes i \texttt{GameControllerens} map af spillere på lige fod med de \texttt{Player} objekter som repræsenterer de fremmede spillere.

\begin{center}
\begin{minipage}[t]{0.8\textwidth}
\begin{flushleft}
\begin{lstlisting}[caption=Pseudo-kode for think i LocalPlayer, label=lst:localplayerthink]
kald think i Player

hvis spilleren ikke har et skib
    returner

hvis fremad knappen er nede
    accelerer spillerens skib
    brug lidt af skibets brændstof

hvis drej til højre knappen er nede
    sæt skibets vinkelhastighed således at det drejer til højre

hvis drej til venstre knappen er nede
    sæt skibets vinkelhastighed således at det drejer til venstre

hvis skydeknappen er nede
    bed skibet om at skyde

hvis selvmordsknappen er nede
    dræb skibet
\end{lstlisting}
\end{flushleft}
\end{minipage}
\end{center}

\begin{figure}[h] 
\begin{center} 
    \begin{minipage}[t]{0.9\textwidth} 
        \begin{center} 
            \includegraphics[width=0.9\textwidth]{gfx/ingame.png} 
            \caption{Screenshot af Blaster} 
            \label{fig:gamestart} 
        \end{center} 
    \end{minipage} 
\end{center} 
\end{figure} 