Construction Set Morrowind-Scriptkurs - Lektion 4

Dieses Thema im Forum "[MW] Plugins und Mods" wurde erstellt von Killfetzer, 15. November 2010.

  1. Killfetzer

    Killfetzer Super-Moderator Mitarbeiter

    4. Bewegung von Objekten - Teil 1

    Heute beschäftigen wir uns zum ersten Mal mit der Bewegung von Objekten. Dies ist natürlich ein riesiges Thema, deswegen gibt es heute nur den ersten Teil.

    Man kann mit der Bewegung von Gegenständen eine größere Interaktivität in Modifikationen bringen. Statt einer Teleporttür kann man auch ein sich bewegendes Fallgitter oder statt einer Treppe einen Lift benutzen. Um genau diese Dinge wird es heute gehen.


    Tatsächlicher Ablauf von Scripten

    Zunächst einmal müssen wir ein wenig Theorie über Scripte in Morrowind machen. Für die bisherigen Scripte war es nicht wichtig, wie genau Morrowind Scripte behandelt, jetzt wird dies mit eine entscheidende Bedeutung bekommen.

    Morrowind lässt jedes Script, dass sich auf irgendeinem Gegenstand in der aktuellen Zelle befindet in jedem Frame (fps = Frames per Second, also (Halb-)Bilder pro Sekunde) einmal durchlaufen. Auf den meisten Rechnern wird also jedes Script einige Dutzend Male pro Sekunde ausgeführt!

    Was ziehen wir daraus für Schlussfolgerungen? Zum Ersten muss ein Script nicht erst aktiviert werden, es läuft automatisch, sobald man die Zelle des entsprechenden Objekts betritt. Das ist normalerweise sehr praktisch, wie wir gleich sehen werden. Zum Zweiten muss man aber auch sicherstellen, dass Aktionen nur einmal ausgeführt werden und nicht in jedem Frame erneut beziehungsweise das genaue Gegenteil, nämlich eine Funktion jeden Frame aufzurufen.


    Bewegung von Gegenständen

    Nur Gegenstände erscheinen und verschwinden zu lassen, wird natürlich schnell langweilig, man möchte sie auch bewegen. Wie funktioniert Bewegung in Morrowind? Genau genommen gibt es keine echte Bewegung. Objekte werden in jedem Frame an eine leicht veränderte Position gesetzt. Da das menschliche Auge aber nur etwa 20 Bilder pro Sekunde sehen kann (und wir hoffentlich eine viel höhere Framerate haben), nehmen wir diese vielen kleinen Sprünge als kontinuierliche Bewegung wahr.

    Da Morrowind seine Scripte sowieso jeden Frame ausführt, nutzen wir dies bei Bewegungen, wir lassen die Bewegungsfunktion einfach in jedem Durchlauf des Scripts eine kleine Bewegung machen. Allerdings gibt es auch immer Situationen, in denen man keine Bewegung haben möchte. Zum Beispiel pausieren die normalen Animationen, wenn man sich im Inventar befindet, Scripte nicht. Also müssen wir dieses Pausieren per Hand erzeugen.

    MenuMode

    Dazu gibt es die äußerst praktische Funktion MenuMode. Diese liefert immer dann eine 1, wenn irgendein Menü geöffnet ist. Ob dies nun das Spielmenü (ESC), das Inventar, ein Dialog oder eine Messagebox ist, macht keinen Unterschied. Mit folgender Konstruktion kann man die Ausführung eines Scripts unterbrechen, wenn ein Menü geöffnet wird:

    Code:
    if ( MenuMode == 1 )
      return
    endif
    
    Dies ist einer der wichtigsten Codebrocken in Morrowind Script. In vielen Scripten ist dies der erste Block, der nach der Variablendeklaration steht.

    Move
    MoveWorld


    Die Bewegung in Morrowind findet in einem dreidimensionalen, kartesischen Koordinatensystem statt (ja, das ist Mathe ;)). Die Achsen dieses Koordinatensystems werden mit X, Y und Z bezeichnet. X läuft dabei von West nach Ost (in Außenzellen), Y von Süd nach Nord (in Außenzellen) und Z von unten nach oben.
    Außerdem unterscheidet Morrowind zwischen einem absoluten und einem relativen Koordinatensystem. Das absolute Koordinatensystem ist das der Welt mit den Eigenschaften, die oben beschrieben sind. Für jedes Objekt existiert aber auch ein eigenes relatives Koordinatensystem. In diesem sind die Achsen entsprechend der Drehung des Objekts in der Welt mitgedreht.

    [​IMG]

    Vergleich des absoulten Welt-Koordinatensystems (schwarz) und des relativen Koordinatensystems eines Gegenstands (rot).
    Das relative Koordinatensystem mit X' und Y' ist aus einer Drehung des Gegenstandes um die Z-Achse um 45° entstanden.

    Wenn das Objekt nicht gedreht ist (also alle Winkel gleich 0 sind), sind das absolute und das relative Koordinatensystem gleich.

    Die beiden Funktionen Move und MoveWorld werden so aufgerufen:

    Code:
    Move, axis, value
    MoveWorld, axis, value
    
    ---
    
    Move, Z, 100
    MoveWorld, X, -200
    
    Diese Funktionen bewegen das aufrufende Objekt mit der in value angegebenen Geschwindigkeit bezüglich der in axis angegebenen Achse. Für axis werden die Buchstaben X, Y und Z akzeptiert. value verarbeitet float-Werte, es können aber auch beliebige andere Werte angegeben werden. Die Werte werden als Editoreinheiten pro Sekunde interpretiert. Tatsächlich wird bei jedem Aufruf nur der entsprechende Bruchteil der Bewegung ausgeführt, die der Zeit seit dem letzten Frame entspricht. Um eine kontinuierliche Bewegung zu erreichen, muss die Funktion also jeden Frame aufgerufen werden. value akzeptiert (leider) keine Variablen!
    Die Funktionen haben keine Auswirkungen auf NPCs, Kreaturen oder den Spieler.

    Move bewegt das Objekt entlang der relativen Achse. Diese Funktion kann zum Beispiel dafür benutzt werden, dass sich ein Pfeil immer in die Richtung seiner Spitze bewegt, egal in welche Richtung er gedreht ist.

    MoveWorld bewegt das Objekt entlang der absoluten Achse. Diese Funktion wird weitaus häufiger benutzt werden und sorgt zum Beispiel dafür, dass sich ein Objekt immer nach oben bewegt, unabhängig davon wie es gedreht ist.

    Im obigen Beispiel ist das Objekt um 45° um die Z-Achse gedreht worden. Ein Move, X, 100 würde das Objekt entlang der rotmarkierten X'-Achse bewegen. Die Funktion MoveWorld, X, 100 hingegen bewegt das Objekt entlang der schwarzen X-Achse.

    Um ein Gefühl für die Geschwindigkeit zu bekommen, muss man wissen, dass eine Editoreinheit 1,42 cm entspricht. Also entsprechen etwa 20 Editoreinheiten pro Sekunde einem km/h. Geschwindigkeiten über 400 Editoreinheiten pro Sekunde (20 km/h) sollten vermieden werden, weil sie meistens abgehackt aussehen, da die Abstände zwischen den einzelnen Sprungpositionen zu groß werden.

    Nun können wir also eine Bewegung starten, wir können sie sogar pausieren, wenn ein Menü geöffnet wird, aber so wird das Objekt eine endlose Bewegung ausführen und irgendwann im Nichts verschwinden. Wie können wir die Bewegung also aufhalten?

    Dazu stehen uns grundsätzlich zwei Optionen zur Verfügung. Entweder stoppen wir die Bewegung, wenn das Objekt einen bestimmten Punkt erreicht hat oder wir lassen die Bewegung nur eine bestimmte Zeit lang laufen.

    GetPos

    Mit dieser Funktion kann man die Position des aufrufenden Objekts bezüglich der angegebenen Achse abfragen:

    Code:
    float xpos
    
    set xpos to GetPos, X
    
    Statt dem X kann man natürlich auch wieder Y und Z abfragen. Der Rückgabewert der Funktion ist eine float-Größe (also eine Dezimalkomma-Zahl). Über eine if-Abfrage kann man nun prüfen, ob das Objekt bereits an seinem Zielpunkt angelangt ist (natürlich funktioniert hier auch ein while, aber das will ich heute nicht auch noch einführen). Hier ein Beispielscript:

    Code:
    begin kf_sk_bewegung_bsp1_script
    
    short state
    float zpos
    
    if ( MenuMode == 1 )
      return
    endif
    
    if ( state == 0 )
      if ( OnActivate == 1 )
        MessageBox, "Nach oben!"
    
        set zpos to GetPos, Z       ;berechne eine obere Schranke für die Bewegung
        set zpos to zpos + 300
    
        set state to 1
      endif
    elseif ( state == 1 )
      if ( GetPos, Z <= zpos )
        MoveWorld, Z, 100
      else
        set state to 2          ;sorgt dafür, dass man nur einmal nach oben fahren kann
      endif
    endif
    
    end
    
    Statt der Konstruktion mit zpos könnte man natürlich auch direkt die Koordinaten aus dem CS einsetzen, die man sich als Zielpunkte ausgesucht hat. Diese Formulierung ist aber universell anwendbar, da ich ja nicht weiß, wo in der Spielwelt ihr das Script ausprobieren wollt.

    GetSecondsPassed

    Die zweite Möglichkeit, um Bewegung zu begrenzen, liegt in der Zeitmessung. Bisher kennen wir dafür die globale Variable GameHour, hiermit ist es aber nicht möglich wirklich kurze Zeitspannen genau zu messen. Dafür gibt es die Funktion GetSecondsPassed. Diese liefert die vergangenen Sekunden(-bruchteile) seit dem letzten Frame zurück. Dies stellt die einzige Scriptmöglichkeit dar, kurze Zeitspannen zu messen. Hier noch einmal ein Script mit der gleichen Funktion wie oben, diesmal mit GetSecondsPassed implementiert:

    Code:
    begin kf_sk_bewegung_bsp2_script
    
    short state
    float timer
    
    if ( MenuMode == 1 )
      return
    endif
    
    if ( state == 0 )
      if ( OnActivate == 1 )
        MessageBox, "Nach oben!"
        set state to 1
      endif
    elseif ( state == 1 )
      set timer to timer + GetSecondsPassed
      MoveWorld, Z, 100
      if ( timer >= 3 )    ;3 Sekunden mal 100 Einheiten pro Sekunde = 300 Einheiten nach oben
        set state to 2          ;sorgt dafür, dass man nur einmal nach oben fahren kann
      endif
    endif
    
    end
    

    Aufgaben

    1. Probiert die Beispielscripte aus und versteht, wie sie funktionieren.
    2. Erstellt einen einfachen Aufzug, der ständig hoch und runter fährt und an jedem Ende jeweils kurz anhält.
    3. Probiert, was passiert, wenn ihr die MenuMode-Abfrage weglasst und auf dem Aufzug das Inventar öffnet.
    4. Warum muss timer im zweiten Beispielscript eine float-Variable sein?
    5. Erstellt einen Activator, der euch beim Aktivieren die aktuelle Framerate (fps) ausgibt.
    6. Erstellt einen Aufzug, der anfangs still steht. Wenn er aktiviert wird, bewegt sich der Aufzug nach oben, wartet dort einen Moment und fährt wieder runter.
    7. Erstellt einen Aufzug, der nach Aktivieren nach oben beziehungsweise unten fährt und dort bleibt, bis er erneut aktiviert wird. Danach fährt er wieder in seine andere Position und wartet dort.

    Lösungen

    [hr]-[/hr]

    Im nächsten Teil beschäftigen wir uns mit der Rotation von Gegenständen. Dies ist quasi nur eine Wiederholung der Bewegungsfunktionen, da sie prinzipiell identisch funktionieren. Außerdem werden wir Gegenstände aus der Ferne bewegen beziehungsweise die Bewegung eines Objekts von einem anderen steuern lassen.
     
    Zuletzt bearbeitet: 30. April 2011
    Mercarryn gefällt das.
  2. Werbung (Nur für Gäste)
  3. Diarrhoe

    Diarrhoe Vertrauter

    Zu deinen Beispielskripten:
    Ich verstehe die Funktionen im Moment so, dass sie das Objekt in jedem Frame um den angegebenen Wert verschieben. Ist das nicht ein bisschen unbequem, da die Framerate auf jedem Rechner zu anderen Zeiten unterschiedlich ist? In meiner Theorie müsste ich den Wert also noch mit "getSecondsPassed" multiplizieren, um das Objekt um den angegebenen Wert in einer Sekunde zu bewegen.

    Der Timer muss eine Float sein, weil er sonst bei
    Code:
    set timer to (timer + getSecondsPassed)
    immer gleich bleiben würde (es sei denn die Framerate ist so gering, dass Morrowind nichtmal ein Bild pro Sekunde schafft :roll: ).

    Code:
    Begin welche_framerate
    
    float fps
    
    if onActivate
     set fps to (1 / getSecondsPassed)
     messagebox "Die aktuelle Framerate beträgt %.0f FPs", fps
    endif
    
    end

    Der Rest folgt, wenn mein Einwand geklärt ist...
     
  4. Killfetzer

    Killfetzer Super-Moderator Mitarbeiter

    Gut mitgedacht :)
    Aber nein, dass macht die Move-Funktion schon alleine. Du gibst Geschwindigkeit pro Sekunde an. Die Umrechnung wie viel das Objekt dann in jedem Frame bewegt werden muss, stellt die Funktion schon alleine an. Irgendwas muss die ja auch noch tun ;)

    Deine Lösungen passen, auch wenn dein Script äußerst unschön formatiert ist. Dass es läuft, ist in dem Fall wohl eher zufallsabhängig, wenn ich mir überlege, wie kleinlich Morrowind Script sonst mit fehlenden Klammern ist. :p
     
  5. Diarrhoe

    Diarrhoe Vertrauter

    Ach, das steht ja sogar in dem Text... Hab ich wohl überlesen.
    Dann folgen mal die anderen Aufgaben:

    Code:
    Begin Lift_Loop
    
    short break
    short state
    float timer
    
    if MenuMode
     return
    endif
    
    set timer to (timer + getSecondsPassed)
    if break
     if timer >= 3   [COLOR="Red"]; 3 Sekunde Pause[/COLOR]
      set break to 0
      set timer to 0
     else
      return
     endif
    endif
    
    if state
     moveWorld z, -50
     if timer >= 10  [COLOR="Red"]; 10 Sekunden Abwärtsbewegung[/COLOR]
      set break to 1
      set state to 0
      set timer to 0
     endif
    else
     moveWorld z, 50
     if timer >= 10  [COLOR="Red"]; 10 Sekunden Aufwärtsbewegung[/COLOR]
      set break to 1
      set state to 1
      set timer to 0
     endif
    endif
    
    end

    Code:
    Begin Lift_Activate_Once
    
    short activated
    short state
    short break
    float timer
    
    if MenuMode
     return
    endif
    
    if activated
     set timer to (timer + getSecondsPassed)
     if break
      if timer >= 3
       set break to 0
       set timer to 0
      else
       return
      endif
     endif
    
     if state
      moveWorld z, -50
      if timer >= 10
       set state to 0
       set activated to 0
       set timer to 0
      endif
     else
      moveWorld z, 50
      if timer >= 10
       set state to 1
       set break to 1
       set timer to 0
      endif
     endif
    
    else
     if onActivate
      set activated to 1
     endif
    endif
    
    end

    Code:
    Begin Lift_Activate_Twice
    
    short activated
    short state
    float timer
    
    if MenuMode
     return
    endif
    
    if activated
     set timer to (timer + getSecondsPassed)
     if state
      moveWorld z, -50
      if timer >= 10
       set activated to 0
       set state to 0
       set timer to 0
      endif
     else
      moveWorld z, 50
      if timer >= 10
       set activated to 0
       set state to 1
       set timer to 0
      endif
     endif
    else
     if onActivate
      set activated to 1
     endif
    endif
    
    end
     
  6. £exa

    £exa Freund des Hauses

    Ich hab mal aus dem Kopf gecoded... hoffentlich hab ich in der Eile nichts übersehen... :-D
    Code:
    Begin Lift_AutoUpDown
    short State
    float Timer
    
    IF ( MenuMode != 0 ) ;im Menu nichts machen
      return
    EndIF
    
    set Timer to (Timer + GetSecondsPassed )
    
    IF ( State < 0 )
      IF ( Timer < 3 )
        return
      EndIF
      set State to ( State * State )
      set Timer to 0
    EndIF
    
    IF ( State == 4 )
      moveWorld z, -50
    Else
      moveWorld z, 50
    EndIF
    
    IF Timer >= 10)
      set Timer to 0
      IF State == 4 )
        set State to -1
      Else
        set State to -2
      EndIF
    EndIF
    
    end
    Antwort:
    Weil das Schreiben in eine Short/Long Variable den Dezimalteil automatisch abschneidet. Der Timer würde sich damit nicht verändern, es sei denn die fps wäre so unterirdisch, dass GetSecondsPassed ganzzahlige Werte liefert...
    Code:
    Begin Lift_UpDownOnPush
    short State
    float Timer
    
    IF ( MenuMode != 0 ) ;im Menu nichts machen
      return
    ElseIF ( State == 0 )
      IF ( OnActivate == 0 )
        return  
      EndIF
      set State to 1
    EndIF
    
    set Timer to (Timer + GetSecondsPassed )
    
    IF       ( State == 1 )
      MoveWorld Z 50
    ElseIF ( State == 2 )
      IF ( Timer >= 3 )
        set Timer to 10
      EndIF
    ElseIF ( State == 3 )
      MoveWorld Z -50
    EndIF
    
    IF ( Timer >= 10 )
      set Timer to 0
      set State to ( State + 1 )
      IF ( State == 4 )
        set State to 0
        SetAtStart
      EndIF
    EndIF
    
    end
    Code:
    Begin Lift_MoveOnPush
    short State
    short Direction
    float Timer
    
    IF ( MenuMode != 0 ) ;im Menu nichts machen
      return
    ElseIF ( State == 0 )
      IF ( OnActivate == 0 )
        return  
      EndIF
      set State to 1
    EndIF
    
    set Timer to (Timer + GetSecondsPassed )
    
    IF ( Direction == -1 )
      MoveWorld Z -50
    Else
      MoveWorld Z 50
    EndIF
    
    IF ( Timer >= 10 )
      set State to 0
      set Timer to 0
      IF ( Direction == -1 )
       set Direction to 1
      Else
       set Direction to -1
      EndIF
    EndIF
    
    end
     
    Zuletzt bearbeitet: 15. November 2010
  7. Teridan

    Teridan Mr. Morrowind 2007

    Oh man, die Aufgaben sind ja höllisch schwer. Ich bin dran, also noch nicht auflösen oder gar die fünfte Lektion starten.

    a. Ich will das in meinem Script über die genauen Koordinaten machen, wie muss der GetPos-Befehl dann aussehen? Ich stelle mir das nämlich leichter vor, denn dann muss ich nur die Koordinaten eingeben, anstatt einzuschätzen, wieviele Einheiten, also cm der Weg von Punkt A zu Punkt B wohl sind.
    b. Eine Verständnisfrage: Im ersten Beispielscript geht das Objekt so lange um 100 Einheiten nach oben, bis die 300 erreicht ist, oder? Also 3 mal, also drei Frames, oder?
    c. Ich habe erstmal einen Aufzug ohne Timer gebaut (ja, ich bin noch bei dem ersten Aufzugsversuch), der als Grundgerüst für die Varianten der anderen Aufgaben dienen soll. Aber das Ding wackelt nur munter vor sich hin. Was mache ich falsch?
    Code:
    Begin Teri_L4_Aufzug1_Script
    
    short status
    float unten
    float oben
    
    if ( MenuMode == 1 )
      return
    endif
    
    if ( status == 0 )
        set oben to GetPos, Z
        set oben to oben + 300
        set unten to GetPos, Z
        set unten to unten - 300
        set status to 1
    elseif ( status == 1 )
        if ( GetPos, Z <= oben )
            MoveWorld, Z, 100
        endif
        set status to 2
    elseif ( status == 2 )
        if ( GetPos, Z >= unten )
            MoveWorld, Z, -100
        endif
        set status to 1
    endif
    
    End Teri_L4_Aufzug1_Script
     
  8. Killfetzer

    Killfetzer Super-Moderator Mitarbeiter

    Keine Angst, ich weiß, dass es ab dieser Lektion einiges schwerer wird ;)

    Das mit den Zentimetern ist doch nur eine Orientierung für euch, dass ihr es mit Größen aus der realen Welt vergleichen könnt. Im CS rechnet ihr natürlich in Editoreinheiten. Die könnt ihr ja immer in der Statusleiste am unteren Rand des Fensters sehen.

    Deine Frage mit dem GetPos verstehe ich nicht ganz, aber wenn du keine Variable verwenden willst, würde es (zum Beispiel) so aussehen:

    if ( GetPos, Z < 12345 )

    Nein. Die 100 bezeichnet die Editoreinheiten pro Sekunde und nicht pro Frame. In einer Sekunde gibt es in Morrowind normalerweise so zwischen 20 und 80 Frames (je nach Rechner). Sagen wir einfach mal 25 Frames pro Sekunde. Dann wird das Objekt mit 100 Einheiten pro Sekunde = 100 Einheiten pro Sekunde geteilt durch 25 Frames pro Sekunde = 4 Einheiten pro Frame bewegt.

    Dein Script sieht schon ganz gut aus. Du hast nur einen kleinen Fehler gemacht. Du erreichst die Zeile set status to 2 bereits im ersten Durchlauf und nicht erst, wenn die Position überschritten ist. Also bewegst du den Aufzug ein Stück nach oben, schaltest dann auf die Abwärtsbewegung um, bewegst ein winziges Stück nach unten und schaltest dort direkt wieder auf die Aufwärtsbewegung um.

    Diesen staus-Wechsel musst du mit einem else in deinen if-Block mit dem Move einbringen.
     
    Teridan gefällt das.
  9. Teridan

    Teridan Mr. Morrowind 2007

    Das hat mir schon weitergeholfen, durch das eingebaute Else funktioniert es jetzt ziemlich gut. Der Aufzug versinkt zwar kurz im Boden, aber da muss ich an den Werten noch etwas feinjustieren. ;)

    Da ich wie gesagt auf die Variablen verzichten wollte, habe ich ein neues Probelm:

    Code:
    Begin Teri_L4_Aufzug1_Script
    
    short status
    
    if ( MenuMode == 1 )
      return
    endif
    
    set status to 1
    
    if ( status == 1 )
        if ( GetPos, Z <= 473.000 )
            MoveWorld, Z, 100
        else
            set status to 2
        endif
    elseif ( status == 2 )
        if ( GetPos, Z >= 109.000 )
            MoveWorld, Z, -100
        else
            set status to 1
        endif
    endif
    
    End Teri_L4_Aufzug1_Script

    Der Aufzug geht nun nach oben und hält auch genau an der Stelle, an der er halten soll. Allerdings kommt er nicht wieder runter. :huh:
     
    Zuletzt bearbeitet: 21. November 2010
  10. Diarrhoe

    Diarrhoe Vertrauter

    Ich würde sagen, das liegt daran, dass du direkt nach der MenuMode-Abfrage "status" auf 1 setzt. Bei der entsprechenden "if"-Schleife ist "status" also nicht 2. Du könntest also entweder eine zusätzliche Variable einfügen, die dafür sorgt, dass "status" am Anfang nur einmal auf 1 gesetzt wird oder du schreibst die Abfragen dahinter anders (mit "status == 0" und "status == 1").
     
  11. Killfetzer

    Killfetzer Super-Moderator Mitarbeiter

    Ich hab lange überlegen müssen, bis ich den Fehler gefunden habe. Gehen wir das Script doch mal durch:

    • Das Hochfahren klappt ja, also springen wir direkt auf den Punkt an dem das GetPos, Z < 473 nicht mehr erfüllt ist. In dem Fall geht das Script in den else-Zweig und setzt status auf 2. Danach überspringt das Script den Rest und geht wieder an den Anfang.
    • Das Menü ist nicht offen, also wird über diesen Punkt hinweggesprungen. Danach wird der status auf 1 gesetzt.
    • Das Script kommt zur Abfrage state == 1. Die ist ja inzwischen wieder wahr, das Script geht also wieder in die Aufwärtsabfrage und setzt dort den status wieder auf 2.
    • Und wieder von vorne...

    Du musst also dieses set status to 1 entfernen. entweder fragst du in deinem Script die Werte 0 und 1 für Status ab (statt 1 und 2) oder du baust noch ein OnActivate um diese Zeile drumrum. Dann kannst du den Aufzug manuell starten.
     
  12. Teridan

    Teridan Mr. Morrowind 2007

    Es funktioniert!

    So muss sich Frankenstein gefühlt haben, als die Finger seines Monsters angefangen haben zu zucken. :lol: Aber wenigstens habe ich euch auch noch zum grübeln gebracht. :p

    Ok, jetzt mache ich mich mal an die eigentlichen Aufgaben. :blink:
     
  13. Killfetzer

    Killfetzer Super-Moderator Mitarbeiter

    Macht noch jemand mit?
     
  14. Mercarryn

    Mercarryn Ehrbarer Bürger

    Ich werd mich dieses Wochenende an diese Lektion setzen, vorher habe ich nicht so genau Zeit, mich in Ruhe damit beschäftigen zu können. Lektion 3 hab ich ja letztens durchgenommen.
     
  15. Teridan

    Teridan Mr. Morrowind 2007

    Ich mache auch noch mit. Wie Mercarryn bin auch ich nicht so schnell. Außerdem ist volle Berufstätigkeit zwar sehr gut, einem zeitintensiven Hobby jedoch eher abträglich. ;)

    Wenn ihr weitermachen wollt, dann hole ich Lektionen halt nach wie dPüm.
     
  16. Zeitgeist

    Zeitgeist Ehrbarer Bürger

    Ich bin momentan mit Vorabiklausuren beschäftigt,daher ist meine Beteiligung etwas geringer als gewünscht...
     
  17. Meine auch... Zwar keine Vorabi Klausuren, aber was anderes. Ich vermute ich werde die nächste Zeit zu gar nichts kommen, was Scripten angeht... Lektion 2 muss ich auch noch nachholen... aber das bleibt doch offen. Also macht ruhig weiter, ich humpel hinterher.
     
  18. Killfetzer

    Killfetzer Super-Moderator Mitarbeiter

    Nö, nö, ich warte noch.
     
  19. Mercarryn

    Mercarryn Ehrbarer Bürger

    Wie versprochen, hab ich mich heute mal mit dieser Lektion näher beschäftigt:

    Sag mal Killfetzer, an deinem ersten Script bekomme ich die Fehlermeldung " script kf_sk_bewegung_bsp1 You need to enter a value in line 21? Compiled script not saved", wenn ich es jetzt mal so rüberkopiere
    Da ist doch aber ein Wert angegeben?
    PHP:
    begin merc_aufzug

    short state
    float timer

    if ( MenuMode == )
      return
    endif

    set timer to timer GetSecondsPassed
    if    (State==0)
        if    (
    timer>=3)
        
    MoveWorld Z200
            
    if    (timer>=5)                            ;5-3 Sekunden ergibt 2 Sekunden Bewegungszeit
            set timer to 0
            set state to 1
            
    endif
        endif
    endif

    if    (
    state==1)
        if    (
    timer>=3)
        
    MoveWorld Z, -200
            
    if    (timer>=5)                            ;5-3 Sekunden ergibt 2 Sekunden Bewegungszeit
            set timer to 0
            set state to 0
            
    endif
        endif
    endif
            

    end
    Ich hatte es mir schon gedacht, dass zwar im Menü-Modus die Bewegung einfriert, da aber das Script im Hintergrund dann doch läuft, wird dann die Position des Activators innerhalb der verstrichenen Zeit sofort aktualisiert.
    Ich nehme an, der timer muss als float-Variable angelegt werden, da die Zeit fliessend ist und kein fester Wert festgelegt werden kann, da man nicht genau weiss, WANN der Spieler das Objekt aktiviert.

    Die weiteren Aufgaben folgen noch.
     
  20. Diarrhoe

    Diarrhoe Vertrauter

    Ein Wert ist angegeben, aber die Achse fehlt.
     
  21. Mercarryn

    Mercarryn Ehrbarer Bürger

    Ja klar, warum ist mir das nicht selber aufgefallen?:headwall:



    PHP:
    begin merc_aufzug_hin_zurueck

    short state
    float zpos

    if ( MenuMode == )
      return
    endif

    if ( 
    state == )
      if ( 
    OnActivate == )

        
    set zpos to GetPosZ
        set zpos to zpos 
    300

        set state to 1
      
    endif
    elseif ( 
    state == )
      if ( 
    GetPos<= zpos )
        
    MoveWorld,  Z100
      
    else
        
    set state to 2
      
    endif
    endif

    if ( 
    state == )
      if ( 
    OnActivate == )

        
    set zpos to GetPosZ
        set zpos to zpos 
    300

        set state to 3
      
    endif
    elseif ( 
    state == )
      if ( 
    GetPos>= zpos )
        
    MoveWorld,  Z, -100
      
    else
        
    set state to 0
      
    endif
    endif


    end
    Wenn man sich das erste Beispielscript von Killfetzer. anschaut und mit etwas Logik den Ablauf umkehrt, hat man in groben Zügen die Lösung dafür. Wenn ich allerdings nicht aufpasse, dass die Werte und Operatoren nicht angepasst sind, muss ich mich nicht wundern, wenn der Lift dem Begriff "Himmelfahrtskommando" ne ganz neue Bedeutung gibt :lol:

    Bei Aufgabe 5 hab ich noch nicht mal nen Ansatz und an Aufgabe 6 beisse ich mir so richtig die Zähne aus, obwohl ich zumindest bei letzterer der Lösung nahe sein sollte.
     
  22. Werbung (Nur für Gäste)
  1. Diese Seite verwendet Cookies, um Inhalte zu personalisieren, diese deiner Erfahrung anzupassen und dich nach der Registrierung angemeldet zu halten.
    Wenn du dich weiterhin auf dieser Seite aufhältst, akzeptierst du unseren Einsatz von Cookies.
    Information ausblenden