i

Teddy - das Spiel

Spielregeln

Die Spielidee zum Teddy-Spiel lautet folgendermaßen:

  • Der Spieler - ein kleines Baby - möchte alle Teddies fangen. Je schneller er alle Teddies fängt, desto mehr Punkte erhält er. Der Spieler kann mit den Pfeiltasten gesteuert werden.
  • Wenn der Spieler einen Teddy trifft, verliert der Teddy ein Leben. Ein Teddy hat fünf Leben.
  • Sollte der Teddy sich auf einem der klebrigen Flecken befinden, werden ihm sofort alle fünf Leben abgezogen.
  • Solange der Teddy noch Leben hat, springt er bei Berührung mit dem Spieler davon.
  • Ein gefangener Teddy ist für den Spieler zu Beginn des Spiels 100 Punkte wert, verliert aber mit jedem Ausführungsschritt des Spiels einen Punkt an Wert.
  • Der Spieler verliert mit jedem Ausführungsschritt des Spiels einen Punkt. Man sollte also auch schnell sein, wenn die Teddies keine Punkte mehr geben, da das Spiel erst beendet ist, wenn man alle Teddies gefangen hat.

Ein vollständiger Spielablauf könnte also z.B. folgendermaßen aussehen:

Vorlage zum Spiel

Einige Teile des Spiels sind schon fertig implementiert. Was noch fehlt, ist die die Implementierung der Teddy-Klasse.

Aufgabe 1 - Vorbereitungen

Lade das Projekt herunter, und entpacke es. Öffne das Projekt in Greenfoot dann durch Doppelklick auf die Datei "project.greenfoot". Starte das Spiel. Der Spieler lässt sich steuern und die Punkte laufen herunter. Mehr passiert noch nicht. Dazu musst Du erst die Teddy-Klasse mit Leben füllen.

Aufgabe 2 - Basis-Teddy

Die Klasse Teddy existiert schon, enthält aber noch kaum Funktionalität. Experimentiere mit den Teddies, indem Du rechts auf sie klickst und den Objektinspektor sowie verschiedene Methoden ausführst. Öffne den Quelltext der Klasse durch Doppelklick auf die Klasse (oder Rechtsklick → Editor öffnen). Erkläre anhand des Quellcodes welche Attribute und Methoden ein Teddy schon hat.

Modell eines Teddy

Im Folgenden müssen wir die Eigenschaften und Fähigkeiten eines Teddy-Bären im Computer implementieren. Wir müssen also ein Modell eines Teddy's für den Computer bilden. Ein Teddy kann Eigenschaften wie z.B. einen Preis, eine Stoffart, eine Marke etc. besitzen. In unserem Fall soll der Teddy aber einen grafischen Teddy für unser Spiel repräsentieren. Deshalb modellieren wir die Eigenschaften und Fähigkeiten, die für unser Spiel relevant sind.

Attribute

Unser Teddy soll ein Alter und die noch verbleibenden Leben als Attribute besitzen. Da er schon springen kann, hat das Klassendiagramm damit folgende Form:

Klassendiagramm mit Attributen

Während man in Klassendiagrammen der UML (Unified Modeling Language) den Datentyp üblicherweise durch Doppelpunkt hinter einer Variablen angibt, wird der Datentyp in Java bei der Definition einer Variablen vorangestellt. Anweisungen müssen in Java mit einem Semikolon abgeschlossen werden. Wir definieren ein Attribut in Java also folgendermaßen:

int alter;

Attribute werden üblicherweise oben in einer Klasse definiert. Eine einfache Teddy-Klasse hätte damit also folgende Form:

class Teddy {
   int alter;
}

Die weiteren Teile des Codes der Vorlage hängen in erster Linie damit zusammen, dass wir eine Unterklasse von Actor bilden wollen. Was das Wort public bedeutet, musst Du noch nicht verstehen. Im Wesentlichen erlauben wir damit den Zugriff auf eine Methode außerhalb der Klasse. Momentan schreiben wir es einfach am besten vor alle Methoden. Im nächsten Projekt wirst Du genauer lernen was public bedeutet.

Insgesamt sieht unsere Klasse nun folgendermaßen aus:

import greenfoot.*;

class Teddy extends Actor
{
    int leben;
    int alter;

    public void springen() {
        // ... Implementierung der Methode
    }
}

Aufgabe 3 - Attribute

Ergänze die Vorlage entsprechend. Teste, ob alles funktioniert hat, indem Du den Objektinspektor eines Teddy's aufrufst. Die Attribute leben und alter müssen hier erscheinen.

Wichtig: Du musst Dich bei den Aufgaben genau an die Namen der Variablen und Methoden halten, da diese an anderen Stelles des Projektes benutzt werden.

Compilieren

Greenfoot compiliert den Code automatisch, sobald Du eine Zeile wechselst. Das bedeutet Greenfoot übersetzt dann das Programm in eine für den Computer ausführbare Form. Enthält Dein Programm syntaktische Fehler werden diese rot unterstrichen. Syntaktische Fehler sind z.B. fehlende Klammern oder ein fehlendes Semikolon, also alle Fehler, die dafür sorgen, dass Dein Programm kein gültiges Java-Programm ist.

Aufgabe 4 - Syntaxfehler

Sorge z.B. durch ein fehlendes Semikolon dafür, dass Dein Programm nicht compilierbar ist und beobachte wie Greenfoot dies Dir anzeigt.

Konstruktoren

Beim Betrachten der Attribute im Objektinspektor ist Dir möglicherweise aufgefallen, dass die Attribute zwar vorhanden sind, aber noch keine sinnvollen Werte enthalten. Wir benötigen also eine Möglichkeit beim Erzeugen eines Objektes bestimmte Operationen, wie z.B. die Initialisierung der Attribute vorzunehmen. Diese Möglichkeit bieten einem Konstruktoren. Der Konstruktor einer Klasse wird immer dann aufgerufen, wenn ein neues Objekt der Klasse erzeugt werden soll. In Java heißt der Konstruktor immer genau so wie die Klasse selbst und kann - ähnlich wie Methoden - Parameter erhalten. Eine vereinfachte Teddy-Klasse könnte also so aussehen:

class Teddy {
    int leben;

    Teddy() {
        leben = 5;
    }
}

Man kann an diesem Beispiel auch sehen wie Zuweisungen funktionieren: Auf der rechten Seite muss ein Ausdruck stehen, der während der Ausführung des Programms einen bestimmten Wert besitzt. Im einfachsten Fall ist dies eine Konstante wie die Zahl 5. Hier wären auch komplexere Ausdrücke wie 5 + 3, leben * 2 oder (leben - 4) * (leben +5) möglich.

Auf der linken Seite muss eine Variable stehen, welche den Wert annehmen kann. Das Gleichheitszeichen ist also nicht als Gleichheitszeichen im mathematischen Sinne zu verstehen, sondern als: "Berechne den Wert auf der rechten Seite des Gleichheitszeichens und weise diesen Wert der Variablen auf der linken Seite zu."
import greenfoot.*;

class Teddy extends Actor
{
    int leben;
    int alter;

    Teddy() {
        leben = 5;
        alter = 0;
    }

    public void springen() {
        // ... Implementierung der Methode
    }
}

Aufgabe 5 - Konstruktor

Ergänze die Vorlage entsprechend. Teste, ob alles funktioniert hat, indem Du den Objektinspektor eines Teddy's aufrufst. Die Attribute sollten nun korrekt initialisiert sein. (Hinweis: alter müsste man im Konstruktor nicht unbedingt auf 0 setzen, da dies der Standardwert für Attribute vom Typ int ist. Es ist aber besserer Stil dies trotzdem zu tun, da man damit den gewünschten Wert explizit dokumentiert.)

Methoden

Das Alter eines Teddy's soll mit jedem Ausführungsschritt des Spiels erhöht werden. In Greenfoot gibt es eine besondere Methode, die automatisch für jedes Objekt ausgeführt wird: Die act-Methode. Diese besitzt keine Parameter und gibt keinen Wert zurück.

Methoden schreibt man üblicherweise unterhalb des Konstruktors auf. Die Anweisungen, die beim Ausführen einer Methode ausgeführt werden sollen, werden in geschweiften Klammern angegeben. Eine vereinfachte Teddy-Klasse könnte also folgende Form haben:

class Teddy {
    int leben;

    Teddy() {
        leben = 5;
    }
    
    void act() {
        // ... hier steht was beim Ausführen von act passieren soll ...
    }
}

Die act-Methode muss in unserem Fall als public definiert sein, womit unsere Klasse so aussieht:

import greenfoot.*;

class Teddy extends Actor
{
    int leben;
    int alter;

    Teddy() {
        leben = 5;
        alter = 0;
    }

    public void springen() {
        // ... Implementierung der Methode
    }

    public void act() {
        // ... hier soll das Alter um eins erhöht werden
    }
}

Aufgabe 6 - act

Ergänze die act-Methode. Ergänze innerhalb der Methode eine Anweisung, die das Alter um eins erhöht. Teste die Implementierung mit Hilfe des Objektinspektors und dem Act- bzw. Run-Button in Greenfoot in der folgenden Art:

Methoden mit Parametern

Damit der Teddy beim Treffen auf einen Kleberfleck oder den Spieler Leben verliert, müssen diese ihm Leben abziehen können. Wir benötigen also eine Methode verringereLeben, welche die noch verbleibenden Leben um einen bestimmten Betrag verringern. Zusammen mit den bisher implementierten Methoden ergibt sich folgendes Klassendiagramm:

Klassendiagramm mit verringereLeben

Da bisher keine der Methoden etwas zurück gibt, könnte man das Klassendiagramm auch folgendermaßen darstellen:

Methoden mit void

In der Praxis wählt man aber oft die obere Variante, auch wenn diese nicht ganz eindeutig ist, da nicht sicher ist, ob die Methode nichts zurück gibt, oder der Rückgabetyp im Klassendiagramm nur nicht dargestellt ist.

    public void verringereLeben(int betrag) {
        // ... leben um betrag verringern
    }

Aufgabe 7 - verringereLeben

Ergänze die Methode mit der entsprechenden Anweisung zum Verringern des Lebens-Attributes. Teste mit Hilfe des Objektinspektors (Dass leben negativ werden kann, ist für unser Spiel nicht störend):

Methoden mit Rückgabe

Schließlich soll der Teddy noch Methoden besitzen, um Informationen über den eigenen Wert zu liefern. Dieser wird für den Punktestand des Spielers benötigt. Der Wert ergibt sich aus 100 - alter. Da der Spieler nur positive Werte berücksichtigen möchte, benötigt der Teddy noch eine Methode hatWert, die zurückgibt, ob der Wert des Teddy's noch im positiven Bereich ist. Im Klassendiagramm ergibt sich folgendes Bild:

Klassendiagramm mit allen Methoden

Methoden geben einen Wert mit Hilfe des Schlüsselwortes return zurück. Sobald bei einer Methode eine return-Anweisung ausgeführt wird, wird die Methode beendet. In Java können die beiden Methoden dann folgendermaßen definiert werden:

    public int getWert() {
        return 100 - alter;
    }
    
    public boolean hatWert() {
        return getWert() > 0;
    }

Beachte, dass die Methode getWert innerhalb der Methode hatWert aufgerufen wird. Ein Objekt kann also eigene Methoden aufrufen.

Aufgabe 8 - Wert

Erkläre die Funktionsweise der beiden Methoden. Ergänze die Methoden und teste mit Hilfe des Objektinspektors und durch Methodenaufrufe.

Spiel fertig stellen

Die Teddy-Klasse ist nun fertig. Da die Spieler-Klasse und die Kleber-Klasse auf Funktionalität des Teddy zugreifen, dieser aber zu Beginn nicht fertig war, wurden dort Teile des Codes auskommentiert. Dies soll nun rückgangig gemacht werden.

Aufgabe 9 - Spiel fertig stellen

Öffne den Code der Klassen Spieler und Kleber. Entferne die beiden Schrägstriche, mit denen Kommentare eingeleitet werden. Tipp: Du kannst alle auskommentierten Zeilen markieren und über das Menü (Bearbeiten) oder über die Tasten F7 bzw. F8 Kommentare aus- oder einschalten.

Teste abschließend das Spiel. Das bedeutet: Spiele :-)

Suche

v
7.1.1.2.1
dev.inf-schule.de/oop/java/klassen/aufbau/teddy
dev.inf-schule.de/7.1.1.2.1
dev.inf-schule.de/@/page/0rLHOvR0Ot7XGmTu

Rückmeldung geben