aboutsummaryrefslogtreecommitdiff
path: root/Info/10
diff options
context:
space:
mode:
authorFlorian Fischer <florian.fischer@muhq.space>2026-04-13 21:25:29 +0200
committerFlorian Fischer <florian.fischer@muhq.space>2026-04-13 21:25:29 +0200
commit68745ae09ec4a9583a9c48b84137207c61731249 (patch)
tree8af3231dd706ee185cc2e6f712f1fe158361446d /Info/10
parent95ef32c5a7ddd5dd7aa93a1444bfc16da1eb676c (diff)
downloadunterricht-68745ae09ec4a9583a9c48b84137207c61731249.tar.gz
unterricht-68745ae09ec4a9583a9c48b84137207c61731249.zip
add rough draft of the last part of the jumpnrun
Diffstat (limited to 'Info/10')
-rw-r--r--Info/10/2/JumpNRun/arbeitsauftrag3.tex134
-rw-r--r--Info/10/2/JumpNRun/slides.md147
2 files changed, 239 insertions, 42 deletions
diff --git a/Info/10/2/JumpNRun/arbeitsauftrag3.tex b/Info/10/2/JumpNRun/arbeitsauftrag3.tex
index 936d4b71..6ad4311a 100644
--- a/Info/10/2/JumpNRun/arbeitsauftrag3.tex
+++ b/Info/10/2/JumpNRun/arbeitsauftrag3.tex
@@ -5,69 +5,119 @@
\usepackage[ngerman]{babel}
\geometry{margin=2cm}
-\newcommand{\Snake}{\texttt{Snake}}
-
-\title{Snake Arbeitsauftrag 3}
+\title{JumpNRun Arbeitsauftrag 3}
\setcounter{section}{3}
\begin{document}
\thispagestyle{empty}
-\subsection{\faIcon{desktop} Kollisionserkennung}
-Damit unsere \textit{Snake}-Variante tatsächlich zu einem echten Spiel wird, müssen wir gewissen Ereignisse erkennen und behandeln.
-
-\subsubsection{\faIcon{desktop} Kollision mit dem Essen}
-
-Wenn der Kopf der Schlange das Essen berührt, soll das Essen verschwinden und die Schlange soll wachsen.
-\begin{defbox}{Kollision}
-\begin{tabular}{p{0.75\textwidth} p{0.5cm} p{0.2\textwidth}}
-\vspace{-1.8cm}
-Von einer Kollision spricht man, wenn zwei Objekte sich \textbf{überschneiden}.
-Eine solche Überschneidung zu erkennen kann je nach Form der Objekte kompliziert sein.
-Unsere Spieleengine \textit{GraphicAndGames} bietet dazu die Methode \mintinline{java}{GrafikSymbol.Schneidet(Area)} an. & &
-\begin{tikzpicture}
-\node[draw, opacity=0.7, minimum size=1.5cm, fill=red] {};
-\node[circle, draw, minimum size=1cm, fill=blue] at (0.5, 0.5) {};
-\end{tikzpicture} \\
-\end{tabular}
-\end{defbox}
+\subsection{Interaktive Objekte}
-\begin{itemize}
-\item Implementiere eine Methode \mintinline{java}{beruehrt(Rechteck)} in der Klasse \texttt{Schlange}, die überprüft, ob der Kopf der Schlange ein anderes Rechteck schneidet (das \texttt{GrafikSymbol} der Klasse \texttt{Rechteck} ist dessen Attribut \texttt{symbol}, jedes \texttt{GrafikSymbol} hat wiederum ein Attribut \texttt{form} vom Typ \texttt{Area}).
-\item Ergänze die Methode \texttt{Ausführen} der Klasse \Snake{} um die Überprüfung, ob die Schlange das Essen berührt. Falls ja, entferne das Essen und rufe die \texttt{wachsen}-Methode der Schlange mit den Koordinaten des Essens auf.
-\end{itemize}
+\subsubsection{\faIcon{desktop} Interaktive Objekte verwalten}
-\subsubsection{\faIcon{desktop} Kollision mit dem Rand}
+\begin{itemize}
+\item Implementiere in einer neuen Datei das Interface \texttt{InteractiveElement}:
+\begin{minted}{java}
+interface InteractiveElement {
+ void onCollisionWithPlayer(Player player, JumpNRun jumpNRun);
+}
+\end{minted}
+\item Ergänze die Klasse \texttt{Level} um das Attribut \texttt{interactiveObjects}, das die *Gruppe* aller interaktiver Objekte speichern soll.
+\item Zerstöre auch alle interaktiven Objekte, wenn das gesamte Level zerstört wird.
+ (\textbf{Tipp:} \mintinline{java}|Level.destroy() { ... }|)
+\end{itemize}
-Da es sich bei dem Rand der Welt nicht um ein Objekt handelt, können wir nicht auf die \texttt{beruehrt}-Methode der Klasse \texttt{Schlange} zurückgreifen.
+\subsubsection{\faIcon{desktop} Mit Interaktive Objekte interagieren}
\begin{itemize}
-\item Ändere die Methode \texttt{bewegen} der Klasse \texttt{Schlange}, sodass sie als Rückgabewert immer \mintinline{java}{true} liefert.
-\item Erweitere die Methode \texttt{bewegen} der Klasse \texttt{Schlange} um eine Überprüfung, ob der die Koordinaten des Kopfes außerhalb der Welt liegen (die Welt ist \textbf{800x600} Pixel groß). Falls der Kopf außerhalb der Welt liegt, soll \mintinline{java}{false} zurückgegeben werden.
-\end{itemize}
-
-\subsubsection{\faIcon{desktop} Kollision mit sich selbst}
-Erweitere die Methode \texttt{bewegen} der Klasse \texttt{Schlange} um eine Überprüfung, ob der Kopf der Schlange eines der im folgenden Körperteile berührt (dazu kannst du auf die Methode \texttt{beruehrt} zurückgreifen). Falls ja, soll \mintinline{java}{false} zurückgegeben werden.
+ \item Ergänze die Methode \texttt{act} der Klasse \texttt{Player}, um die Kollisionserkennung mit allen interaktiven Objekten eines Levels. \\
+ (Tipp: Du kannst viel von der Kollisionserkennung der \texttt{solidObjekts} kopieren.)
+ \item Rufe für jedes kollidierende interaktive Objekt die Methode \texttt{onCollisionWithPlayer} mit dem Player Objekt (\mintinline{java}{this}) und dem gesamten \texttt{jumpNRun} Spiel-Objekts auf.
+\end{itemize}
-\subsection{\faIcon{desktop} Spielende}
-Nachdem die Methode \texttt{bewegen} eine Kollision festgestellt hat (Rückgabewert \mintinline{java}{false}) soll das Spiel beendet werden.
+\subsubsection{\faIcon{desktop} Ziel in Sicht}
\begin{itemize}
-\item Implementiere eine Methode \texttt{gameOver} der Klasse \Snake{}, die das Spiel mittels der Methode \mintinline{java}{Zeichenfenster.TaktgeberStoppen();} anhält.
-\item Erweitere die Methode \texttt{gameOver} um die Ausgabe einer Nachricht. Die Klasse \texttt{Text} erlaubt es dir Text auf dem Zeichenfenster anzuzeigen.
+\item Implementiere die Klasse \texttt{Goal} die von der Klasse \texttt{Sprite} \emph{erbt} und das Interface \texttt{InteraktiveElement} \emph{implementiert}.
+ (\mintinline{java}{implements InteractiveElement})
+\item Implementiere den Konstruktor der Klasse \texttt{Goal}.
+\begin{itemize}
+ \item Wähle das Sprite $160$ aus der Sprite-Bibliothek \texttt{SpriteLibrary.Plattforms} aus. \\
+ (\mintinline{java}{super(x, y, SpriteLibrary.Plattforms, 160);})
+ \item Mit der Anweisung \mintinline{java}{playAnimation(160, 161, RepeatType.loop, 3);} lässt du die Flagge im "Wind" wehen.
+\end{itemize}
+\item Implementiere die Methode \texttt{onCollisionWithPlayer} der Klasse \texttt{Goal} die zum nächsten Level weiter schaltet. \\
+ (\textbf{Tipp:} Implementiere die Methode \mintinline{java}{JumpNRun.nextLevel(Level level)} und rufe sie mit dem Nachfolger des aktuellen Levels auf)
\end{itemize}
-\subsection{\faIcon{desktop} Für Schnelle}
-Es fehlt unserem Spiel an einigen Ecken noch an Feinschliff.
+\subsection{\faIcon{desktop} Baue dein eigenes Spiel}
+Verändere das nun fertige Grundspiel nach deinen Vorstellungen.
+
+\begin{tcolorbox}[]
\begin{itemize}
-\item Sorge dafür das Essen nur auf gerader Linie der Schlange erscheint (Ein Vielfaches der Seitenlänge des Rechtecks).
-\item Ergänze das Spiel um einen Highscore (du kannst bspw. das Attribut \texttt{ticks} wiederverwenden).
-\item Implementiere, dass die Geschwindigkeit des Spiels zunimmt. Du kannst die Taktfrequenz, in der die \texttt{Ausführen}-Methode aufgerufen wird, mit der Methode \mintinline{java}{Zeichenfenster.TaktdauerSetzen(ms);} ändern.
+ \item Ergänze eine Stopuhr pro Level.
+ \item Füge sich bewegende Hindernisse/Gegner hinzu.
+ \item Ergänze Powerups die eingesammelt werden müssen.
+ \item Erweitere das Spiel um einen zweiten Spieler.
+ \item ...
\end{itemize}
+\end{tcolorbox}
+
\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}
+% Damit unsere \textit{Snake}-Variante tatsächlich zu einem echten Spiel wird, müssen wir gewissen Ereignisse erkennen und behandeln.
+
+% \subsubsection{\faIcon{desktop} Interaktive Objekte verwalten}
+
+% Wenn der Kopf der Schlange das Essen berührt, soll das Essen verschwinden und die Schlange soll wachsen.
+% \begin{defbox}{Kollision}
+% \begin{tabular}{p{0.75\textwidth} p{0.5cm} p{0.2\textwidth}}
+% \vspace{-1.8cm}
+% Von einer Kollision spricht man, wenn zwei Objekte sich \textbf{überschneiden}.
+% Eine solche Überschneidung zu erkennen kann je nach Form der Objekte kompliziert sein.
+% Unsere Spieleengine \textit{GraphicAndGames} bietet dazu die Methode \mintinline{java}{GrafikSymbol.Schneidet(Area)} an. & &
+% \begin{tikzpicture}
+% \node[draw, opacity=0.7, minimum size=1.5cm, fill=red] {};
+% \node[circle, draw, minimum size=1cm, fill=blue] at (0.5, 0.5) {};
+% \end{tikzpicture} \\
+% \end{tabular}
+% \end{defbox}
+
+% \begin{itemize}
+% \item Implementiere eine Methode \mintinline{java}{beruehrt(Rechteck)} in der Klasse \texttt{Schlange}, die überprüft, ob der Kopf der Schlange ein anderes Rechteck schneidet (das \texttt{GrafikSymbol} der Klasse \texttt{Rechteck} ist dessen Attribut \texttt{symbol}, jedes \texttt{GrafikSymbol} hat wiederum ein Attribut \texttt{form} vom Typ \texttt{Area}).
+% \item Ergänze die Methode \texttt{Ausführen} der Klasse \Snake{} um die Überprüfung, ob die Schlange das Essen berührt. Falls ja, entferne das Essen und rufe die \texttt{wachsen}-Methode der Schlange mit den Koordinaten des Essens auf.
+% \end{itemize}
+
+% \subsubsection{\faIcon{desktop} Mit Interaktive Objekte interagieren}
+
+% Da es sich bei dem Rand der Welt nicht um ein Objekt handelt, können wir nicht auf die \texttt{beruehrt}-Methode der Klasse \texttt{Schlange} zurückgreifen.
+
+% \begin{itemize}
+% \item Ändere die Methode \texttt{bewegen} der Klasse \texttt{Schlange}, sodass sie als Rückgabewert immer \mintinline{java}{true} liefert.
+% \item Erweitere die Methode \texttt{bewegen} der Klasse \texttt{Schlange} um eine Überprüfung, ob der die Koordinaten des Kopfes außerhalb der Welt liegen (die Welt ist \textbf{800x600} Pixel groß). Falls der Kopf außerhalb der Welt liegt, soll \mintinline{java}{false} zurückgegeben werden.
+% \end{itemize}
+
+% \subsubsection{\faIcon{desktop} Kollision mit sich selbst}
+% Erweitere die Methode \texttt{bewegen} der Klasse \texttt{Schlange} um eine Überprüfung, ob der Kopf der Schlange eines der im folgenden Körperteile berührt (dazu kannst du auf die Methode \texttt{beruehrt} zurückgreifen). Falls ja, soll \mintinline{java}{false} zurückgegeben werden.
+
+% \subsection{\faIcon{desktop} Spielende}
+% Nachdem die Methode \texttt{bewegen} eine Kollision festgestellt hat (Rückgabewert \mintinline{java}{false}) soll das Spiel beendet werden.
+
+% \begin{itemize}
+% \item Implementiere eine Methode \texttt{gameOver} der Klasse \Snake{}, die das Spiel mittels der Methode \mintinline{java}{Zeichenfenster.TaktgeberStoppen();} anhält.
+% \item Erweitere die Methode \texttt{gameOver} um die Ausgabe einer Nachricht. Die Klasse \texttt{Text} erlaubt es dir Text auf dem Zeichenfenster anzuzeigen.
+% \end{itemize}
+
+% \subsection{\faIcon{desktop} Für Schnelle}
+% Es fehlt unserem Spiel an einigen Ecken noch an Feinschliff.
+
+% \begin{itemize}
+% \item Sorge dafür das Essen nur auf gerader Linie der Schlange erscheint (Ein Vielfaches der Seitenlänge des Rechtecks).
+% \item Ergänze das Spiel um einen Highscore (du kannst bspw. das Attribut \texttt{ticks} wiederverwenden).
+% \item Implementiere, dass die Geschwindigkeit des Spiels zunimmt. Du kannst die Taktfrequenz, in der die \texttt{Ausführen}-Methode aufgerufen wird, mit der Methode \mintinline{java}{Zeichenfenster.TaktdauerSetzen(ms);} ändern.
+% \end{itemize}
diff --git a/Info/10/2/JumpNRun/slides.md b/Info/10/2/JumpNRun/slides.md
index bff23279..c4191131 100644
--- a/Info/10/2/JumpNRun/slides.md
+++ b/Info/10/2/JumpNRun/slides.md
@@ -577,4 +577,151 @@ Das Attribut `Shape standsOn`{.java} der Klasse `Player` merkt sich auf welchem
## {.standout}
+Wir wollen, dass etwas passiert!
+
+## Erinnerung: Interaktive Elemente
+
+Neben mehrere feste Plattformen soll ein Level auch **interaktive Elemente** enthalten.
+
+::: {.columns}
+:::: {.column width=50%}
+\begin{center}
+\begin{tikzpicture}
+ \begin{class}[text width=4cm]{InteraktivesObjekt}{0,-3.5}
+ \attribute{?}
+ \attribute{?}
+ \operation{onCollision(player)}
+ \end{class}
+
+ \begin{class}[text width=4cm]{Level}{0,0}
+ \attribute{festeObjekte}
+ \attribute{\textcolor{red}{interaktiveObjekte}}
+ \end{class}
+ \association{Plattform}{n}{}{Level}{enthält}{1};
+\end{tikzpicture}
+\end{center}
+::::
+
+:::: {.column width=50%}
+![](img/jumpnrun.png)
+::::
+:::
+
+## Mehrere Klassen mit den gleichen Methoden?
+Wir müssen sicherstellen, dass alle Objekte mit dem Player interagieren können.
+
+\begin{tcolorbox}[colframe=yellow, colback=yellow!20, title=\textcolor{black}{\faIcon{lightbulb} Idee(n)}]
+\begin{itemize}
+ \item<2-> Gemeinsmane Oberklasse
+ \item<3-> \boldred{Interface}
+\end{itemize}
+\end{tcolorbox}
+
+::: {.columns}
+:::: {.column width=70%}
+\pause\pause\pause
+\vspace{0.1cm}
+Ein neues \boldred{Interface}:
+```java
+interface InteractiveElement {
+ void onCollisionWithPlayer(Player player,
+ JumpNRun jumpNRun);
+}
+```
+::::
+
+:::: {.column width=30%}
+\only<4->{
+\begin{tikzpicture}
+\node[fill=magenta!20, line width=1pt, draw, minimum height=1cm, minimum width=3cm, rounded corners=5pt] (v) {Interakt. Objekt};
+\node[fill=bg, minimum height=1cm, minimum width=3cm, rounded corners=5pt, above=-0.1cm of v] (e) {Player};
+\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) {Player};
+
+\node[rotate=90] at ($(v.north west) - (0.3cm, 0.0cm)$) {\boldred{interface}};
+\end{tikzpicture}
+}
+
+::::
+:::
+
+## \faIcon{desktop} Arbeitsauftrag: Interaktive Objekte verwalten \hfill{} 10min
+
+\let\tightlist\relax
+* Implementiere in einer neuen Datei das Interface `InteractiveElement`:
+ ```java
+ interface InteractiveElement {
+ void onCollisionWithPlayer(Player player, JumpNRun jumpNRun);
+ }
+ ```
+* Ergänze die Klasse `Level` um das Attribut `interactiveObjects`, das die *Gruppe* aller interaktiver Objekte speichern soll.
+* Zerstöre auch alle interaktiven Objekte, wenn das gesamte Level zerstört wird.
+ (**Tipp:** `Level.destroy() { ... }`{.java})
+
+## \faIcon{desktop} Arbeitsauftrag: Mit interaktiven Objekte interagieren \hfill{} 10min
+
+Damit etwas passiert, wenn der Spieler ein interaktives Objekt berührt, wollen wir `onCollisionWithPlayer(Player, JumpNRun)`{.java} bei einer Kollision aufrufen.
+
+:::{.block}
+### Interaktions Beispiele {.example}
+
+* Flagge wird berührt -> Level wechseln
+* Gegner wird berührt -> Leben verlieren
+* ...<M-Escape>
+:::
+
+* Ergänze die Methode `act` der Klasse `Player`, um die Kollisionserkennung mit allen interaktiven Objekten eines Levels.
+ (Tipp: Du kannst viel von der Kollisionserkennung der `solidObjekts` kopieren.)
+* Rufe für jedes kollidierende interaktive Objekt die Methode `onCollisionWithPlayer` mit dem Player Objekt (`this`{.java}) und dem gesamten `jumpNRun` Spiel-Objekts auf.
+
+## \faIcon{desktop} Arbeitsauftrag: Ziel in Sicht \hfill{} 10min
+
+\let\tightlist\relax
+* Implementiere die Klasse `Goal` die von der Klasse `Sprite` *erbt* und das Interface `InteraktiveElement` *implementiert*.
+ (`implements InteractiveElement`{.java})
+* Implementiere den Konstruktor der Klasse `Goal`.
+ * Wähle das Sprite *160* aus der Sprite-Bibliothek `SpriteLibrary.Plattforms` aus.
+ (`super(x, y, SpriteLibrary.Plattforms, 160);`{.java})
+ * Mit der Anweisung `playAnimation(160, 161, RepeatType.loop, 3);`{.java} lässt du die Flagge im "Wind" wehen.
+* Implementiere die Methode `onCollisionWithPlayer` der Klasse `Goal` die zum nächsten Level weiter schaltet.
+ (**Tipp:** Implementiere die Methode `JumpNRun.nextLevel(Level level)` und rufe sie mit dem Nachfolger des aktuellen Levels auf)
+
+## \faIcon{desktop} Arbeitsauftrag: Baue dein eigenes Spiel
+
+Verändere das nun fertige Grundspiel nach deinen Vorstellungen.
+
+### Vorschläge {.example}
+* Ergänze eine Stopuhr pro Level.
+* Füge sich bewegende Hindernisse/Gegner hinzu.
+* Ergänze Powerups die eingesammelt werden müssen.
+* Erweitere das Spiel um einen zweiten Spieler.
+* ...
+
+
+## {.standout}
+
Dieses Werk ist lizenziert unter einer [CC BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/) Lizenz \faCreativeCommons\ \faCreativeCommonsBy\ \faCreativeCommonsSa.