next up previous contents index
Next: ,,Lasst uns Menschen machen Up: Schritt für Schritt ins Previous: ,,...ein Strom, zu wässern

Subsections



,,... und siehe, eine Tür war aufgetan ...''

Verschlossene Türen und versteckte Schlüssel gehören zu einem Textadventure wie die Olive zum Martini. Deshalb gibt es auch in Eden eine verschlossene Tür; sie führt vom östlichen Teil des Gartens - EdenE - zu einem Raum, den wir noch nicht gesehen haben und der den schönen Namen EastOfEden trägt. Es handelt sich um eine komplizierte Tür: Sie ist auf beiden Seiten (fast) gleich; dafür steht sie nicht an einer Seite des Raums oder - wie gewöhnlich - an einer Wand, sondern mittendrin ohne eine bestimmte Richtung; außerdem bietet sie eine böse Überraschung, wenn der Spieler sie zum ersten Mal öffnet (zum Trost bekommt er Punkte dafür):

Object Tuer EdenE

 with  description "Die Tür ist bis auf das Schlüsselloch mit Blumen

                    zugewachsen. Sie steht mitten im Raum, trotzdem 

                    kannst du ihre Rückseite nicht sehen.",

       name 'tuer' 'blume' 'blumen' 'zugewachsen' 'schluessel' 'loch'

            'Raum' ,

       each_turn[;

          if (location == EastOfEden)

              self.&name->6 = 'Garten';

          else

              self.&name->6 = 'Raum';

          ],

       when_closed "Eine mit Blumen bewachsene Tür steht da.",

       when_open [;

          if (self in EdenE) "Eine Tür führt aus dem Garten heraus in

                              einen weiten, offenen Raum."; ! rtrue!

          "Die Tür führt zurück in den Garten Eden.";

          ],

       door_to [;

          if (self in EdenE) return EastOfEden; ! auch das ist true! 

          return EdenE;

          ],

       door_dir in_to,

       with_key Primel,

       before [;

          lookUnder: "Du siehst viele Blumen.";

          take, lift, transfer: "So kommst du nicht weiter."; 

          ],

        react_before [;

           insert, puton: if (self == second)

                          {

                             if (noun==primel) 

                                <<unlock self primel>>;

                             else 

                                "So kommst du nicht weiter.";

                          }

           ],

        after [;

           open: if (self hasnt general) 

                 {

                    achieved(0);

                    give self general;

                    move schlange to mitte;

                    "Du öffnest die Tür nur einen Spalt weit, da wird sie 

                     dir schon aus der Hand gestoßen. Etwas Großes, rot und

                     schwarz Gefärbtes drückt die Tür auf und dringt in den

                     Garten ein. Es ist ein Tier, das du noch nicht kennst,

                     langgestreckt und ohne Gliedmaßen. Es sieht dich kurz 

                     an, zischt, und du fühlst dich mit einem Mal wie eiskalt.

                     - Dann wendet es sich wieder ab und schlängelt durch 

                     das Gras in westlicher Richtung in den Garten.^^

                     Das Tier braucht einen Namen. Du beschließt, es

                     ~Schlange~ zu nennen. ^^

                     Die Tür ist jetzt offen. Du siehst durch die Tür in einen

                     weiten, offenen Raum.";

                  }

           unlock: remove primel;

                   give primel general;

                   "Du hältst die Primel an das Schlüsselloch. Sie schlägt

                    sofort Wurzeln zwischen den anderen Blumen und ist von

                    ihnen nicht mehr zu unterscheiden.

                    ^^Die Tür ist nicht mehr versperrt.";

           ],

        found_in EdenE EastOfEden,

        short_name "Tür",

        dekl 9,

 has    female static door openable lockable locked;

Die Tür an sich

Zur Tür wird ein Objekt durch das Attribut door. openable legt fest, dass der Spieler sie auf- und zumachen kann; lockable legt fest, dass er sie - mit dem richtigen Schlüssel - auf- oder zusperren kann. Das Attribut locked schließlich bedeutet, dass die Tür zu Anfang zugesperrt ist. Die Aktionen dazu heißen ##Open, ##Close, ##Lock und ##Unlock.

door_dir
legt die Richtung fest, in die der Spieler gehen muss, um durch die Tür zu gehen (hier nur: in_to, d.h. hinein; eine normalere Tür stünde an einer Wand in einer bestimmten Richtung und hätte an dieser Stelle noch etwa e_to oder w_to). Diese property darf man nicht verwechseln mit
door_to
enthält den Namen des Raums, in den der Spieler gelangt, wenn er durch die Tür geht.
with_key
enthält den Namen des Objekts, mit dem die Tür auf- und zugesperrt werden kann (hier nur einmal, weil die Primel nach dem Aufsperren mit dem Befehl remove aus dem Spiel entfernt wird).
when_closed
und
when_open
enthalten unterschiedliche Beschreibungen je nach dem Zustand der Tür.
Das Auf- und Zumachen und das Auf-und Zusperren eines container-Objekts funktioniert genauso wie bei der Tür. door_dir und door_to sind dabei natürlich unnötig.

Beachte:

Eine Tür muss gar keine Tür sein. Mit dem eben beschriebenen Instrumentarium kann man auch z.B. eine Brücke oder einen Materietransmitter bauen.


Zwei Seiten einer Tür

Im klassischen Adventure dreht sich alles darum, durch die Tür und an den Schatz zu kommen. Wie die Tür auf der Rückseite aussieht, ist nicht so wichtig. Unsere Tür aber hat zwei Seiten:

Zunächst ist sie wieder mit found_in als Schiebekulisse implementiert, d.h. sie befindet sich immer in dem Raum, in dem auch die Spielfigur ist. Dies ermöglicht es, entweder mit (location==EdenE) oder mit (self in EdenE) abzufragen, auf welcher Seite wir gerade sind. (Beides führt hier zum gleichen Ergebnis: location ist der augenblickliche Aufenthaltsort der Spielerfigur25; mit in wird abgefragt, ob EdenE der parent von self, d.h. der Tür ist.) Je nach dem Ergebnis ändern wir den Inhalt von door_to und die Beschreibung des Raums, der durch die offene Tür zu sehen ist, in der property when_open. Bei einer ,,normalen'' Tür müssten wir auch noch door_dir ändern.

Beachte:

Hier ist an zwei Stellen (die ich markiert habe) der oben (2.6.3) beschriebene Trick mit (implizitem) return angewendet worden; bei ,,sauberer'' Programmierung müsste da jeweils noch ein else stehen.

Um das Ganze perfekt zu machen, jonglieren wir auch mit dem Namen der Tür. Der Befehl ,,Gehe in den Garten'' soll den Spieler durch die Tür schicken, wenn er auf der anderen Seite steht. Steht er aber schon im Garten, wäre der Befehl sinnlos und der Spieler würde sich zu Recht aufregen, wenn er mit ,,Gehe in den Garten'' aus dem Garten herausgeschickt würde.

Zu Spielbeginn steht die Tür auf der Gartenseite (in EdenE) und der letzte (siebte) Eintrag der name-property lautet: 'Raum'. Auf 'Garten' hört die Tür gar nicht, wohl aber auf ,,Gehe in den Raum''. Geht der Spieler aber durch die Tür, so ändern wir diesen (siebten) Eintrag von 'Raum' in 'Garten' und voilá: ,,Gehe in den Garten'' funktioniert; dafür hört die Tür nicht mehr auf 'Raum', denn das ist überschrieben worden.

Wie macht man das? Ganz einfach: Intern ist das name-property ein array, d.h. ein Feld aus einzeln (mit dem Operator ->) adressierbaren Wörterbucheinträgen. Ein ,,normales'' property der Tür kann z.B. mit tuer.description (innerhalb des für die Tür geschriebenen Codes einfacher mit self.description) aufgerufen werden. Uns interessiert aber nicht die gesamte name-property, sondern nur ein einzelner (der siebte und letzte) Eintrag. Um dies zu kennzeichnen, muss dem name ein & vorangestellt werden, also self.&name.

Nun kann der siebte Eintrag mit self.&name->6 adressiert werden (der erste Eintrag hat den Index 0, der siebte den Index 6).

Wie aber merken wir, ob der Spieler durch die Tür gegangen ist? Wir schauen ganz einfach nach jedem Zug nach, wo er steht und sorgen dafür, dass der Name richtig gesetzt ist. Dafür benutzen wir der Einfachkeit halber die property each_turn , die eine Routine enthalten kann, die bei jedem Zug ausgeführt wird, wenn die Tür im Blickfeld des Spielers ist.

Die Türe der Pandora

Wenn die Tür zum ersten Mal geöffnet wird, ist das Attribut general noch ungesetzt. Dann lassen wir die Schlange in den Garten einbrechen und setzen anschließend general, damit das nicht noch einmal passiert. Mit der Routine Achieved(0) wird festgehalten, dass der Spieler die erste (bzw. die nullte, auch hier wird beginnend mit Null gezählt) Aufgabe des Spiels gelöst hat und dafür Punkte beanspruchen kann.

noun und second

Wir betrachten nochmal die react_before-property und dort die Regel für ##Insert und ##PutOn : Hier werden Handlungen des Spielers wie ,,Setze die Primel auf die Tür'' abgefangen (In diesem Befehl wäre die Primel erstes, direktes Objekt (noun) und die Tür zweites Objekt (second).) und abgeändert -- in den Befehl ,,Sperre die Tür mit der Primel auf'' (auf ,,Informese'' <Unlock Tuer Primel>, der zweite Satz spitze Klammern steht wieder für ein implizites return und statt Tuer kann self stehen).



Footnotes

... Spielerfigur25
Jedenfalls dann, wenn es hell ist. Wenn es dunkel ist, ist die Spielerfigur in einem besonderen Ort namens TheDark und nur die Variable real_location gibt Auskunft darüber, wo sie sein sollte.

next up previous contents index
Next: ,,Lasst uns Menschen machen Up: Schritt für Schritt ins Previous: ,,...ein Strom, zu wässern
Frank Borger
2003-05-02