Eigene Sprites
Jetzt kommt alles zusammen. Sprite ist eine Klasse aus der Bibliothek – und du kannst von ihr erben, genau wie Lehrer von Person. Damit baust du dir eigene Figuren mit eigenem Verhalten.
Eine Figur mit eigenem Verhalten
Klicke in den Ausgabebereich und steuere den Hasen mit den Pfeiltasten.
a) Welche Methoden hat Hase selbst, welche sind geerbt?
b) Was passiert, wenn du run() löschst? Sage es voraus und probiere es aus.
Auflösung
a) Selbst geschrieben sind nur der Konstruktor und run(). Alles andere – addCostume, setPosition, changeX, isKeyPressed, ifOnEdgeBounce – ist von Sprite geerbt.
Das ist genau der Vorteil, den du bei Person und Lehrer gesehen hast: Der ganze gemeinsame Teil steht schon in der Oberklasse.
b) Der Hase erscheint, bewegt sich aber nicht mehr. run() ist in Sprite bereits vorhanden – dort tut sie nichts. Deine Fassung überschreibt sie.
| Methode | wann wird sie aufgerufen |
|---|---|
| Konstruktor | einmal, beim Erzeugen |
run() |
in jedem Bild, etwa 60-mal pro Sekunde |
whenKeyPressed(KeyCode k) |
einmal beim Drücken einer Taste |
whenClicked() |
beim Anklicken der Figur |
run() überschreibst du für Dauerverhalten (Bewegung, Prüfungen). Für einmalige Reaktionen nimmst du die when-Methoden.
Mehrere Figuren derselben Klasse
Acht Objekte, eine Klasse – und jedes verhält sich anders.
a) Erkläre, warum sich die Münzen unterschiedlich schnell drehen, obwohl sie alle dieselbe run()-Methode ausführen.
b) Was müsstest du ändern, damit sich alle gleich schnell drehen?
Auflösung
a) Weil drehrichtung ein Attribut ist. Jedes Münzobjekt hat einen eigenen Wert dafür, gesetzt im Konstruktor. Die Methode ist dieselbe – die Daten, mit denen sie arbeitet, sind es nicht.
Das ist derselbe Punkt wie bei den beiden Autos in Lektion 1, jetzt nur sichtbar in Bewegung.
b) Statt drehrichtung würde man direkt eine feste Zahl schreiben – oder den Wert nicht mehr zufällig setzen.
Vererbung in der Grafik
Jetzt bauen wir eine echte Hierarchie: Gegenstände, die eingesammelt werden können.
classDiagram
class Sammelbar {
#int punktwert
+Sammelbar(int pX, int pY, int pPunktwert)
+int getPunktwert()
+void run()
}
class Muenze {
+Muenze(int pX, int pY)
}
class Edelstein {
+Edelstein(int pX, int pY)
}
Sprite <|-- Sammelbar
Sammelbar <|-- Muenze
Sammelbar <|-- Edelstein
Beachte, wie wenig in Muenze und Edelstein steht: nur das Kostüm, der Punktwert und gegebenenfalls die Größe. Position, Punktwert-Verwaltung und Schwebeverhalten stehen einmal in Sammelbar.
Soll das Schweben schneller werden, änderst du eine Methode in einer Klasse – und beide Gegenstandsarten ziehen mit.
Aufgabe 1: Ein Sammelspiel
Baue aus den Bausteinen ein kleines Spiel:
- Eine steuerbare Figur (wie der Hase oben).
- Mehrere Sammelgegenstände auf der Bühne.
- Berührt die Figur einen Gegenstand, verschwindet er und die Punktzahl steigt um seinen Punktwert.
- Die Punktzahl wird auf der Bühne angezeigt.
Tipp 1: Berührung erkennen
this.getTouchingSprite(Sammelbar.class) liefert den berührten Gegenstand – oder null, wenn keiner berührt wird.
Der Zusatz .class bedeutet: „ein Objekt von dieser Art“. Weil Muenze und Edelstein beide Sammelbar sind, findet dieser eine Aufruf beide Sorten.
Tipp 2: Einsammeln
Sammelbar gefunden = this.getTouchingSprite(Sammelbar.class);
if (gefunden != null) {
// Punkte melden und den Gegenstand entfernen
}
Zum Melden brauchst du die Bühne: Buehne b = (Buehne) this.getStage(); – die Umwandlung ist nötig, weil getStage() allgemein eine Stage liefert.
Zum Entfernen gibt es gefunden.remove().
Zusatzaufgabe
Erweitere das Spiel:
a) Ergänze eine dritte Sorte Sammelgegenstand – etwa einen Schlüssel (keyGreen), der 100 Punkte bringt. Wie viel Code musst du dafür schreiben?
b) Ergänze eine Klasse Gegner, die sich von allein bewegt und bei Berührung Punkte abzieht.
c) Beende das Spiel, wenn alle Gegenstände eingesammelt sind. Mit this.find(Sammelbar.class) bekommst du eine Liste aller noch vorhandenen Gegenstände.