Inhaltsverzeichnis
Rollenspiel
Für ein einfaches Rollenspiel sollen Objekte der Klasse Krieger und Magier erstellt werden. Die Objekte sollen sich sowohl durch ihre Eigenschaften (Attribute), als auch durch ihre Fähigkeiten (Methoden) unterscheiden. Ziel ist es ein Modell zu entwickeln, das es den Charakteren ermöglicht sich in einer umgebenden Welt zu bewegen und zu interagieren (zaubern, angreifen, verteidigen).
Das Modell wird zunächst ohne grafische Elemente in BlueJ entwickelt. Dabei werden die grundlegenden Elemente der objektorientierten Programmierung vermittelt: Die folgenden Elemente der Informatik werden am konkreten Beispiel eingeführt und sofort praktisch eingesetzt: Behältervariable, Attribut, Attributwert, Variable, Zuweisung, Vergleich, Fallunterscheidung, Konstruktor, Parameter, Vererbung, Polymorphie, Referenzvariable und Schleifen.
Die Klassen können später in die Entwicklungsumgebung Greenfoot übernommen werden um dem Spiel grafische Elemente und eine umgebende Welt hinzuzufügen.
Projektbeschreibung
Für ein Rollenspiel sollen Objekte der Klasse Krieger und Magier erstellt werden.
- Alle Charaktere besitzen Lebensenergie (Gesundheit oder Ausdauer) als Attribut.
- Alle Charaktere haben einen Namen.
- Jeder Charakter kann einen Nahkampfangriff ausführen.
- Jeder Charakter kann Schaden an der Gesundheit nehmen.
- Der Zustand aller Charaktere ist tot oder lebendig.
- Der Krieger besitzt zusätzlich Wut.
- Der Krieger besitzt eine Methode berserker(), die seine Wut erhöht.
- Der Krieger kann nur dann angreifen, wenn er genügend Wut hat. Er erhält Wut entweder dadurch dass er Schaden nimmt oder alternativ durch den Aufruf der berserker-Methode.
- Der Magier besitzt zusätzlich Zauberenergie (Mana).
- Der Magier kann heilen und einen Feuerball zaubern.
- Heilen und Feuerball kosten Mana.
- Heilen erhöht die Ausdauer.
- Die Attributwerte Gesundheit, Mana und Wut besitzen Maximalwerte. Sie sind also nach oben hin begrenzt.
Aufgaben
Aufgabe 1 (Attribute und grundlegende Methoden)
- Erstelle die Klassen MAGIER und KRIEGER mit den in der Projektbeschreibung genannten Attributen und Methoden. Erstelle jeweils zwei Standardkonstruktoren.
- Die Methode heilen() soll nur dann funktionieren, wenn der Magier noch lebt. Ansonsten soll eine aussagekräftige Fehlermeldung erscheinen.
- Die Methode heilen() soll zusätzlich nur dann funktionieren, wenn der Magier genug Mana hat.
- Die Methode nimmtSchaden() soll ebenfalls nur dann funktionieren, wenn der Magier noch lebt. Ansonsten soll eine aussagekräftige Fehlermeldung erscheinen.
Aufgabe 2 (Die Heilen-Methoden)
- Nenne die Methode heilen() um in kleineHeilung().
- Erstelle ein Methode grosseHeilung(), die den Magier um 20 Punkte heilt.
- Erstelle eine Methode heilen(int betrag), die den Magier um einen variablen Wert (hier: betrag) heilt. Den variablen Wert nennen wir auch Parameter.
- Verwerfe den Code in kleineHeilung() und großeHeilung() und benutze stattdessen zur Definition der beiden Methoden die heilen(int betrag) Methode.
Aufgabe 3 (Methoden für Schaden und Angriff)
- Implementiere die folgenden Methoden wie folgt:
- nimmSchaden(int Wert) ist bei Magiern und Kriegern unterschiedlich implementiert. Der Krieger bekommt zusätzlich Wut, wenn die Methode bei ihm aufgerufen wird.
- feuerball(int Wert) kostet so viel Mana wie Schaden verursacht wird (Wert).
- nahkampfangriff(int Wert) kann ein Krieger nur dann aufrufen, wenn er genügen Wut hat.
Aufgabe 4 (Referenzvariablen)
- Die Methoden feuerball(int Wert) in der Klasse Magier und nahkampfangriff(int Wert) in der Klasse Krieger sollen so abgeändert werden, dass man den Gegner, den man angreifen möchte, über eine Referenzvariable als Parameter, auswählen kann.
- Schreibe die Methoden feuerball(int Wert, KRIEGER Gegner) nahkampfangriff(int Wert, Magier Gegner).
Aufgabe 5 (Vererbung)
- Verlege alle bisher doppelt verwalteten Attribute und Methoden aus den Klassen MAGIER und KRIEGER in eine übergeordnete Klasse CHARAKTER.
- Definiere die Klasse CHARAKTER als abstrakt.
- Erstelle eine neue Klasse DRUIDE, die alles von CHARAKTER erbt.
Aufgabe 6 (Vererbung und Polymorphie)
- Problem: Die Methode public void feuerball(int Wert, KRIEGER Gegner) in MAGIER kann nur KRIEGER angreifen.
- Lösung: Die Methode public void feuerball(int Wert, CHARAKTER Gegner) in MAGIER kann alle CHARAKTER angreifen.
- Ändere alle Methoden entsprechend ab.
Aufgabe 7 (Maximalwerte für Attribute)
- Gesundheit, Mana und Wut sollen einen Maximalwert von 100 nicht überschreiten.
- Führe dazu neue Attribute ein (z.B. GesMax) und programmiere die Klassen so um, dass diese nicht mehr überschritten werden.
Aufgabe 8 (Angreifen und Parieren mit Wahrscheinlichkeit)
- Ein Angriff soll immer nur mit einer bestimmten Wahrscheinlichkeit gelingen. D.h. es gibt Angriffe, die ihr Ziel verfehlen.
- Genauso kann ein erfolgreichen Angriff mit einer bestimmten Wahrscheinlichkeit pariert werden. D.h. Selbst wenn dem Angreifer ein Angriff gelingt und der Gegner pariert, erhält der Gegner keinen Schaden.
- Um dies Umzusetzen benötigen wir Zufallszahlen.
- Setze mit diesem Hintergrundwissen das Verfehlen und Parieren in den Klassen Magier und Krieger um.
Zufallsgenerator und Zufallszahlen in Java
Dazu benutzen wir eine bereits vordefinierte Klasse in Java. Die Klasse java.util.Random kann benutzt werden um Zufallszahlen zu erzeugen. Dazu erzeugen wir ein Objekt der Klasse Random. Dieses Objekt entspricht einem Zufallsgenerator.
- Um aus dem Zufallsgenerator eine Zufallszahl zwischen 0 und 1 zu erzeugen rufen wir für das Objekt die Methode nextDouble() auf.
- Am Anfang der Klasse muss die Importanweisung stehen: import java.util.Random;
- Random zufallsgenerator = new Random(); erzeugt den Zufallsgenerator
- double Zufallszahl = zufallsgenerator.nextDouble(); erzeugt eine Behältervariable und legt die vom Generator erzeugte Zufallszahl hinein.
Zufallsgenerator und Zufallszahlen in der Online-IDE
- Über Hilfe - API-Verzeichnis kommt man zur Klasenübersicht.
- Die Klasse Random enthält statische Methoden. Diese kann man aufrufen, indem man den Klassennamen einfach voranstellt, z.B. Random.randdouble(0.0, 1.0);
Aufgabe achtdreiviertel (Act-Methode)
- Für manche Attribute muss man getter- und setter-Methoden einführen.
- Codedoppelungen vermeiden: Das Attribut Gesundheit wurde hoffentlich bereits in die Oberklasse Charakter verlegt, denn Objekte beider Klassen (Magier,Krieger) haben dieses Attribut. Die Attribute Mana und Wut sind zunächst in den jeweiligen Klassen angelegt worden. Mana beim Magier und Wut beim Krieger. Bei genauer Betrachtung stellt sich aber heraus, dass beide Attribute gleich funktionieren. Wenn der Magier zu wenig Mana hat, kann er nichts tun. Wenn der Krieger zu wenig Wut hat, kann er auch nichts tun. Mana und Wut werden weniger, wenn eine Methode ausgeführt wurde. Wäre es evtl. sinnvoller, statt Mana und Wut in Magier und Krieger zu verwalten, ein gekoppeltes Attribut ManaWut in Charakter zu verwalten? Man könnte das Attribut auch allgemein PrimaerAttribut nennen. Man stellt dann (hoffentlich) fest, dass mehrere Codedoppelungen verschwinden und fast alles in die Klasse Charakter verlegt werden kann.
- Der Magier erhält eine Methode manaRegeneration(). Durch Aufruf der Methode kann er durch ungestörte Meditation 10 Manapunkte regenerieren.
- Magier und Krieger erhalten eine act-Methode. In dieser Methode wird das Verhalten des Kriegers/Magiers festgelegt. Jeder Charakter kann pro Runde genau eine Sache tun. Der Magier kann sich entscheiden zwischen: Heilen, Mana regenerieren, Feuerball. Der Krieger zwischen Berserker und Nahkampfangriff. Wenn ein Magier zu wenig Mana hat, wird er wohl regenerieren. Wenn er zu wenig Gesundheit hat wird er sich wohl heilen.
Aufgabe 9 (Testen)
- Erstelle in einer Testklasse mehrere Charaktere und lasse diese in einer Testmethode gegeneinander kämpfen.
- Teste die Methode mehrmals. Das Ergebnis sollte (wegen der Zufallskomponente aus Aufgabe 8) variieren.
- In der Testmethode wird ein Objekt der Klasse Magier und ein Objekt der Klasse Krieger erstellt.
- Danach werden so lange die act-Methoden der beiden Objekte aufgerufen, bis einer den Löffel abgibt. Der Aufruf der act-Methoden wird also wiederholt. Das passiert mit einer Wiederholungsschleife. In dem Fall die while-Schleife.
Beispiel für eine Testklasse
public class TestKampf { public static void main(String[] args) { Magier magier1 = new Magier(); Krieger krieger1 = new Krieger(); //Runde auf 1 setzen int i = 1; //Kampfrunde wird wiederholt solange beide leben (d.h. bis einer tot umfällt) while (magier1.isLebendig() && krieger1.isLebendig()) { System.out.println("Runde " + i + " =========================="); //Magier und Krieger tun pro Runde genau eine Sache (Heilen, Mana regenerieren, Nachkampfangriff, Feuerball, Berserker) magier1.act(krieger1); krieger1.act(magier1); //Zustand beider Objekte ausgeben magier1.ausgeben(); krieger1.ausgeben(); //Runde um 1 Erhöhen i++; } } }
Programmausgabe
Die Ausgabe des Programms könnte z.B. folgendermaßen aussehen:
Gandalf fühlt sich mit 20 Gesundheit und 20 Mana wie neu geboren Haudraufundschluss fühlt sich mit 50 Gesundheit und 0 Wut wie neu geboren Runde 1 ========================== Gandalf führt den Angriff auf Haudraufundschluss erfolgreich aus! Haudraufundschluss hat jetzt 40 Gesundheit Haudraufundschluss erhält durch den erhaltenen Schaden 10 Wut Haudraufundschluss greift Gandalf an und ... verfehlt! Gandalf hat Gesundheit 20 und 10 Mana Haudraufundschluss hat Gesundheit 40 und 0 Wut Runde 2 ========================== Gandalf führt den Angriff auf Haudraufundschluss erfolgreich aus! Haudraufundschluss hat den Angriff pariert! Haudraufundschluss ärgert sich darüber, dass er so wenig Wut hat und hat deshalb wieder 10 Wut Gandalf hat Gesundheit 20 und 0 Mana Haudraufundschluss hat Gesundheit 40 und 10 Wut Runde 3 ========================== Gandalf regeneriert Mana und hat jetzt wieder 10 Mana Haudraufundschluss führt den Angriff auf Gandalf erfolgreich aus! Gandalf hat den Angriff pariert! Gandalf hat Gesundheit 20 und 10 Mana Haudraufundschluss hat Gesundheit 40 und 0 Wut Runde 4 ========================== Gandalf führt den Angriff auf Haudraufundschluss erfolgreich aus! Haudraufundschluss hat den Angriff pariert! Haudraufundschluss ärgert sich darüber, dass er so wenig Wut hat und hat deshalb wieder 10 Wut Gandalf hat Gesundheit 20 und 0 Mana Haudraufundschluss hat Gesundheit 40 und 10 Wut Runde 5 ========================== Gandalf regeneriert Mana und hat jetzt wieder 10 Mana Haudraufundschluss führt den Angriff auf Gandalf erfolgreich aus! Gandalf hat jetzt 10 Gesundheit Gandalf hat Gesundheit 10 und 10 Mana Haudraufundschluss hat Gesundheit 40 und 0 Wut Runde 6 ========================== Gandalf heilt sich um 10 Gandalf hat jetzt 20 Gesundheit Haudraufundschluss ärgert sich darüber, dass er so wenig Wut hat und hat deshalb wieder 10 Wut Gandalf hat Gesundheit 20 und 0 Mana Haudraufundschluss hat Gesundheit 40 und 10 Wut Runde 7 ========================== Gandalf regeneriert Mana und hat jetzt wieder 10 Mana Haudraufundschluss führt den Angriff auf Gandalf erfolgreich aus! Gandalf hat den Angriff pariert! Gandalf hat Gesundheit 20 und 10 Mana Haudraufundschluss hat Gesundheit 40 und 0 Wut Runde 8 ========================== Gandalf führt den Angriff auf Haudraufundschluss erfolgreich aus! Haudraufundschluss hat den Angriff pariert! Haudraufundschluss ärgert sich darüber, dass er so wenig Wut hat und hat deshalb wieder 10 Wut Gandalf hat Gesundheit 20 und 0 Mana Haudraufundschluss hat Gesundheit 40 und 10 Wut Runde 9 ========================== Gandalf regeneriert Mana und hat jetzt wieder 10 Mana Haudraufundschluss führt den Angriff auf Gandalf erfolgreich aus! Gandalf hat den Angriff pariert! Gandalf hat Gesundheit 20 und 10 Mana Haudraufundschluss hat Gesundheit 40 und 0 Wut Runde 10 ========================== Gandalf führt den Angriff auf Haudraufundschluss erfolgreich aus! Haudraufundschluss hat den Angriff pariert! Haudraufundschluss ärgert sich darüber, dass er so wenig Wut hat und hat deshalb wieder 10 Wut Gandalf hat Gesundheit 20 und 0 Mana Haudraufundschluss hat Gesundheit 40 und 10 Wut Runde 11 ========================== Gandalf regeneriert Mana und hat jetzt wieder 10 Mana Haudraufundschluss führt den Angriff auf Gandalf erfolgreich aus! Gandalf hat jetzt 10 Gesundheit Gandalf hat Gesundheit 10 und 10 Mana Haudraufundschluss hat Gesundheit 40 und 0 Wut Runde 12 ========================== Gandalf heilt sich um 10 Gandalf hat jetzt 20 Gesundheit Haudraufundschluss ärgert sich darüber, dass er so wenig Wut hat und hat deshalb wieder 10 Wut Gandalf hat Gesundheit 20 und 0 Mana Haudraufundschluss hat Gesundheit 40 und 10 Wut Runde 13 ========================== Gandalf regeneriert Mana und hat jetzt wieder 10 Mana Haudraufundschluss führt den Angriff auf Gandalf erfolgreich aus! Gandalf hat den Angriff pariert! Gandalf hat Gesundheit 20 und 10 Mana Haudraufundschluss hat Gesundheit 40 und 0 Wut Runde 14 ========================== Gandalf führt den Angriff auf Haudraufundschluss erfolgreich aus! Haudraufundschluss hat jetzt 30 Gesundheit Haudraufundschluss erhält durch den erhaltenen Schaden 10 Wut Haudraufundschluss führt den Angriff auf Gandalf erfolgreich aus! Gandalf hat jetzt 10 Gesundheit Gandalf hat Gesundheit 10 und 0 Mana Haudraufundschluss hat Gesundheit 30 und 0 Wut Runde 15 ========================== Gandalf regeneriert Mana und hat jetzt wieder 10 Mana Haudraufundschluss ärgert sich darüber, dass er so wenig Wut hat und hat deshalb wieder 10 Wut Gandalf hat Gesundheit 10 und 10 Mana Haudraufundschluss hat Gesundheit 30 und 10 Wut Runde 16 ========================== Gandalf heilt sich um 10 Gandalf hat jetzt 20 Gesundheit Haudraufundschluss führt den Angriff auf Gandalf erfolgreich aus! Gandalf hat den Angriff pariert! Gandalf hat Gesundheit 20 und 0 Mana Haudraufundschluss hat Gesundheit 30 und 0 Wut Runde 17 ========================== Gandalf regeneriert Mana und hat jetzt wieder 10 Mana Haudraufundschluss ärgert sich darüber, dass er so wenig Wut hat und hat deshalb wieder 10 Wut Gandalf hat Gesundheit 20 und 10 Mana Haudraufundschluss hat Gesundheit 30 und 10 Wut Runde 18 ========================== Gandalf führt den Angriff auf Haudraufundschluss erfolgreich aus! Haudraufundschluss hat jetzt 20 Gesundheit Haudraufundschluss erhält durch den erhaltenen Schaden 10 Wut Haudraufundschluss greift Gandalf an und ... verfehlt! Gandalf hat Gesundheit 20 und 0 Mana Haudraufundschluss hat Gesundheit 20 und 10 Wut Runde 19 ========================== Gandalf regeneriert Mana und hat jetzt wieder 10 Mana Haudraufundschluss führt den Angriff auf Gandalf erfolgreich aus! Gandalf hat den Angriff pariert! Gandalf hat Gesundheit 20 und 10 Mana Haudraufundschluss hat Gesundheit 20 und 0 Wut Runde 20 ========================== Gandalf führt den Angriff auf Haudraufundschluss erfolgreich aus! Haudraufundschluss hat jetzt 10 Gesundheit Haudraufundschluss erhält durch den erhaltenen Schaden 10 Wut Haudraufundschluss greift Gandalf an und ... verfehlt! Gandalf hat Gesundheit 20 und 0 Mana Haudraufundschluss hat Gesundheit 10 und 0 Wut Runde 21 ========================== Gandalf regeneriert Mana und hat jetzt wieder 10 Mana Haudraufundschluss ärgert sich darüber, dass er so wenig Wut hat und hat deshalb wieder 10 Wut Gandalf hat Gesundheit 20 und 10 Mana Haudraufundschluss hat Gesundheit 10 und 10 Wut Runde 22 ========================== Gandalf führt den Angriff auf Haudraufundschluss erfolgreich aus! Haudraufundschluss ist gerade gestorben! Haudraufundschluss ist tot! Haudraufundschluss erhält durch den erhaltenen Schaden 10 Wut Haudraufundschluss ist tot und kann deshalb nicht angreifen! Gandalf hat Gesundheit 20 und 0 Mana Haudraufundschluss hat Gesundheit 0 und 10 Wut