1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
|
\documentclass{handout}
\csname endofdump\endcsname
\usepackage{minted}
\usepackage{hyperref}
\usepackage[ngerman]{babel}
\geometry{margin=2cm}
\usetikzlibrary{calc, shapes.arrows}
\title{JumpNRun Arbeitsauftrag 2}
\setcounter{section}{2}
\begin{document}
\thispagestyle{empty}
\subsection{Weiterarbeiten}
\begin{tcolorbox}
Du kannst mit deinem eigenen Projekt weiterarbeiten oder du verwendest den Workspace \textbf{JumpNRun Vorlage 2}.
Wenn du mit der Vorlage weiterarbeitest, kannst die manchne Schritte der Arbeitsaufträge in runden Klammern auslassen, da diese in der Vorlage schon enthalten sind.
\end{tcolorbox}
\subsection{\faIcon{desktop} Plattformen und Level}
Ein Level besteht aus soliden - unbeweglichen und undurchlässigen - Plattformen.
Außerdem, soll ein Level zum nächsten Level weiterleiten können und die Startposition des Spielers festlegen.
\begin{tabular}{p{0.325\textwidth} p{0.675\textwidth}}
\vspace{0mm}
\begin{tikzpicture}
\begin{class}[text width=4.75cm]{Level}{0,0}
\attribute{festeObjekte}
\attribute{interaktiveObjekte}
\operation{next(): Level}
\operation{spawnPlayer(Player player)}
\end{class}
\end{tikzpicture} &
\begin{defbox}{Objekte gruppieren}
Die Online-IDE bietet die Klasse `Group` um mehrere graphische Objekte zu verwalten.
Wir benötigen folgende Methoden:
\begin{itemize}
\item \mintinline{java}{void add(T shape)} - Fügt ein Objekt der Gruppe hinzu
\item \mintinline{java}{void destroyAllChildren()} - Zerstört alle Objekte der Gruppe
\end{itemize}
\end{defbox}
\\
\end{tabular}
\begin{itemize}
\item (Implementiere oder Kopiere die Klasse \texttt{Level})
\item Implementiere die Klasse \texttt{Level1}, die von der Klasse \texttt{Level} erbt.
\item Erzeuge ein Rechteck für den Boden.\newline
(\mintinline{java}{new Rectangle(x, y, breite, hoehe)})
\item Erzeuge ein Rechteck als linke Spielrand-Begrenzung.
\item Erzeuge vier Rechtecke als aufsteigende Platformen.\newline
Vorschlag: \mintinline{java}{new Rectangle(200 + 450 * i, 470 - 40 * i, 300, 25)}
\item Füge alle erzeugten Rechtecke der \texttt{solidObjekt} Gruppe hinzu.
\end{itemize}
\subsection{\faIcon{desktop} Spielstart}
Vervollständige den Konstruktor der Klasse \texttt{JumpNRun}.
\begin{itemize}
\item Erzeuge ein \texttt{Level1} Objekt und initialisiere damit das \texttt{Level} Attribut der Klasse.
\item Rufe die \texttt{spawnPlayer}-Methode des ersten Levels mit dem \texttt{Player} Attribute der Klasse auf.
\end{itemize}
\subsection{\faIcon{desktop} Kollision}
Bisher fällt der Spieler einfach durch den Boden!
\begin{defbox}{Kollision erkennen}
\begin{tabular}{p{0.5\textwidth} p{0.48\textwidth}}
\vspace{0mm}
Um eine Kollision zwischen zwei Objekten zu erkennen, müssen wir prüfen, ob sie sich in \emph{mindestens} einem Punkt im Koordinatensystem überschneiden. &
\vspace{-0.5cm}
\begin{pseudocode}
\begin{verbatim}
für alle Objekte
für alle anderen Objekte
Finde Überschneidung
Falls Überschneidung
Behandle Überschneidung
\end{verbatim}
\end{pseudocode} \\
\end{tabular}
\end{defbox}
Die Methode \mintinline{java}{getCollidingShapes(Group g)} eines Sprites gibt alle Objekte einer Gruppe \texttt{g} zurück, die mit dem \texttt{Sprite} kollidieren.
\label{subsection:collision-detection}
Mit der \texttt{foreach}-Variante der \texttt{for}-Schleife können wir alle Kollisionen behandeln.
\begin{minted}{java}
// Finde alle kollidierenden soliden Objekte des Levels
Shape[] collidingShapes = getCollidingShapes(jumpNRun.level.solidObjects);
for (Shape shape: collidingShapes) { // Betrachte jedes kollidierende Objekt
// Behandle Kollision
}
\end{minted}
Implementiere in der \mintinline{java}{void act()} des Spielers die Kollisionserkennung.
\begin{itemize}
\item Speichere alle \emph{soliden} kollidierenden Objekte, des aktuellen Levels als Variable.\newline
(\mintinline{java}{Shape[] collidingShapes = getCollidingShapes(jumpnrun.level.solidObjects);}
\item Implementiere eine \texttt{foreach}-Wiederholung, die alle kollidierenden Objekte behandeln soll.\newline
(\mintinline{java}|for(Shape shape: collidingShapes) {}|)
\end{itemize}
\subsection{\faIcon{desktop} Kollision behandeln}
\label{subsection:collision-handling}
\begin{defbox}{Kollision was jetzt?}
\begin{tabular}{p{0.37\textwidth} p{0.6\textwidth}}
\vspace{0mm}
\begin{tikzpicture}[scale=0.9]
\node[draw, minimum width=2cm, minimum height=0.5cm] (p) at (0,0) {};
% \draw[opacity=0.7] (2,2) -- (-2,-2);
% \draw[opacity=0.7] (-2,2) -- (2,-2);
\node[draw, minimum width=2cm, minimum height=0.5cm] (p) at (0,0) {};
\node[draw, single arrow, below=0.5cm of p, shape border rotate=90] {bottom};
\node[draw, single arrow, left=0.5cm of p] {left};
\node[draw, single arrow, right=0.5cm of p, shape border rotate=180 ] {right};
\node[draw, single arrow, above=0.5cm of p, shape border rotate=270] {top};
\end{tikzpicture}
&
Der Spieler, soll die aktuelle Bewegung, die zur Kollision geführt hat, rückgängig machen, bis es zu keiner Kollision mehr kommt. \newline\vspace{2mm}
Die Geschwindigkeit des Spielers muss in die Kollisionsrichtung gestoppt (auf \texttt{0} gesetzt werden). \\
\end{tabular}
\end{defbox}
Implementiere im Spieler die Methode \mintinline{java}{void reactToCollisionWithShape(Shape shape)}:
\begin{itemize}
\item Bestimme die Richtung, aus der der Spieler mit \texttt{shape} kollidiert ist.\newline
(\mintinline{java}{Direction direction = directionRelativeTo(shape);})
\item Setze je nach Richtung (\texttt{top}, \texttt{left}, \texttt{right}, \texttt{bottom}), die Geschwindigkeit dieser Richtung auf 0.
\item Mache die letzte Bewegung mit \mintinline{java}{moveBackFrom(shape, false)} rückgängig.\newline
(\mintinline{java}{moveBackFrom(Shape otherShape, boolean keepColliding)})
\item Wiederholung die letzte Bewegung in die Richtung, die \emph{nicht} zur Kollision führt.
\end{itemize}
\subsection*{\faIcon{desktop} Kollision erkennen \emph{und} behandeln}
Der folgende Pseudocode beschreibt das Zusammenspiel der Erkennung von Kollision und ihrer anschließenden Behandlung.
\begin{pseudocode}
\texttt{für alle überschneidenden Objekte}
\hspace{5mm}\texttt{behandle Überschneidung}
\end{pseudocode}
Wir wollen also unsere \textbf{Kollisionserkennung} \mintinline{java}{getCollidingShapes(Group group)} (Siehe: \ref{subsection:collision-detection}) mit unserer \textbf{Kollisionsbehandlung} \mintinline{java}{reactToCollisionWithShape(Shape shape)} (Siehe: \ref{subsection:collision-handling}) verbinden.
\vspace{3mm}
\begin{center}
\textbf{Kollisionserkennung} \hspace{5mm} \faIcon{link} \hspace{5mm} \textbf{Kollisionsbehandlung}
\end{center}
\vspace{3mm}
\begin{itemize}
\item Rufe mit \emph{jedem} kollidierenden Shape in \texttt{collidingShapes} die Methode \mintinline{java}{reactToCollisionWithShape} auf.
\end{itemize}
\subsection{\faIcon{desktop} Auf dem Boden stehen}
Bei Kollision \textbf{von oben} wollen wir erkennen, das wir auf festem Boden stehen!
Das erlaubt Gravitation wirken zu lassen, abzuspringen und gegebenenfalls eine Laufanimation anzuzeigen.
Das Attribut \mintinline{java}{Shape standsOn} der Klasse \texttt{Player} merkt sich auf welchem Shape der Spieler steht.
\begin{itemize}
\item (Ergänze das \texttt{standsOn} Attribut vom Typ \texttt{Shape} in der Klasse \texttt{Player})
\item (Ändere die Prüfung, ob Gravitation wirkt zu: \mintinline{java}{standsOn == null})
\item Bei Kollision von \emph{oben}, speichere das kollidierende \texttt{shape} im Attribut \texttt{standsOn}.
\item Überprüfe vor der Kollisionserkennung, ob der Spieler noch mit einem möglicherweise gespeicherten \texttt{standsOn} Objekt kollidiert. (\mintinline{java}{standOn != null && !collidesWith(standsOn)})
\item \emph{Falls nein} setze \texttt{standOn} auf \mintinline{java}{null}
\end{itemize}
\vfill
Dieses Werk ist lizenziert unter einer \href{https://creativecommons.org/licenses/by-sa/4.0/}{CC BY-SA 4.0} Lizenz \faCreativeCommons\ \faCreativeCommonsBy\ \faCreativeCommonsSa.
\end{document}
|