aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian Fischer <florian.fischer@muhq.space>2026-03-14 12:14:12 +0100
committerFlorian Fischer <florian.fischer@muhq.space>2026-03-14 12:14:58 +0100
commitfb2812be04f4be4368a255d5a883473879f885d6 (patch)
treeb5f9fc50fa7d1d2ed318794858fbf9f439d0deed
parent064b1ec7878818b04b4161dd9c877d76f4c30798 (diff)
downloadunterricht-fb2812be04f4be4368a255d5a883473879f885d6.tar.gz
unterricht-fb2812be04f4be4368a255d5a883473879f885d6.zip
add the second exercise sheet
-rw-r--r--Info/10/2/JumpNRun/arbeitsauftrag2.tex187
-rw-r--r--Info/10/2/JumpNRun/slides.md4
2 files changed, 126 insertions, 65 deletions
diff --git a/Info/10/2/JumpNRun/arbeitsauftrag2.tex b/Info/10/2/JumpNRun/arbeitsauftrag2.tex
index f886d958..abf8f818 100644
--- a/Info/10/2/JumpNRun/arbeitsauftrag2.tex
+++ b/Info/10/2/JumpNRun/arbeitsauftrag2.tex
@@ -5,99 +5,160 @@
\usepackage[ngerman]{babel}
\geometry{margin=2cm}
-\newcommand{\Snake}{\texttt{Snake}}
+\usetikzlibrary{calc, shapes.arrows}
-\title{Snake Arbeitsauftrag 2}
+\title{JumpNRun Arbeitsauftrag 2}
\setcounter{section}{2}
\begin{document}
\thispagestyle{empty}
-\subsection{\faIcon{desktop} Essen}
+\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 Erstelle eine neue Klasse \texttt{Essen}.
-\item Ergänze die Klasse Essen um ein \textit{Attribut} \texttt{symbol} vom Typ \texttt{Rechteck}/
-\item Implementiere den \textit{Konstruktor} der Klasse \texttt{Essen}:
- \begin{itemize}
- \item Es soll die Position übergeben werden.
- \item Initialisiere \texttt{symbol} mit einem neuen roten Rechteck an der richtigen Position mit der Größe 20x20.
- \end{itemize}
-\item Implementiere eine Methode \texttt{entferne()} der Klasse \texttt{Essen}, die das \texttt{symbol} mittels dessen Methode \texttt{Entfernen()} von der Zeichenfläche löscht.
-\item Teste deine Klasse \texttt{Essen}, indem du neue Objekte von ihr anlegst und wieder entfernst.
+ \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}
-
-\subsection{\faIcon{desktop} Zeitgesteuertes Essen}
-\begin{defbox}{Zeitgesteuerte Ereignisse}
-Die Methode \mintinline{java}{public void Ausführen()} unserer Spiel-Klasse wird für jedes neue Bild von der Spiel-Engine aufgerufen. \\[0.2cm]
-Um Aktionen in Abhängigkeit von der Zeit auszuführen, müssen wir wissen wie viel „\textit{Zeit}“ bereits vergangen ist.
\end{defbox}
+\\
+\end{tabular}
\begin{itemize}
-\item Ergänze die Klasse \Snake{} um eine \textit{Attribut} \texttt{ticks}, das die Anzahl der bereits gezeichneten Bilder speichert.
-\item Importiere in der Klasse \Snake{} die Java Klasse \texttt{Random}, indem du außerhalb deiner Klasse \Snake{} die Zeile \mintinline{java}{import java.util.Random;} einfügst.
-\item Ergänze die Klasse \Snake{} um ein \textit{Attribut} \texttt{zufall} vom Typ \texttt{Random}, initialisiere das \textit{Attribut} im \textit{Konstruktor}.
-\item Ergänze die Methode \mintinline{java}{Snake.Ausführen}:
- \begin{itemize}
- \item Erhöhe zu Beginn die Anzahl der bereits gezeichneten Bilder.
- \item Falls das aktuelle Bild ein Vielfaches von 30 ist:
- \begin{itemize}
- \item Falls ein Essen in dem \textit{Attribut} \texttt{essen} der Klasse \Snake{} gespeichert ist, entferne es.
- \item Erzeuge eine neues \texttt{Essen}-Objekt an einer zufälligen Position (\mintinline{java}{zufall.nextInt(max)} liefert dir eine Zufallszahl zwischen 0 und \texttt{max}).
- \end{itemize}
-
- \end{itemize}
-\end{itemize}
-
-\begin{defbox}{Modulo}
-Die \boldred{Modulo-Operation}, in Java das Zeichen \texttt{\%}, liefert als Ergebnis, den Rest der Ganzzahldivision zweier Zahlen. \\[0.1cm]
-\textbf{Beispiele}: \mintinline{java}{7 % 3 == 1; 64 % 30 == 4}
-\end{defbox}
+\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.
+\item Die Methode \mintinline{java}{Level next()} soll nichts zurückgeben, da es kein zweites Level gibt (\mintinline{java}{return null}).
+\item Implementiere die Methode \mintinline{java}{void spawnPlayer(Player player)} und setzte das \texttt{player} Objekt an eine geeignete Startposition (\texttt{100, 400}).
+\end{itemize}
-\newpage
-\subsection{\faIcon{desktop} Wachstum}
+\subsection{\faIcon{desktop} Spielstart}
-Damit unsere Schlange wachsen kann, muss sie aus mehr Körperteilen als nur dem Kopf bestehen.
+Vervollständige den Konstruktor der Klasse \texttt{JumpNRun}.
\begin{itemize}
-\item Ersetze das \textit{Attribut} Kopf der Schlange durch ein Feld namens \texttt{koerper} vom Typ \texttt{Rechteck}.
-\item Initialisiere das Feld im \textit{Konstruktor} der Klasse \texttt{Schlange} mit Länge 0.
-\item Ergänze die Klasse \texttt{Schlange} um die Methode \mintinline{java}{wachsen(int x, int y)}:
- \begin{itemize}
- \item Erzeuge ein neues Feld, das um ein Element länger ist als der aktuelle Körper der Schlange.
- \item Erzeuge einen neuen Kopf an der richtigen Position (grün und 20x20 Pixel groß).
- \item Speichere den neuen Kopf als erstes Element in dem neu erzeugten Feld.
- \item Kopiere alle Elemente des aktuellen Körpers in das neue Feld. \\
- \textbf{Vergiss nicht}: Das neue Feld enthält bereits den Kopf am Index 0.
- \item Speichere das neue Feld in dem \textit{Attribut} \texttt{koerper}.
- \end{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} Bewegung der Schlange}
+\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}
-\begin{defbox}{Bewegung mehrere Körperteile}
-\begin{tabular}{p{0.65\textwidth} p{5cm}}
-\vspace{-3.5cm}
-Es bietet sich an bei der Bewegung der Schlange die Bewegung der Raupen in der Natur nachzuahmen.
-Dabei wird jedes Körperteil an die Position des Vorgängers gezogen.
+Die Methode \mintinline{java}{getCollidingShapes(Group g)} eines Sprites gibt alle Objekte einer Gruppe \texttt{g} zurück, die mit dem \texttt{Sprite} kollidieren.
-Du kannst ein Feld rückwärts durchlaufen, indem du die dir bereits bekannte \mintinline{java}{for} Schleife leicht modifizierst.
+Mit der \texttt{foreach}-Variante der \texttt{for}-Schleife können wir alle Kollisionen behandeln.
\begin{minted}{java}
-for (int i = feld.length -1; i >= 0; i--) {
- ...
+// 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}
+
+\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}
&
-\includegraphics[keepaspectratio, width=5cm]{img/Copyrighted/caterpillar_movement.png} \\
+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 Beginnend mit dem letzten Körperteil setze die Position auf die des Körperteils davor.
-\item Verschiebe anschließend den Kopf wie gewohnt in die aktuelle Richtung.
-\item Teste deine Methoden \texttt{bewegen} und \texttt{wachsen}, indem du alle 40 Bilder die Schlange in die aktuelle Richtung wachsen lässt.
+\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} Auf dem Boden stehen}
+
+Bei Kollision \textbf{von oben} wollen wir erkennen, das wir auf festem Boden stehen!
+Das erlaubt uns 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 Gravitation zu einer Prüfung \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}
+
+
diff --git a/Info/10/2/JumpNRun/slides.md b/Info/10/2/JumpNRun/slides.md
index 16c4d61c..7217a6b7 100644
--- a/Info/10/2/JumpNRun/slides.md
+++ b/Info/10/2/JumpNRun/slides.md
@@ -494,7 +494,7 @@ Die Online-IDE bietet die Klasse `Group` zur Verwaltung mehrer graphischer Objek
Vervollständige den Konstruktor der Klasse `JumpNRun`.
\let\tightlist\relax
-* Erzeuge in `Level1` Objekt und initialisiere damit das `Level` Attribut der Klasse `JumpNRun`.
+* Erzeuge ein `Level1` Objekt und initialisiere damit das `Level` Attribut der Klasse `JumpNRun`.
* Rufe die `spawnPlayer`-Methode des ersten Levels mit dem `Player` Attribute der Klasse `JumpNRun` auf.
\faIcon{play} Teste deine Implementierung.
@@ -572,7 +572,7 @@ Implementiere `void reactToCollisionWithShape(Shape shape)`{.java} im Spieler:
Das Attribut `Shape standsOn`{.java} der Klasse `Player` merkt sich auf welchem Shape der Spieler steht.
* (Ergänze das `standsOn` Attribut vom Typ `Shape` in der Klasse `Player`)
-* (Ändere die Gravitation zu einer Prüfung `standsOn == null`)
+* (Ändere die Gravitation zu einer Prüfung `standsOn == null`{.java})
* Bei Kollision von \emph{oben}, speichere das kollidierende `shape` im Attribut `standsOn`.
* Überprüfe vor der Kollisionserkennung, ob der Spieler noch mit einem möglicherweise gespeicherten `standsOn` Objekt kollidiert. (`standOn != null && !collidesWith(standsOn)`{.java})
* \emph{Falls nein} setze `standOn` auf `null`{.java}