Eine Worldmap erstellen

Mit Worldmap ist eine Stadtkarte oder eine Gegend gemeint auf der der Spieler per Mausclicks den nächsten Ort aufsuchen kann.

Zunächst braucht ihr einen Raum der als eure Karte dient. Dieses stattet ihr mit Objekten aus, um mit diesen die jeweiligen möglichen Orte anklicken zu können.

Auf folgende Art betretet ihr eine Worldmap. In dem Walkmapskript bei den Ausgängen aus euren Räumen wo im Normalfall ein beamto Befehl ist, kommt nun folgendes rein :

setfocus (none)
loadroom (karte)

Den Focus müsst ihr auf None setzen da ansonsten der aktuelle Raum sich an euren Character anpassen würde.
Wir befinden uns jetzt auf der Karte. Im Skript eines Objektes das einen Ort darstellt steht nun :

on (click)
{
  setfocus (last)
  beamto (self ; Zielraum ; 12 ; 27 ; 1)
}

Mit "last" wird der letzte Character fokusiert, also den welchen ihr vor dem Betreten der Worldmap hattet. Mit dem beamto Befehl stellt ihr diesen Character dann in den Zielort. Der Raumwechsel findet dann automatisch statt.

Es ist auch möglich eine Worldmap über mehrere Bildschirme zu verteilen. Auf der Worldmap müssen dann Objekte plaziert werden welche als Scrollbuttons dienen. In diesen wird dann im on (click) Ereignis der Befehl setpos (raum ; x ; y ; FALSE) eingesetzt. Dadurch ändert ihr die Bildposition auf der Karte.


Effekte mit dem Raumlicht

Durch den Befehl setlight (raum ; rot ; grün ; blau) wird der Raum mit einer Lichtfarbe übersät. Hiermit lassen sich Effekte wie Lichtschalter oder Rotlicht erstellen.
Nehmen wir als Beispiel einen dunklen Raum der ein gelbliches Blinklicht haben soll. Für dieses Effekt benutzen wie das on (loop1) Ereigniss im Raumskript. Der Loop1 Teil eines Raumskriptes wird kontinuierlich wiederholt solange ein Raum geladen ist unabhängig von der Spielsituation. Benutzt werden sollte es nur für reine optische Effekte die das eigentliche Adventure nicht beeinflussen. Folgender Teil beschreibt den Blinklichteffekt :

on (loop1)
{
  setlight (raum ; 50 ; 50 ; 50)
  wait (1)
  setlight (raum ; 210 ; 150 ; 50)
  wait (0,1)
}

Erst wird der Raum verdunkelt für eine Sekunde und anschließend für 0,1 Sekunden in der Blinklicht Farbe getaucht. Hier könnten nun auch noch unterschiedliche Effekte reingepackt werden, die durch if Bedingungen abgefragt werden. Seht euch dazu z.B den Keller aus dem Test Adventure an.


Einen nachlatschenden Character kreieren.

Ihr kennt aus Spielen wie Sam&Max oder Discworld dem Hauptcharacter nachlaufende Character. Hierzu benötigen wie das Loop2 Ereigniss aus Raumskripten. Loop2 unterscheidet sich von Loop1 dadurch das es nur im normalen Spielverlauf abgearbeitet wird. Während Cutscenes, Textscenes und während ein Character per Mausklick anvisiert wird setzt es aus!
Der Loop2 Teil ist für alle im Hintergrund ablaufenden Vorgänge gedacht die durch den Spieler unterbrochen werden können, wie z.B jemanden anlabern.

Um also einen Mitlauf-Character zu haben, müsst ihr bei jedem Ausgang in jedem Raum dafür sorge tragen das selbiger mit gebeamt wird, in den nächsten Raum. Im billigsten Fall steht dann in jedem Raumskript :

on (loop2)
{
  follow (mitlaufcharacter ; self)
  wait (1)
}

Hierbei läuft euer Mitlaufcharacter einmal pro Sekunde zu der Position von eurem gewählten Character, was ziemlich unkreativ ist. Schöner wirds wenn ihr einige Aktionen einplant die raumabhängig sind. Denkt dabei an Sam&Max und an die ganze Scheiße die Max überall anstellt. Euer Mitlaufcharacter muss also nicht ständig an den Füssen seines Partners kleben sondern kann zwischendurch auch mal alleine handeln. Als kleines Beispiel hab ich ins Test Adventure den Roboter eingebaut, der in regelmäßigen Abständen in die Ladestation muss.


Sich Unterhaltende Hintergrund Character

Ebenfalls mit dem loop2 Teil lassen sich Hintergrundgespräche realisieren. Diese Dialoge sollen natürlich dadurch unterbrechbar sein, das ihr diese Typen anquakt. Jetzt könntet ihr einen Dialog formen der abwechselnd aus einem speech Befehl und einem wait Befehl besteht. Das hat allerdings einen Nachteil :
Jedesmal wenn das Loop2 Ereigniss unterbrochen wird durch eine Cut- oder Textscene wird es zurückgesetzt. Bei einer Verkäuferfigur die immer nur den selben Satz trillert geht das in Ordnung, bei einem richtigen Dialog ist es aber eher unerwünscht das das Gespräch immer von vorn beginnt. Deshalb bedienen wir uns der Nummernvariablen.

Neben Merkern, die entweder TRUE oder FALSE sind, könnt ihr nämlich auch Zahlen abspeichern. Diese müssen nicht im Editor vordefiniert werden. Zum setzen einer Zahl verwendet man den Befehl setnum (name ; zahl) und zum Abfragen if_num (name ; zahl). Jeder Zahlenwert ist bei Beginn Null.
Ein kurzer Dialog sähe so aus :

on (loop2)
{
  if_num (talknumber ; 0)
  {
    speech (figur1 ; Dialogtext 1)
    setnum (talknumber ; +1)
    wait (2)
  }
  if_num (talknumber ; 1)
  {
    speech (figur2 ; Dialogtext 2)
    setnum (talknumber ; +1)
    wait (2)
  }
  if_num (talknumber ; 2)
  {
    speech (figur1 ; Dialogtext 3)
    setnum (talknumber ; +1)
    wait (2)
  }
}

Nach jedem Satz wird die Nummer "talknumber" um 1 erhöht und dadurch sicher gestellt das bei einer Unterbrechung des Loop2 Teils der Dialog an der Stelle weiter geführt wird wo er unterbrochen wurde. Im TestAdventure ist das Reden des Obst- und Gemüseverkäufer durch eine Zufallszahl geregelt, welche mit dem Skriptbefehl randomnum (name ; obergrenze) erzeugt wird.


Ein Nummernpad erstellen

Ihr kennt sicher noch aus Zak McKrackon oder Maniac Manson die Nummernpads die meist 4 stellige Kombinationen von einem abverlangen. Für so ein Pad brauchen wir als erstes einen Raum der das Nummernpad enthält. Dieser Raum ist mit Objekten ausgestattet die für die Zahlen stehen. Zunächst müssen wir diesen Raum betreten, indem wir ein Keypad benutzen wollen. Für das Objekte welches das Keypad darstellt tragen wir also ein :

on (use)
{
  taskbar (false)
  setfocus (none)
  loadroom (keypad)
}

Wird ein Bedienfeld benutzt wollen wie dieses natürlich während wie das Keypad benutzen nicht sehen, deshalb schalten wir es mit taskbar (false) aus. Jetzt sind wir auf dem Keypad Raum. Um feststellen zu können wie oft bereits eine Ziffern gedrückt wurde, richten wir beim Betreten des Keypad Raumes eine Zahl ein, dazu tragen wir im Raumskript ein :

on (enter)
  setnum (click_count ; 1)

Für dieses Beispiel nehmen wir eine 3 stellige Kombination. In jedes Ziffernobjekt im Keypad Raum kommt nun folgendes hinein :

on (mouse)
  showinfo(Ziffer 1 ; false)

on (click)
{
  playsound (click)
  if_num (click_count ; 1)
    setnum (ziffer1 ; 1)
  if_num (click_count ; 2)
    setnum (ziffer2 ; 1)
  if_num (click_count ; 3)
    setnum (ziffer3 ; 1)
  setnum (click_count ; +1)
}

Je nachdem um den wievielten Click es sich handelt wird die entsprechende Ziffer abgespeichert. Für die anderen Ziffernobjekte müssen die Zahlen natürlich entsprechend geändert werden. Jetzt müssen wir noch im loop1 Teil des Raumskripts überprüfen ob 3 mal geclickt wurde und anschließend abbrechen und reagieren :

on (loop1)
  if_num (click_count ; 4)
  {
    setnum (click_count ; 5)
    if_num (ziffer1 ; 3)
      if_num (ziffer2 ; 7)
        if_num (ziffer3 ; 2)
          {
          cutscene (richtig)
          break()
          }
    cutscene (falsch)
  }

Wurde 3 mal gedrückt wird zunächst "click_count" nochmals hochgesetzt. So wird sicher gestellt das dieser Teil nur einmal überprüft wird.
Als nächstes wird das Ergebnis überprüft. Es kann mehrere richtige Kombinationen geben. Hierbei wird bei der Kombination 3, 7, 2 die Cutscene "richtig" abgespielt und sonst die Cutscene "falsch".

Um den Raum mit dem Keypad nun noch verlassen zu können muss in beiden Cutscenes drin stehen :

setfocus (last)
taskbar (true)

Und danach eure jeweilige Reaktion.


Einen Taschenlampeneffekt erstellen

Für einen Taschenlampen Effekt so wie er in Maniac Mansion auftaucht, braucht ihr eine Grafik die als solcher Lichteffekt dienen soll. (Im simpelsten Fall ein grauer Kreis, NICHT ganz WEISS). Füllt ein neues Objekt (Flashlight) mit diesem Bild und stellt "Additif blenden" auf ein. Setzt dieses Objekt in einen leeren welchen ihr im Gamesetup als "Überall Objekte"-Raum angebt, dadurch ist dieses Objekt überall im Spiel verfügbar. Ändert den Zustand des Objektes auf 0 damit es zu Beginn eures Spiels nicht aktiv ist.

Jetzt braucht ihr eine Bedingung um die Taschenlampe einzuschalten. Das hängt dann davon ab ob der Spieler überhaupt ne Taschenlampe hat, ob die Batterien voll sind ect. Nehmen wir mal an ihr habt einen Merker Namens "flashlighton" den ihr bei euren Bedingungen setzt. Im Hauptskript muss dann folgendes stehen :

if_bool (flashlighton ; true)
  setobj (flashlight ; 1)
if_bool (flashlighton ; false)
  setobj (flashlight ; 0)

setnum (posx ; [mousex])
setnum (posx ; -50)
setnum (posy ; [mousey])
setnum (posy ; -50)

moveobj (flashlight ; 0+[posx] ; 0+[posy] ; 0)

Erst wird geprüft ob das Objekt Flashlight angezeigt werden soll oder nicht. Anschließend wird die Position festgelegt. Erst auf die aktuelle Mausposition und dann um 50 Pixel nach oben bzw. nach links versetzt um es mittig zum Mauszeiger zu setzen. Hierbei gehen wir davon aus das das Objekt 100x100 groß ist.
Zuletzt wird das Objekt Flashlight bewegt zu [posx] und zu [posy] mit der Speed "0", was bedeutet das es sofort dort ist ohne Bewegung.


Variablen Nutzen

Inbesondere für Minigames und alle aufwendigeren Ideen die über dem normalen Adventuretreiben hinaus gehen ist der Umgang mit Variablen umabdinglich. PaC-DK bietet hierfür nicht nur die Merker welche bereits im Editor eingestellt werden, sondern es können auch Zahlen und Texte gespeichert werden. (Siehe auch Referenz unter : if_num und setnum.)

Random Zahlen : Minigames machen erst richtig sinn wenn die Dinge nicht in vordefinierter Reihenfolge passieren. Dazu gibts den randomnum Befehl.

Zahlen addieren und subtrahieren : Der setnum Befehl erlaubt nicht nur das setzen und addieren/subtrahieren von ganzen Zahlen sondern auch von anderen Zahlenwerten der Befehl dazu sieht dann so aus :

setnum (zahl1 ; +[zahl2])

Hier wird der Nummer "Zahl1" der Wert von "Zahl2" hinzugefügt. Die eckigen Klammern geben an das der zweite Wert eine Variable ist und keine Zahl. Auch möglich wäre das :

setnum (zahl1 ; [zahl2] - [zahl3] * 3)

Ist das Ergebniss einer solchen Berechnung keine ganze Zahl wird der Kommawert für weitere Berechnungen gespeichert oder kann auch in den Befehlen wait, timer und jiggle verwendet werden. Alle anderen Befehle werden aber bei Verwendung dieser Nummern mit dem gerundeten Zahlenwert gefüttert.
Neben den Rechenzeichen Plus (+), Minus (-), Multiplizieren (*) und Dividieren (/) gibt es noch (:) welches ebenfalls dividiert aber wie zuvor ein gerundetes Ergebniss speichert. (Das kann manchmal von Nöten sein)

Vergleichen : Mit dem if_num Befehl können nicht nur ganze Werte abgefragt werden sondern auch Größenordnungen in der Art wie :

if_num (zahl1 ; >20)

oder

if_num (zahl1 ; <[zahl2])

Texte speichern : Mit dem Befehl if_string und setstring lassen sich Textzeilen oder einzelne Wörter in Variablen ablegen :

Ausgabe von Variablen: Variablen können mit showinfo oder einem speech Befehl auch ausgegeben werden. Beispiel :

offspeech (10 ; 3 ; Punktestand : [score])

Auch hier werden Variablen mit eckigen Klammern eingefügt.

Wiederverwenden : Zahlen und Texte können mittels der eckigen Klammern in den meisten Anweisungen benutzt werden, Beispiel :

setstring (room ; firstroom)
setnum (red ; 120)
setnum (green ;200)
setnum (blue ; 25)

setlight ( [room] ; [red] ; [green] ; [blue] )

Vordefinierte Variablen : Es gibt einige Variablen die ebenfalls mit Klammern angegeben genutzt werden können :

[mousex] und [mousey] sind die aktuelle Mausposition in Pixeln. (Können als Einzige mit Setnum verändert werden)
[hour], [minute], [second] geben die aktuelle Zeit an.
[year], [month], [day] geben das aktuelle Datum an.
[currentroom] gibt einen String zurück mit dem Namen des momentanen Raums.
[roomx] und [roomy], geben die aktuelle Position des Raums zurück.
[charx] und [chary] sind die aktuelle Position des aktiven Characters in Pixel. [charzoom] gibt einen Kommawert der aktuellen größe des aktiven Characters zurück. 1 bedeutet der Character hat 100% Größe. 0.5 = 50% usw.
CharX, CharY und Charzoom können jetzt auch mit anderen Chars benutzt werden in der Form [charx:name] um so Position und Größe ALLER Charactere auslesen zu können.
[obj:object] gibt den aktuellen Zustand eines Objektes aus.
[objx:object] und [objy:object] geben die Position eines Objektes wieder.
[actiontext] enthält den Text der Aktionszeile um ihn alternativ in Form einer Textoutzeile auszugeben.
[empty] wird benutzt um zu prüfen ob ein String leer ist, also keinen Inhalt besitzt.


Verzögerte Ereignisse

Um ein Ereigniss zeitverzögert ablaufen zu lassen gibt es Timer. Benutzt werden diese so :

timer (sekunden)
  cutscene (irgendwas)

Nach der abgelaufenen Anzahl an Sekunden wird eine Cutscene gestartet. Es können maximal 10 Timer gleichzeitig aktiv sein. Pro Timer kann immer nur ein Befehl angehängt werden!! Bei Cut- und Textscenes werden alle Timer eingefroren und laufen bei normalen Spielablauf wieder weiter.


Eigenes Save/Load menu erstellen.

Seit Version 1.2 befindet sich im GameSetup das Feld "Eigenes Save/Load Menü verwenden". Dies gibt euch die Möglichkeit ein eigenes Menü zu erstellen das dann anstatt des Standardmenüs beim drücken der Escape Taste aufgerufen wird.
Hierzu verwendet ihr abermals einen Raum, den ihr auch im GameSetup angeben müsst. Dieser Raum funktioniert nun wie ein Subroom.

Durch die neuen Befehle savegame(slot), loadgame(slot), quit(), textspeed und textenabled könnt ihr Buttons erstellen (mit on(click) ereignissen) um euer Menü zum funktionieren zu bringen. Lediglich auf Namen für die Savegames müsst ihr verzichten.

Bedenkt das beim Beenden und Neustarten (durch quit und restart) des Spiels keine Abfrage mehr erfolgt, es sei denn ihr selbst baut eine ein, indem z.B euer Button für Quit nicht sofort quit() ausführt, sondern erst zwei andere Buttons sichtbar macht für Ja/Nein.
Außerdem : Die Ereignisse on(enter) und on(exit) funktionieren hier auch, ihr könnt also dafür sorgen das beim Aufruf eures Menüs das Menü zurück gestellt wird.


Ein Coin-Interface erstellen.

Erstellt einen Raum, am besten namens "Coin". Genauso wie ein Bedienfeld gestaltet ihr hier nun auch ein paar Buttons und vielleicht noch einen Hintergrund. Jeder Button enthält nun im Skript :

On (click)
command (look)

bzw. den Befehl den dieser Button auslösen soll. Das wars im Raum schon.

Im Projektsetup geht auf die Einstellungen des Coin-Interfaces und schaltet es ein. Gebt nun den Raumnamen an.
Autopopup sollte an sein es sei denn ihr wollt es immer selber einschalten. Dazu müsstet ihr in jeden Objekt drin haben :

on (rightclick)
popupcoin ()

Zum Schluss müsst ihr nun noch den Mittelpunkt des Menü anpassen, soll heißen der Punkt wo sich das Menü im Raum befindet. Dieser Punkt entscheidet auch wie das Menü erscheint zur Position der Maus.
Joa, das wars schon. Wer will ändert noch das Fading.


Particle Effekte

Für einen Particle Effekt benötigt ihr zunächst ein Objekt dessen verschiedene Zustände die Grafiken für die Particle enthalten. Der Befehl zum setzen des Effekts sieht z.B so aus :

setparticles (snow ; 4 ; 148 ; 30 ; 2 ; 35)

"snow" ist das verwendete Objekt.
"4" ist die Geschwindigkeit.
"148" ist die Menge der entstehenden Particle, wobei der Wert von 1 bis 151 reichen. Sinnvoll sind aber nur Werte ab 130 aufwärts.
"30" ist die Richtung. 0 würde gerade nach unten und 90 würde nach rechts bedeuten.
"2" ist die Drehung. Pro Frame dreht sich hiermit ein Particle um 2 Grad im Uhrzeigersinn.
"35" ist die Variation. Wenn ein Artikel entsteht kann es hiermit bis zu 35% langsamer oder schneller sein als der Speed Wert angibt.

Der Effekt wird gestartet mit startparticles ()" und wieder gestoppt mit stopparticles ()
Beide Befehle können auch mit einem (fast) in den Klammern versehen werden und den Effekt sofort aus- und einzuschalten.

Mit dem Befehl "Particleview" ist es außerdem möglich einen von 4 Darstellungsoptionen für Partikel zu wählen. Partikel können ganz vorne dargestellt werden aber auch hinter diversen Objekten um zum Beispiel Regen durch ein Fenster betrachten zu können.

Je nach Einstellungen können die Particle die FPS Zahl ordentlich in den Keller drücken also seit sparsam.


Sprachen hinzufügen

Seit Version 2.2 gibt es ein Tool in PaC-DK welches das Übersetzen eines Spiels kinderleicht macht. Seht dazu unter "Der Editor" - "Das Sprachtool"


FX Shapes :

Seit Version 2.3 bietet PaC-DK eine sogenannte FX-Shape Funktion, die einzelnen sollen hier nun beschrieben werden.

Bodenspiegel : Diese Fläche kopiert alle Character als Spiegeleffekt in den Boden hinein. Dieser Effekt ist natürlich nicht wirklich echt, da es ja nur eine 2D Täuschung ist. Dies hat zur Folge das die Frage, ob der Effekt gut rüber kommt, auch von den verwendeten Grafiken abhängt.

Zum einen ist da der Character an sich. Wenn ihr ganz genau hier links auf die Füße schaut werdet ihr die Unstimmigkeit sehen können an den Fersen. In der Regel ist das nicht weiter tragisch und fällt kaum auf.
Der Bodenspiegel-Effekt wird nach den "HINTEN" Objekten dargestellt. Wollt ihr also zum Beispiel einen Teppich auf den Boden legen, dann fügt ihn als Objekt mit dem Status "MITTE" in den Raum ein. Der Character läuft darüber die Spiegelung aber wird verdeckt.

Habt ihr im Bereich des spiegelnden Bodens auch Objekte stehen, welche selber sich im Boden spiegeln, müsst ihr die Spiegelung seperat als Objekt so wie auch den Teppich hinzufügen, damit der Character sich nicht darauf spiegelt.

Wenn ihr darüber hinaus auch bewerkstelligen wollt, das die Figur über diese Fläche wo sich das Objekt spiegelt, gehen kann, müsst ihr zusätzlich noch mit Walkmapskripten das Spiegelobjekt aus- und anzuschalten, so das die Figur sich in dem Bereich spiegelt wenn sie VOR dem Objekt steht oder eben die Spiegelung überdeckt wird wenn die Figur HINTEN dem Objekt steht.

Am einfachsten ist es natürlich soetwas von vorne rein zu vermeiden indem man keine stehenden Objekte auf eine Bodenspiegelfläche stellt ;)
Um im Bodenspiegel auch Türen die sich öffnen zu sehen benutzt ihr dann Objekte mit dem Status hinten.


Wandspiegel : Auch der Wandspiegel ist natürlich nur eine 2D Täuschung. Es wird eine richtungsmäßig umgedrehte Version des Characters in die Wand kopiert und zwar so als würde sich weiter hinten im Raum stehen.

Ihr habt beim Wandspiegel die Möglichkeit die X Position der Spiegelung von der Raumposition abhängig zu machen. Dies ist auf jeden Fall empfohlen das es echter aussieht. Da der Character in die Ferne kopiert wird ist es notwendig das die Tiefenmap nicht an der unterseite der Wand aufhört sondern bis ganz nach oben geht. Ansonsten würde der Character nicht verkleinert gespiegelt werden.

Ein Wandspiegel FX-Shape besitzt wie ein Objekt mit der Darstellungsart "Mitte" einen Mittelpunkt der verändert werden kann. Dieser muss dort palziert werden wo die Figur am nächsten an den Spiegel herantreten kann. Wenn die Spiegelungen euch zu weit oben erscheinen setzt diesen Mittelpunkt weiter nach unten. Kleine Korrekturen können mit der Positionseinstellung vorgenommen werden, welche ihr unten links im Raumfenster seht wenn FX-Shapes aktiviert sind.

Gespiegelt wird immer das Gegenstück zur aktuellen Aktion des Characters. Steht er nach vorne schauend und redet wird er im Spiegel nach hinten schauen und reden (sofern vorhanden). Bei den Extra-Animationen wird ein Character immer mit Ansicht von hinten gespiegelt, da es ja keine Gegenstücke zu den Extra-Animationen gibt. Ihr solltet also zusätzliche Animationen nicht vor einem Wandspiegel ablaufen lassen. Dürfte doof aussehen.

Um etwas auf einen Wandspiegel zu setzen (zum Beispiel eine Aufschrift) müsst ihr dies als Objekt mit der Darstellungsart "Mitte" auf den Spiegel setzen. Der Mittelpunkt dieses Objektes muss auf gleicher höhe mit dem des Wandspiegeleffektes sein, damit das Objekt genau zwischen Figur und Spiegelung steht.


Partikel Barriere : Eine Partikel Barriere "löscht" Partikel die mit ihr in Berührung kommen.

Wie hier im Bild zu sehen läßt sich durch eine solche Barriere ein Wetter Effekt an bestimmten Stellen ausgrenzen. Um den Effekt optisch richtig zu gestalten, sollte das FX Shape etwas größer als die tatsächliche Begrenzung in der Grafik sein. Zusätzlich kann noch die Darstellung der Partikel mit dem Befehl "Particleview" so geändert werden das noch ein Objekt mit dem Status "VORNE" an dieser Stelle plaziert wird damit man nicht direkt sieht wie ein Partikel einfach verschwindet, sondern er läuft nicht sichtbar hinter das Objekt.




Skriptfunktionen nutzen

Wenn Adventure aufwendiger und länger werden, wird auch meistens mehr Skriptaufwand betrieben. Kommt es vor das ein paar Skriptzeilen öfter als an einer Stelle im Spiel verwendet werden, ist es hilfreich eine Skript-Funktion zu nutzen und sich das stetige rumkopieren dieser Zeilen zu sparen.

Wie funktioniert das? Eine Funktion ist ein erstelltes Skript das mit dem Befehl function (skriptname) ausgeführt wird. Im Gegensatz zu einer Cutscene läuft das Spiel aber normal weiter. Eine Funktion ist eher für Berechnungen gedacht als für Spielereignisse.

Beispiel : Ihr habt in eurem Spiel rollenspieltypische Werte wie HP und MP untergebracht. Diese Werte werden ja im ganzen Spiel verändert. Will man nun das die Anzeige dieser Werte eine entsprechende Farbe hat (rot = wenig, blau = viel) muss man ein paar Berechnungen durchführen um den richtigen Farbwert zu erhalten (Das Downloadbare Beispiel "Textout Demo" zeigt dies) Um diese Berechnungen nun nicht überall dort wo die Werte verändert werden mit einbringen zu müssen, schreibt man sie einfach in ein Skript rein und muss sich anschließend nur noch mit function (textcolor) ausführen.

Loopende Funktionen : Will man einen Skriptteil haben der sich im ganzen Spiel raumunabhängig wiederholt wiederholt, musste man auf das Hauptskript zurückgreifen. (siehe z.B das Taschenlampentutorial) Soll so ein Teil aber nicht das ganze Spiel über ablaufen musste man solche Passagen bisher im Hauptskript durch eine Variable ausklammern. Der Nachteil : Wenn es mehrere solcher Teile wurden, war das Hauptskript schnell voll damit. Die Lösung ist eine loopende Funktion : function (skriptname ; infinitly) läßt eine Funktion sich solange wiederholen bis man sie mit stopfunction wieder anhält, was wesentlich eleganter ist.


Einen Aufzug Effekt erstellen

In eurem Spiel könnte es vorkommen das ihr einen Character per Aufzug oder einer Platform von einem Ort zum anderen bewegen wollt. Der Knackpunkt hierbei ist es ja das eure Figur sich selber dabei nicht bewegen soll, sie soll also getragen werden und nicht gehen.

Für so ein Vorhaben gibt es seit Version 2.7.3 die Befehle Linkchar und Unlinkchar, welche es ermöglichen eine Figur mit einem Objekt zu verknüpfen, bewegt sich das Objekt (per MOVEOBJ) bewegt sich der Character mit führt aber keine Animationen aus. Er kann während er gelinkt ist auch nicht vom Spieler bewegt werden.

Was ihr dabei beachten solltet : Damit ein Character nicht nach hinten zoomt, also kleiner wird wenn er von einem Aufzug Objekt nach oben getragen wird verwendet den Befehl stopzooming. Während eine Figur von einem Objekt "getragen" wird ist es egal ob die Walkmappunkte über die sie sich bewegt frei sind oder nicht, ABER : An dem Punkt wo euer Character steht wo ihr ihn mit unlinkchar wieder frei gebt muss der Walkmappunkt schon frei sein, sonst hängt er fest.

Zum Betrachten eines Beispiels seht euch den 8. Raum der Funktionsdemo an.


In-Game Zeitmessung

Um in einem Adventure die Spiellaufzeit messen zu können, könnt ihr folgendes machen.
Erstellt ein Skript mit dem Namen "gameclock" und füllt es hiermit :
setnum (frames ; +1)

if_num (frames ; 50)
  {
  setnum (frames ; 0)
  setnum (seconds ; +1)
  }

if_num (seconds ; 60)
  {
  setnum (seconds ; 0)
  setnum (minutes ; +1)
  }

if_num (minutes ; 60)
  {
  setnum (minutes ; 0)
  setnum (hours ; +1)
  }

Es ist wichtig das ihr diese Variablen nicht second oder minute nennt weil diese feste Variablen für die Systemzeit sind.
Ins Startskript kommt folgendes um die Werte auf 0 zu setzen :
setnum (frames ; 0)
setnum (seconds ; 0)
setnum (minutes ; 0)
setnum (hours ; 0)

Um die aktuelle Spielzeit anzuzeigen :
textout (1 ; Spielzeit : [hours]:[minutes]:[seconds] ; x ; y... ect)

Diese Zeitmessung kann nun ein- und ausgestellt werden mit :
function (gameclock ; infinity) und
stopfunction (gameclock)

Um Ereignisse von der Spielzeit abhängig zu machen fragt einfach die Variablen ab...
if_num (hours ; >1)
z.B läßt etwas nach 2 Stunden Spielzeit passieren.



Eigene Aktionszeile erstellen

- Schaltet im Projektsetup die standard Aktionszeile aus.
- Dort wo eure eigene Zeile sein soll, setzt eine Textoutzeile (direkt im Startskript) welche die Variable [actiontext] beinhalten muss.
- Bindet die Textoutzeile ggfs, dort wo ihr sie haben wollt und passt sie an.
- Verwendet den Befehl textalign auf Wunsch um die Zentrierung der Zeile zu ändern. (Die standard Aktionszeile ist ja auch mittig.)



Skripte in Animationen

In Gegenständen, Objekten und Charaktern kann man pro einzelnem Frame einer Animation eine Skriptzeile eingeben.

Die einfachste Verwendung dieser Skriptzeilen wäre das Abspielen einer Sounddatei zu einem bestimmten Zeitpunkt der Animation. Hierfür gibt es eine einfach Möglichkeit : Einfach eine Sounddatei direkt auf einen Frame per Drag&Drop ziehen und es wird automatisch ein Playsound Befehl erstellt.
Weitere Einsatzmöglichkeiten : Ein Objekt färbt sich selbst um mittels setobjlight, ein Charakter erzeugt bei seinen Schritten Erschütterungen mit jiggle oder ein Objekt bewegt sich mit moveobj selbsttätig durch die Gegend.

Generell gilt : Wird, als Beispiel, die Farbe eines Objektes im Zustand 2 wechselnd geändert muss im ersten Frame des Zustands 1 dafür gesorgt werden das die Farbe wieder auf den Ursprung gesetzt wird, da nicht bestimmt werden kann zu welchem Zeitpunkt in einer ablaufenden Animation der Zustand gewechselt wurde.



Sonstiges

Objekte Bewegen : Mit dem Befehl Moveobj könnt ihr Objekte in eine Richtung ziehen lassen. Mit if_xobj und if_yobj könnt ihr die aktuelle Position abfragen.

Tastatur abfragen : Mit dem Befehl if_keydown und if_keypressed kann die Tastatur für Minigames mit verwendet werden.

Objekt Gruppen : Mit dem Befehl group lassen sich bis zu 20 Objekte zu einer Gruppe verbinden. Dieser Gruppenname kann dann mit setobj und moveobj verwendet werden um alle Objekte in einer Gruppe auf einmal zu bewegen oder zu verändern.