Suche Home Einstellungen Anmelden Hilfe  

Projekt "Dungeon"

Entwurfsbeschreibung zu Version 0.5 (Prototyp)

Die Erstellung umfangreicher Diagramme gemäß der UML ist ohne ein entsprechendes Werkzeug nur schwer möglich, wenn nicht gar unmöglich. Selbst wenn ein entsprechendes Werkzeug zur Verfügung steht, wird beispielsweise ein Sequenzdiagramm für dieses relativ einfache Beispiel schon sehr komplex.

1) Strukturkomponenten (Klassen und Objekte)

Die Klasse stellt einen Bauplan für gleichartige Objekte dar. In diesem Bauplan werden die Eigenschaften, die Struktur und das Verhalten der Objekte beschrieben. eine Klasse besteht dabei im Wesentlichen aus Attributen und Methoden. Um mit Objekten arbeiten zu können, werden diese aus den Klassen erzeugt, man sagt auch "instantiiert" und nennt die Objekte Instanzen der Klasse.
Durch Attribute werden die Eigenschaften und die Struktur der Objekte repräsentiert. Alle Objekte einer Klasse besitzen dieselben Attribute. Die Werte der Attribute können jedoch verschieden sein. Methoden realisieren die Operationen, die auf Objekten einer Klasse ausgeführt werden können.



Die Verwaltung des Höhlensystems und die Steuerung der Objekte im Labyrinth übernimmt das "Hauptprogramm", für das die Klasse dungeon bereitgestellt wird. Das Programm adventu ist unter TurboPascal zusätzlich notwendig, um ein Objekt der Klasse dungeon zu initialisieren.
Klasse dungeon
- dungeon : array[1..40,1..20] of char;
- nebel : array[1..40, 1..20] of integer;
- held : tHeld;
- monster : array[1..7] of tMonster;
- items : array[1..7] of tGegenstand;
- io_dungeon : tKonsole;
- io_com : tKonsole;
 Init;
 Zeigen;
 Bewegen;
 Run;
 Kampf;
- Hoch;
- Rechts;
- Links;
- Runter;
- Aufnehmen;
Die Methode Init()richtet zunächst zwei Fensterbereiche ein. In dem einen werden das Höhlensystem und seine Bewohner, Gegenstände und Hindernisse angezeigt werden. Hierzu dienen die Feldvariablen dungeon und nebel. Die Feldvariablen nebel werden auf 0 gesetzt, wenn der Bereich des Höhlensystems unsichtbar ist, sonst auf 1
Der zweite Fensterbereich dient dem textorientierten Dialog. Beide Fensterbereiche sind Objekte einer gemeinsamen Klasse Konsole, um die Portabilität auf andere Sprachen und Systeme zu erleichtern.
Anschließend werden der Held, die Monster und die Gegenstände initialisiert sowie die Wände rings um das Labyrinth gesetzt. Monster und Gegenstände werden zufällig im dungeon verteilt. Jedes dungeon-Feld enthält entweder einen Gegenstand, ein Monster oder eine Wand. Die Parameter zur Initialisierung dieser Objekte werden später erläutert.
Es wäre zwar denkbar, gemeinsame Eigenschaften von Held, Monster und Gegenständen von einer Klasse abzuleiten, dies erscheint jedoch weder natürlich, noch vom Aufwand her angemessen.
Der Ausgang wird durch das Symbol '>' gekennzeichnet.
In dieser Prototyp-Version werden alle Objekte im Dungeon sichtbar geschaltet (Die entsprechende Routine sollte im Hinblick auf zukünftige Versionen natürlich leicht abänderbar sein).
Die Methode Zeigen() gibt den jeweils aktuellen Zustand des Höhlensystems, verwaltet in dungeon und nebel, in das Fenster io_dungeon aus.
Die Methode Bewegen() steuert das Bewegen des Helden durch das Höhlensystem, abhängig von den Tastatureingaben im zweiten Fensterbereich io_com, und ruft den Eingaben entsprechend die Methoden Hoch(), Runter(), Links() oder Rechts() auf.
Diese gekapselten Methoden prüfen jeweils, ob der Held entweder gegen eine Wand läuft und einen Schaden() (Methode von Held) erleidet oder positionieren den Helden neu und rufen die Methode Aufnehmen() auf.
Die gekapselte Methode Aufnehmen() überprüft, ob sich auf dem gerade betretenen Feld ein Monster oder ein Gegenstand befindet. Handelt es sich um einen Gegenstand, wird dieser vom Held aufgenommen (Methode nehmen) und eine entsprechende Meldung im Dialogfenster io_com ausgegeben. Befindet sich auf dem Feld ein Monster, so wird die Methode Kampf() aufgerufen. Das entsprechende Feld wird in beiden Fällen sichtbar geschaltet.
Die Methode Kampf() wählt zunächst zufällig aus den noch lebenden Monstern eines aus. Der Status des Helden und des ausgewählten Monsters (Methoden zeigen und kurz_zeigen) werden angezeigt. Die erste Runde muss der Held gegen das Monster kämpfen. Anschließend kann der Held entscheiden, wenn beide Kampfpartner den Kampf überleben, ob er den Kampf fortsetzen möchte, oder er sich zunächst zurückzieht, um seine Kräfte zu sammeln. Ansonsten wird solange gekämpft, bis einer der beiden Kämpfenden stirbt.
Der Kampf selbst findet dadurch statt, dass die Methode Schaden des Objekts Held mit dem Kampfwert des Monsters aufgerufen wird. Anschließend wird die Methode Schaden des Objekts Monster mit dem Kampfwert des Monsters aufgerufen.
Die Methode Run() startet das Spiel, nachdem die Initialisierung mit Init() erfolgte und ruft solange die Methoden Bewegen() und Zeigen() auf, bis entweder der Held tot ist oder er den Ausgang gefunden hat.


Die Klasse Items dient der Instantiierung aller Gegenstände, unabhängig von ihrer Art. Jeder Gegenstand hat bestimmte Eigenschaften, die seinem Träger nützlich werden können. Zudem hat jeder Gegenstand einen bestimmten Wert und eine maximale Anfangsstabilität, die sich im Laufe des Spiels verändern kann.
Klasse Items
Bezeichnung : string;
Wert, Attacke, Ruestung, Heilung, Gewicht, Stabilitaet, Max_Stab : real;
-  io_com : tKonsole; 
Init(bez : string; w,a,r,h,g,s,ms : real);
Schaden(s : real);
Reparieren(r : real);
Flicken;
Zeigen : string;
Kurz_zeigen : string;
- Werte_neu_berechnen;
Die Methode Init(..) erzeugt ein neues Objekt der Klasse, wobei die Parameter folgende Bedeutung haben:
w: finanzieller Wert eines Gegenstandes (in dieser Version irrelevant)
a: Attackewert, bestimmt die Schädigung des Gegners
r: Rüstungswert, schützt vor den gegnerischen Attacken
h: Heilungswert (in dieser Version irrelevant)
g: Gewicht (in dieser Version irrelevant)
s: Stabilität (<=0, dann ist der Gegenstand defekt)
ms: maximale Stabilität
Diese Parameter müssten nach der "objektorientierten Lehre" eigentlich gekapselt werden, aber der Aufwand für die dann erforderlichen Zugriffs-Methoden ist zu hoch und nicht notwendig.

!! Hier hat sich eine Verwirrung eingeschlichen. Items entspricht Gegenstand.

Die Methode Schaden(s) führt zu einer s-prozentigen Schädigung der Attacke, Rüstung und Heilungseigenschaften des Objekts. Hierzu wird zusätzlich eine gekapselte Methode Werte_neu_berechnen() verwendet, die auch für die folgenden Methoden benötigt wird.
Reparieren(r) repariert den Gegenstand um den angegebenen Wert, gegebenenfalls bis zur maximalen Stabilität. Flicken() reduziert die maximale Stabilität und setzt die aktuelle Stabilität auf die neue maximale Stabilität. Reparieren und Flicken werden in dieser Programmversion noch nicht verwendet.
Zeigen() liefert die aktuellen Eigenschaften des Gegenstandes, Kurz_Zeigen()  den Namen des Gegenstandes.


 
Klasse held
x, y
- lebenspunkte, max_leben : real;
- (* mana, max_mana, zschaden : integer *)
- attack, ruestung : real;
- name : string;
- rucksack : tInventar;
- (* zauberbuch : tZauberbuch *)
 Init(bez : string; l, ml : real; a, r : real; xx,yy : integer);
 Zeigen : string; 
 Kurz_Zeigen : string; 
 Schaden(s : real);
 Nehmen(g : tGegenstand);
 (* Heilen;  *)
 (* Zaubern; *)
 (* Inventar_zeigen; *) 
 Kampfwert : real;
 Tot : boolean; 
- Werte_neu_berechnen;
- Ruestungswert : real; 
Mit der Methode Init() werden Parameter mit der folgenden Bedeutung übergeben:
bez: der Name des Helden
l: die Anzahl der aktuellen Leben
ml: die Anzahl der maximalen Leben
a: Attackewert
r: Rüstungswert
xx,yy: die Startposition des Helden
Die in (* .. *) gehaltenen Attribute/Methoden sind in dieser Version noch nicht implementiert, deuten aber die gewünschten Erweiterungen an. Die Position des Helden wird in den öffentlichen Attributen x und y festgehalten.
Zur Anzeige des aktuellen Status des Helden dient die Methode Zeigen(), die einen vorformatierte String zurückgibt. Die Methode Kurz_Zeigen() liefert in dieser Version nur den Namen des Helden.
Die Methode Schaden(s) berechnet eine Schädigung (hier: Rückgang der Lebenspunkte) des Helden aus dem Prozentwert s und dem Rüstungswert des Helden. In dieser Prototyp-Version berechnen sich Attacke und Rüstungswert bei einem Schaden aus den Lebenspunkten mittels der gekapselten Methode Werte_neu_berechnen(). Der Rüstungswert() ergibt sich als real-Zahl und berücksichtigt mögliche Gegenstände im Rucksack.
Gegenstände, die der Held entdeckt hat, können mittels der Methode Nehmen(g) in den Rucksack g gelegt werden, wobei derzeit keine Nebenbedingungen wie Gewicht, Fassungsvermögen oder Wert der Gegenstände überprüft werden.
Der Kampfwert() für einen aktuellen Kampf ergibt sich aus dem aktuellen attack Wert des Helden und der Gegenstände im Rucksack. Gleiches gilt für die Methode Ruestungswert(). Allerdings wird der Rüstungswert auf 100 beschränkt.
Die Methode Tot() liefert den boolean Wert true, wenn der Held tot ist.


 
Klasse monster
- lebenspunkte, max_leben : real;
- attack, ruestung : real;
- (* item : tGegenstand; *)
- name : string;
- x, y : integer;
Init(bez : string; l, ml : real; a, r : real; xx, yy : integer);
Zeigen : string;
Kurz_Zeigen : string;
Schaden(s : real);
Kampfwert : real;
Tot : boolean;
-  procedure Werte_neu_berechnen;
Die Klasse monster ist ähnlich aufgebaut, wie die Klasse held. Allerdings haben Monster derzeit keinen Rucksack, in den sie beispielsweise Gegenstände aufnehmen könnten, wenn sie frei durch das Labyrinth laufen würden.

Die Position eines Monsters kann ebenso wie bei der Klasse held in den x und y Attributen abgelegt werden. Diese Attribute haben in dieser Programmversion jedoch keine Relevanz, da sie nicht benötigt werden (siehe Klasse dungeon).

Anmerkung: Anhand der Klassen monster und held kann später das Prinzip der Vererbung verdeutlicht werden, z.B. von einer Klasse lebewesen.
 



Der Rucksack, in dem der Held seine Gegenstände sammelt, wird als Objekt der Klasse inventar erzeugt.
 
Klasse inventar
 - Item : array[1..20] of tGegenstand;
 - Zahl : 0..20;
 procedure Init;
 procedure Schaden(s : integer);
 procedure Aufnehmen(g : tGegenstand);
 procedure Ablegen(n : integer);
 procedure Heilen;

 function Zeigen :  string;
 function sum_w : real;
 function sum_a : real;
 function sum_r : real;
 function sum_g : real;

In dieser Programmversion kann der Inventar maximal 20 Gegenstände umfassen, die in dem gekapselten Array Item durch Aufruf der Methode Aufnehmen() abgelegt werden.
Die Methode Ablegen(n) ermöglicht das Herausnehmen eines Gegenstandes n aus dem Inventar.
Die Methode Heilen() hat noch keine Auswirkungen, soll aber demnächst die Reparatur des Inventars ermöglichen, wenn beispielsweise ein Schaden() entstanden ist.
Die Methoden sum_w(), sum_a(), sum_r() und sum_g() liefern jeweils die Summe der Werte, Attackewerte, Rüstungswerte bzw. Gewichte aller im Inventar vorhandenen Gegenstände als real-Zahl.
Die Methode Zeigen() liefert eine formatierten String, der mit einem Zeilenumbruch-Kode endet. Diese Vorgehensweise ist sicherlich verbesserbar, wenn die Klasse konsole geschickter implementiert wird. Für unseren Prototyp unter MS-DOS soll diese Variante zunächst genügen.


Alle Ein-/Ausgaben auf den Bildschirm sollen von der Klasse konsole realisiert werden. Diese Klasse hängt stark von der verwendeten Basismaschine, der definierten Benutzerschnittstelle und auch dem Benutzermodell ab. Die folgende Klasse ist für ein Standard MS-Dos Fenster konzipiert.
Klasse konsole
-  x_start,y_start, x_ende, y_ende, akt_zeile : integer;
Init(x,y,b,h : integer);
Meldung(msg : string);
Meldungxy(x,y : integer; msg : string); 
Loeschen;
(* procedure Close_Window; *)
Tastatur_Abfrage : char; 
Die Methode Init() erzeugt ein Fensterobjekt der Breite b und Höhe h (in Zellen) beginnend mit den Koordinaten x,y. Diese Parameter werden in den gekapselten Attributen abgelegt, welche an die jeweilige physische Konsole anpassbar sind.
Als einfache Ausgabe-Methode stehen Meldung(msg) und Meldungxy(x,y,msg) zur Verfügung. Beide Methoden geben einen String in das Fenster aus, der alle Formatierungen (inkl. Zeilenumbrüche) enthalten muss. Meldung(msg) schreibt den String in die aktuelle Fensterzeile und Meldungxy(..) in die entsprechende Fensterzelle (der String sollte die Länge 1 haben).
Die Methode Loeschen() löscht den Inhalt des Fensters.
Mit der Methode Tastatur_Abfrage() wird eine Tastatureingabe innerhalb dieses Fensters abgefragt (ohne Ausgabe) und als char zurückgegeben.

2) Beziehungen zwischen den Strukturkomponenten

Bei den Beziehungen werden in der UML sogenannte Assoziationsbeziehungen, bei denen die beteiligten Klassen gleichwertig sind, Aggregations- bzw. Kompositionsbeziehungen, bei denen eine Klasse Bestandteil einer anderen Klasse ist, und Vererbungsbeziehungen unterschieden.


 
 

Benutzer: Gast • Besitzer: mthomas • Zuletzt geändert am: