From 14b65ba17ccda644817c678b025252eb22436857 Mon Sep 17 00:00:00 2001 From: Florian Fischer Date: Fri, 26 Apr 2024 16:50:05 +0200 Subject: add the third snake exercise and slides section --- Info/10/2/Snake/arbeitsauftrag2.tex | 39 ++++++---- Info/10/2/Snake/arbeitsauftrag3.tex | 45 +++++++++-- Info/10/2/Snake/slides.md | 149 +++++++++++++----------------------- 3 files changed, 117 insertions(+), 116 deletions(-) diff --git a/Info/10/2/Snake/arbeitsauftrag2.tex b/Info/10/2/Snake/arbeitsauftrag2.tex index f955181e..5c60b26e 100644 --- a/Info/10/2/Snake/arbeitsauftrag2.tex +++ b/Info/10/2/Snake/arbeitsauftrag2.tex @@ -4,6 +4,8 @@ \usepackage[ngerman]{babel} \geometry{margin=2cm} +\newcommand{\Snake}{\texttt{Snake}} + \title{Snake Arbeitsauftrag 2} \setcounter{section}{2} @@ -25,21 +27,21 @@ \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] +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} \begin{itemize} -\item Ergänze die Klasse \texttt{Snake} um eine \textit{Attribut} \texttt{ticks}, das die Anzahl der bereits gezeichneten Bilder speichert. -\item Importiere in der Klasse \texttt{Snake} die Java Klasse \texttt{Random}, indem du außerhalb deiner Klasse \texttt{Snake} die Zeile \mintinline{java}/import java.util.Random;/ einfügst. -\item Ergänze die Klasse \texttt{Snake} um ein \textit{Attribut} \texttt{zufall} vom Typ \texttt{Random}, initialisiere das \textit{Attribut} im \textit{Konstruktor}. -\item Ergänze die Methode \texttt{Snake.Ausführen}: +\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 \texttt{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}). + \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} @@ -47,7 +49,7 @@ Um Aktionen in Abhängigkeit von der Zeit auszuführen, müssen wir wissen wie v \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/ +\textbf{Beispiele}: \mintinline{java}{7 % 3 == 1; 64 % 30 == 4} \end{defbox} \newpage @@ -58,7 +60,7 @@ Damit unsere Schlange wachsen kann, muss sie aus mehr Körperteilen als nur dem \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)/: +\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ß). @@ -72,16 +74,25 @@ Damit unsere Schlange wachsen kann, muss sie aus mehr Körperteilen als nur dem \subsection{\faIcon{desktop} Bewegung der Schlange} \begin{defbox}{Bewegung mehrere Körperteile} -\begin{tabularx}{\textwidth}{X p{5cm}} -\vspace{-2.5cm} +\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. & +Dabei wird jedes Körperteil an die Position des Vorgängers gezogen. + +Du kannst ein Feld rückwärts durchlaufen, indem du die dir bereits bekannte \mintinline{java}{for} Schleife leicht modifizierst. + +\begin{minted}{java} +for (int i = feld.length -1; i >= 0; i--) { + ... +} +\end{minted} +& \includegraphics[keepaspectratio, width=5cm]{img/Copyrighted/caterpillar_movement.png} \\ -\end{tabularx} +\end{tabular} \end{defbox} \begin{itemize} -\item Beginnend mit dem letzten Körperteil setze die Position auf die des Körperteils davor in dem \texttt{koerper} Feld. +\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. \end{itemize} diff --git a/Info/10/2/Snake/arbeitsauftrag3.tex b/Info/10/2/Snake/arbeitsauftrag3.tex index 26a2a2ea..3de38106 100644 --- a/Info/10/2/Snake/arbeitsauftrag3.tex +++ b/Info/10/2/Snake/arbeitsauftrag3.tex @@ -4,6 +4,8 @@ \usepackage[ngerman]{babel} \geometry{margin=2cm} +\newcommand{\Snake}{\texttt{Snake}} + \title{Snake Arbeitsauftrag 3} \setcounter{section}{3} @@ -11,28 +13,57 @@ \thispagestyle{empty} \subsection{\faIcon{desktop} Kollisionserkennung} -\begin{itemize} -\item -\end{itemize} +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(GrafikSymbol)} 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 +\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}). +\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} Kollision mit dem Rand} +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 +\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 +\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} -\subsection{\faIcon{desktop} Bewegung der Schlange} \end{document} diff --git a/Info/10/2/Snake/slides.md b/Info/10/2/Snake/slides.md index 5aa5914e..451ed3c6 100644 --- a/Info/10/2/Snake/slides.md +++ b/Info/10/2/Snake/slides.md @@ -383,6 +383,24 @@ Berührt der Kopf das Essen? :::: ::: +## Wann frisst die Schlange das Essen + +### \faIcon{lightbulb} Wo findet die Überprüfung statt? +\pause +In der `Ausführen`-Methode der Welt-Klasse `Snake`, da + +>- dort Schlange und Essen bekannt sind +>- dort die Schlange bewegt wird + +\pause +### Pseudocode +``` +Schlange bewegen +Falls Kopf das Essen berührt + entferne Essen + Schlange wachse +``` + ## Kollision mit dem Rand der Welt ::: {.columns align=center} @@ -396,8 +414,29 @@ Ist die Position des Kopfes noch Teil der Welt? :::: ::: +## Kollision mit dem Rand der Welt + +### \faIcon{lightbulb} Wo findet die Überprüfung statt? +\pause +In der `bewegen`-Methode der Klasse `Schlange`, nachdem der Kopf bewegt wurde + +### \faIcon{lightbulb} Woher weiß das Spiel das die Schlange kollidiert ist? +\pause +Die Methode `bewegen` gibt einen Wahrheitswert zurück, ob sie erfolgreich war. + +\pause +### Pseudocode +``` +Koerper bewegen +Kopf bewegen +Falls kopf.x < 0 oder kopf.x > Weltbreite + oder kopf.y < 0 oder kopf.y > Welthöhe + return false +return true +``` ## Kollision mit sich selbst + ::: {.columns align=center} :::: {.column width=50%} \vspace{0.3cm} @@ -409,101 +448,21 @@ Berührt der Kopf der Schlange eins der eigenen Körperteile? :::: ::: +## Kollision mit sich selbst +### \faIcon{lightbulb} Wo findet die Überprüfung statt? +\pause +In der `bewegen`-Methode der Klasse `Schlange`, nachdem die Schlange bewegt wurde. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +\pause +### Pseudocode +``` +Koerper bewegen +Kopf bewegen +... - +Für jedes koerperteil hinter dem kopf + Falls kopf beruehrt koerperteil + return false - - - - - - - +return true +``` -- cgit v1.2.3