--- author: Florian Fischer theme: metropolis aspectratio: 169 --- # Phase I - Modellierung eines Spiels ## \faIcon{pencil-alt} Modellierung \hfill 10min ::: {.columns align=center} :::: {.column width=50%} * Erstelle ein Klassendiagramm mit allen **Klassen**, die du im rechten Screenshot ausmachen kannst. * Notiere die **Attribute**, die du sehen kannst und welche die Klassen haben müssen. * Notiere die **Methoden**, die die Klassen vermutlich haben. * Zeichne und beschrifte die Beziehungen zwischen den Klassen. :::: :::: {.column width=50%} ![](img/jumpnrun.png) :::: ::: ## "Offensichtliche" Klassen ::: {.columns} :::: {.column width=45%} ### Spieler \vspace{-0.3cm} *Attribute*: \vspace{-0.2cm} * Geschwindigkeit * Position \vspace{-0.3cm} *Methoden*: \vspace{-0.2cm} * Bewegen * Springen \vspace{-0.3cm} ### Flagge * Position \vspace{-0.3cm} ### Plattform * Position * Höhe * Breite ::: :::: {.column width=55%} \begin{tikzpicture} \begin{class}[text width=3cm]{Spieler}{0,0} \attribute{geschwindigkeit} \attribute{position} \operation{bewegen()} \operation{springen()} \end{class} \begin{class}[text width=3cm]{Flagge}{0,-4.5} \attribute{position} \end{class} \begin{class}[text width=3cm]{Platform}{5,-2.5} \attribute{position} \attribute{hoehe} \attribute{breite} \end{class} \association{Spieler}{steht auf}{}{Platform}{}{}; \association{Spieler}{erreicht}{}{Flagge}{}{}; \end{tikzpicture} :::: ::: ## "Nicht sichtbare" Klassen ::: {.columns} :::: {.column width=50%} ### Level \vspace{-0.3cm} *Attribute*: \vspace{-0.2cm} * feste Objekte * interaktive Objekte \vspace{-0.3cm} *Methoden*: \vspace{-0.2cm} * naechstes Level * Spieler-Position setzen ### Spiel * Level * Spieler * Highscore * Zeit * ... ::: :::: {.column width=50%} \begin{tikzpicture} \begin{class}[text width=3cm]{Level}{0,0} \attribute{festeObjekte} \attribute{interaktiveObjekte} \end{class} \begin{class}[text width=3cm]{Spiel}{0,-2.5} \attribute{level} \attribute{player} \end{class} \end{tikzpicture} :::: ::: ## Klassendiagramm \centering \begin{tikzpicture} \begin{class}[text width=3cm]{Spieler}{6,1} \attribute{geschwindigkeit} \attribute{position} \operation{bewegen()} \operation{springen()} \end{class} \begin{class}[text width=3cm]{Flagge}{4.5,-2.5} \attribute{position} \end{class} \begin{class}[text width=3cm]{Platform}{8,-3.75} \attribute{position} \attribute{hoehe} \attribute{breite} \end{class} \begin{class}[text width=3cm]{Spiel}{0,0} \attribute{Level} \attribute{Player} \end{class} \association{Spiel}{}{}{Spieler}{1}{}; \begin{class}[text width=3cm]{Level}{1,-4.5} \attribute{festeObjekte} \attribute{interaktiveObjekte} \end{class} \association{Spiel}{}{}{Level}{1}{}; \association{Level}{}{}{Flagge}{}{}; \association{Level}{}{}{Platform}{n}{}; \end{tikzpicture} ## {.standout} Wer ruft die Methoden des Spielers auf? ## \faIcon{chalkboard-teacher} EVA-Prinzip {.t} ::: {.columns} :::: {.column width=65%} \vspace{0.2cm} \only<2->{ Trennung der Datenverarbeitung in: \begin{itemize} \item \boldred{E}ingabe: \texttt{input()} \item \boldred{V}erarbeitung: \texttt{update()} \item \boldred{A}usgabe: \texttt{output()} \end{itemize} } \vspace{0.1cm} \only<3->{\textbf{\faIcon{lightbulb} Wie oft müssen wir die drei Schritte ausführen?}} \only<4->{ Solange das Spiel läuft! \begin{block}{EVA-Loop} \phantomsection\label{eva-loop} \texttt{solange Spiel aktiv}\\ ~~\texttt{input()}\\ ~~\texttt{update()}\\ ~~\texttt{output()}\\ \end{block} } :::: :::: {.column width=30%} \vspace{1.5cm} \begin{tikzpicture} \only<2->{ \node[line width=1pt, draw, minimum width=3cm, rounded corners=5pt] (e) {Eingabe}; \node[line width=1pt, draw, minimum width=3cm, rounded corners=5pt, below=of e] (v) {Verarbeitung}; \node[line width=1pt, draw, minimum width=3cm, rounded corners=5pt, below=of v] (a) {Ausgabe}; \draw[-{Triangle}, line width=1pt] (e) to (v); \draw[-{Triangle}, line width=1pt] (v) to (a); } \only<4>{ \draw[-{Triangle}, line width=1pt, dashed] (a.east) -- ($(a.east) + (0.5, 0)$) -- ($(e.east) + (0.5, 0)$) -- (e.east); } \end{tikzpicture} :::: ::: ## \faIcon{chalkboard-teacher} \only<2->{Spieleengine} **\faIcon{lightbulb} Sind wir die ersten mit diesem Problem?** \pause Sicher nicht! Also lasst uns das Rad nicht neu erfinden, sondern eine \boldred{Spieleengine} verwenden, die uns die lästigen Dinge abnimmt. \pause ### Online-IDE ``` solange Spiel aktiv <- Online-IDE input() <- Online-IDE update() <- Wir output() <- Online-IDE ``` ## Wie werden unsere Methoden aufgerufen? ::: {.columns} :::: {.column width=75%} Wir erfüllen mit unserer `Spieler`-Klasse das \boldred{interface}, das die Online-IDE vorgibt. \vspace{0.1cm} Ein Interface gibt zu implementierende Methoden vor. \vspace{0.1cm} Um automatisch das Interface zu erfüllen, erben wir von der Klasse `Actor`. :::: :::: {.column width=25%} \hspace{-1.25cm} \scalebox{1.1}{ \begin{tikzpicture} \node[fill=magenta!20, line width=1pt, draw, minimum height=1cm, minimum width=3cm, rounded corners=5pt] (v) {Verarbeitung}; \node[fill=bg, minimum height=1cm, minimum width=3cm, rounded corners=5pt, above=-0.1cm of v] (e) {Eingabe}; \draw[line width=1pt, rounded corners=5pt, fill=bg] ($(v.north west) + (0, 1cm)$) -- ($(v.north east) + (0, 1cm)$) -- (v.north east) {[sharp corners] -- ($(v.north east) - (0.625cm, 0)$) -- ($(v.north east) - (0.6cm, 0.2cm)$) -- ($(v.north east) - (0.8cm, 0.2cm)$) -- ($(v.north east) - (0.775cm, 0)$) -- ($(v.north east) - (1.525cm, 0)$) -- ($(v.north east) - (1.5cm, 0.2cm)$) -- ($(v.north east) - (1.7cm, 0.2cm)$) -- ($(v.north east) - (1.675cm, 0)$) -- ($(v.north east) - (2.425cm, 0)$) -- ($(v.north east) - (2.4cm, 0.2cm)$) -- ($(v.north east) - (2.6cm, 0.2cm)$) -- ($(v.north east) - (2.575cm, 0)$)} -- (v.north west) -- ($(v.north west) + (0, 1cm)$); \draw[line width=1pt, red] ($(v.north east) + (0.1cm, 0.2cm)$) -- ($(v.north east) - (-0.1cm, 0.3cm)$) -- ($(v.north west) - (0.1cm, 0.3cm)$) -- ($(v.north west) + (-0.1cm, 0.2cm)$) -- ($(v.north east) + (0.1cm, 0.2cm)$); \draw[-Latex, bend left=35, line width=0.75pt] ($(e.east) + (0, 1mm)$) to ($(v.east)-(0,1mm)$); \node[minimum height=1cm, above=-0.1cm of v] (e) {Eingabe}; \node[rotate=90] at ($(v.north west) - (0.3cm, 0.0cm)$) {\boldred{interface}}; \end{tikzpicture} } :::: ::: \pause **Java** `class Player extends Actor`{.java} \pause **Methoden** * `void act()`{.java} ## Wie erhalten wir die Eingaben? ::: {.columns} :::: {.column width=75%} \faIcon{lightbulb} Wir fragen die Online-IDE. \vspace{0.1cm} Die Online-IDE bietet Methoden, um die Eingaben zu erfragen. \vspace{0.1cm} Wir haben die Methoden bereits von der Klasse `Actor` geerbt. :::: :::: {.column width=25%} \hspace{-1.25cm} \scalebox{1.1}{ \begin{tikzpicture} \node[line width=1pt, draw, minimum height=1cm, minimum width=3cm, rounded corners=5pt] (v) {Verarbeitung}; \node[fill=bg, minimum height=1cm, minimum width=3cm, rounded corners=5pt, above=-0.1cm of v] (e) {Eingabe}; \draw[line width=1pt, rounded corners=5pt, fill=cyan!20] ($(v.north west) + (0, 1cm)$) -- ($(v.north east) + (0, 1cm)$) -- (v.north east) {[sharp corners] -- ($(v.north east) - (0.625cm, 0)$) -- ($(v.north east) - (0.6cm, 0.2cm)$) -- ($(v.north east) - (0.8cm, 0.2cm)$) -- ($(v.north east) - (0.775cm, 0)$) -- ($(v.north east) - (1.525cm, 0)$) -- ($(v.north east) - (1.5cm, 0.2cm)$) -- ($(v.north east) - (1.7cm, 0.2cm)$) -- ($(v.north east) - (1.675cm, 0)$) -- ($(v.north east) - (2.425cm, 0)$) -- ($(v.north east) - (2.4cm, 0.2cm)$) -- ($(v.north east) - (2.6cm, 0.2cm)$) -- ($(v.north east) - (2.575cm, 0)$)} -- (v.north west) -- ($(v.north west) + (0, 1cm)$); \draw[line width=1pt, red] ($(v.north east) + (0.05cm, 0.2cm)$) -- ($(v.north east) - (-0.05cm, 0.3cm)$) -- ($(v.north west) - (0.05cm, 0.3cm)$) -- ($(v.north west) + (-0.05cm, 0.2cm)$) -- ($(v.north east) + (0.05cm, 0.2cm)$); \draw[-Latex, bend right=35, line width=0.75pt] (v.east) to ($(e.east) + (0, 2mm)$); \node[minimum height=1cm, minimum width=3cm, above=-0.1cm of v] (e) {Eingabe}; \node[rotate=90] at ($(v.north west) - (0.3cm, 0.0cm)$) {\boldred{interface}}; \end{tikzpicture} } :::: ::: \pause **Methoden** * `boolean isGamepadButtonDown(int gamepadIndex, int buttonIndex)`{.java} * `boolean isGamepadConnected(int gamepadIndex)`{.java} * `boolean isKeyDown(String key)`{.java} * `boolean isKeyUp(String key)`{.java} ## \faIcon{desktop} Arbeitsauftrag: Los gehts! \hfill 10 min \let\tightlist\relax * Öffne das **JumpNRun Vorlage1** Projekt. * Untersuche die bereits vorhandenen Klassen. * Ergänze die Klasse `Player` um die Attribute: `vx`, `speed` vom Typ `double`{.java}. * Initialisiere `vx` mit `0` und `speed` mit 10. ## \faIcon{desktop} Arbeitsauftrag: Spieler bewegen \hfill 15 min Vervollständige die Methode `act` des Spielers * Die Figur soll sich entsprechend ihrer Geschwindigkeit in X-Richtung (`vx`) horizontal bewegen. **Tipp**: Verwende die Methode `move(double deltaX, double deltaY)`{.java} der Klasse `Sprite` * *Falls* eine Pfeiltaste gedrückt wird, soll sich Figur mit der Geschwindigkeit `speed` in die entsprechende Richtung bewegen. **Tipp**: Verwende die Methode `isKeyDown(int key)`{.java} mit den beiden Pfeiltasten: `Key.ArrowLeft`{.java} und `Key.ArrowRight`{.java} * Wird **keine** der beiden Tasten gedrückt, soll die Figur abbremsen. Setzte ihre Geschwindigkeit in X-Richtung auf $80%$ des aktuellen Werts. \faIcon{play} Teste deine Implementierung. ## \faIcon{desktop} Arbeitsauftrag: Fallen \hfill 10 min \let\tightlist\relax * Ergänze den Spieler um die Attribute: `vy`, `gravity`, `sprung` vom Typ `double`{.java}. * Initialisiere die Attribute `gravity` mit `0.8` und `sprung` mit `-15`. * Die Figur soll sich auch entsprechend ihrer Geschwindigkeit in Y-Richtung (`vy`) vertical bewegen. **Tipp**: Passe den `move(...)` Methoden-Aufruf in der `act`-Methode an. * *Falls* die Figur **nicht** auf dem Boden steht, d.h. ihr Mittelpunkt einen Y-Wert (`getCenterY()`) *kleiner* als 350 hat, soll sich ihre Geschwindigkeit in Y-Richtung `vy` um `gravity` erhöhen. * *Ansonsten* wenn sie auf dem Boden steht, soll ihre Y-Geschwindigkeit `vy` auf `0` gesetzt werden. ## \faIcon{desktop} Arbeitsauftrag: Springen \hfill 10 min *Falls* die Figur auf dem Boden steht, d.h. ihr Mittelpunkt einen Y-Wert *größer gleich* 350 hat, **und** die Pfeiltaste nach oben gedrückt ist `Key.ArrowUp` soll sich ihre Geschwindigkeit in Y-Richtung `vy` um `sprung` erhöhen. \faIcon{play} Teste deine Implementierung. ## \faIcon{desktop} Arbeitsauftrag: Blickrichtung ### \faIcon{earlybirds} Für Schnelle Die Figur soll in die Richtung ihrer Bewegung blicken. \let\tightlist\relax * Ergänze die Klasse `Player` um das Attribute: `headingRight` vom Typ `boolean`{.java} * *Falls* eine Pfeiltaste gedrückt wurde und ein Richtungswechsel statt findet * passe den Wert des Attributs `headingRight` entsprechend an * spiegele die Figur durch einen Aufruf der Methode `mirrorX()` # Phase II - Plattformen und Kollision ## Plattformen und Level ::: {.columns} :::: {.column width=50%} \begin{center} \begin{tikzpicture} \begin{class}[text width=4cm]{Plattform}{0,-4.5} \attribute{position} \attribute{hoehe} \attribute{breite} \end{class} \begin{class}[text width=4cm]{Level}{0,0} \attribute{festeObjekte} \attribute{interaktiveObjekte} \end{class} \end{tikzpicture} \end{center} \vspace{1cm} Ein Level soll mehrer feste Plattformen haben. :::: :::: {.column width=50%} ![](img/jumpnrun.png) :::: :::