\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}