Goetz Geschrieben 2. Juni 2019 Autor Geschrieben 2. Juni 2019 Tabellen - Teil 4 Eine Lua Tabelle kann Elemente vom Typ 'table' enthalten Beispiel = { {1, 2, 3} , {63, 127, 255} , {true, true, false} } Das Ergebnis hat Ähnlichkeit mit mehrdimensionalen Tabellen. Die 63 im obigen Beispiel steht an Position Beispiel[2][1], nämlich im zweiten Block an erster Stelle. Der Vergleich mit landläufigen Tabellen ist aber irreführend. Hilfreicher ist, die Lua-Tabellen einfach als Datensammlung zu verstehen. Sie haben in mancher Hinsicht mehr Ähnlichkeit mit Objekten als mit Tabellen. Deshalb müssen Lua-Tabellen nicht dimensioniert werden. Das heißt, dass man nicht (wie in anderen Sprachen) vorher die Anzahl der Zellen festlegen muss. Bands = { Beatles = {"John", "Paul", "George", "Ringo"}, Stones = {"Mick", "Keith", "Brian", "Ian", "Bill", "Charlie"}, Who = {"Pete", "Roger", "John", "Keith"} } print(Bands.Stones[2]) Die Tabelle Bands enthält 3 Elemente, deren Index jeweils ein String ist. Nämlich der Bandname. Jedes der drei Elemente ist ebenfalls eine Tabelle. Die Elemente dieser Untertabellen sind einfache Aufzählungen. Der Index jedes Elements ist also eine Nummer, beginnend mit der Zahl 1 für das erste Element. Beachtet bitte das Komma hinter jeder Untertabelle. Dieses Komma ist erforderlich, um die Elemente Beatles, Stones und Who voneinander zu trennen. Die Zeilenumbrüche und Einrückungen in der Tabelle sind optional und dienen nur der Lesbarkeit. Man könnte ebenso gut den gesamten Tabelleninhalt in eine lange Zeile schreiben. Oder umgekehrt auf noch mehr Zeilen verteilen: Bands = { Beatles = { "John", "Paul", "George", "Ringo" }, Stones = { "Mick", "Keith", "Brian", "Ian", "Bill", "Charlie" }, Who = { "Pete", "Roger", "John", "Keith" } } Das ist reine Geschmacksache. Die Trennung der Elemente entsteht allein durch die Kommas und die geschweiften Klammern. Aber aus Erfahrung kann ich empfehlen, Programmzeilen mit mehr als 80 Zeichen Länge zu vermeiden. Im Übrigen werdet ihr im MBS keine großen Tabellen am Stück erstellen. Dazu besteht kein Grund. Diese Tabellen entstehen auf andere Weise. Aber es wird euch helfen, wenn ihr versteht wie Tabellen in Lua aufgebaut sind. Weil ihr später an einzelne Daten aus solchen Tabellen drankommen wollt. Weil ihr zum Beispiel von einem Zug den Namen des dritten Waggons benötigt: Zuege = { { Name = "Gueterzug_1", Geschwindigkeit = 80, Typ = "Gueter", Lok = { Name = "V200", Typ = "Diesel", Kupplung_vorne = false, Kupplung_hinten = true }, Waggons = { { Name = "G10", Typ = "Kasten", Kupplung_vorne = true, Kupplung_hinten = true }, { Name = "Kbs", Typ = "Rungen", Kupplung_vorne = true, Kupplung_hinten = true }, { Name = "OVP", Typ = "Tank", Kupplung_vorne = true, Kupplung_hinten = true }, { Name = "G10", Typ = "Kasten", Kupplung_vorne = true, Kupplung_hinten = false }, } } } print(Zuege[1].Waggons[3].Name)
Goetz Geschrieben 3. Juni 2019 Autor Geschrieben 3. Juni 2019 Tabellen - Teil 5 Ihr habt nun gesehen, dass man in einer Tabelle Zahlen, Strings, Booleans und Tabellen speichern kann. Und das letzte Beispiel hat euch vielleicht gezeigt, warum das praktisch ist. Es geht bei Tabellen nur darum, eine Ansammlung von Daten vernünftig zu organisieren. Das ist ungefähr so, als würde man alles, was zu einem bestimmten Waggon gehört, in eine Schachtel packen: Seinen Namen, die Beschriftungen, die Länge, den Status der beiden Kupplungen, die Position beweglicher Teile etc. Und dann einen Zug bilden, indem man eine Lok-Schachtel und mehrere Waggon-Schachteln hintereinander in eine große Zug-Schachtel steckt. Das hat alles nur organisatorische Bedeutung. @wopitir schrieb mir gestern eine PN, in der er die ganze Tabellenstruktur mit den Ordnern und Unterordnern bei Windows verglich. Und das trifft es ganz gut. Aber Lua Tabellen können noch mehr. Man kann in einer Tabelle auch eine Funktion speichern. Warum auch nicht? Man speichert in Lua ja eigentlich nur die Adressen, unter denen etwas liegt. Ob an dieser Speicheradresse eine Zahl, ein Text oder eine Funktionsdefinition zu finden ist, macht technisch also gar keinen Unterschied. Vorweg muss ich eine alternative Schreibweise für die Definition einer Funktion vorstellen. Diese Variante kennt ihr schon: function Beispiel() print("Ich bin eine Beispielfunktion") end Diese Schreibweise macht dasselbe: Beispiel = function() print("Ich bin eine Beispielfunktion") end Der einzige Unterschied ist die Reihenfolge, in der etwas passiert. Im zweiten Beispiel wird zuerst eine namenlose Funktion angelegt und dann die Adresse dieser Funktion an den Namen Beispiel übergeben. Das Resultat ist aber dasselbe wie bei der ersten Schreibweise. Die zweite Schreibweise eignet sich, um die Adresse einer Funktion an einen Tabellenplatz zu übergeben: Bands = { Beatles = {"John", "Paul", "George", "Ringo"}, Stones = {"Mick", "Keith", "Brian", "Ian", "Bill", "Charlie"}, Who = {"Pete", "Roger", "John", "Keith"}, Anzahl = function(Bandname) print("Die Band "..Bandname.." hat "..#Bands[Bandname].." Mitglieder") end, Erster = function(Bandname) print("Das erste Bandmitglied der "..Bandname.." heißt: "..Bands[Bandname][1]) end } Bands.Anzahl("Stones") Bands.Erster("Who") Beachtet bitte, dass innerhalb der Funktion keine Kommas am Zeilenende stehen dürfen. Denn der gesamte Funktionsblock bildet ein Element. Am Ende der Funktionsdefinition muss hingegen zwingend ein Komma stehen, falls weitere Tabellenelemente folgen. Deshalb steht im obigen Beispiel ein Komma hinter dem end, welches die Definition von Anzahl abschließt. Im MBS sind die Modelle Objekte. Und diese Objekte werden, wenn ich Neo richtig verstanden habe, in V5 eigene Funktionen bekommen, welche man per Lua aufrufen kann. Wie ihr oben seht, ist der Aufruf solcher Funktionen sehr einfach. Aber es hilft wenn man eine Vorstellung davon hat, wie die Daten dazu tabellarisch organisiert sind.
Goetz Geschrieben 4. Juni 2019 Autor Geschrieben 4. Juni 2019 Tabellen - Teil 6 Für den Aufruf von Funktionen, die in einer Tabelle stehen, kennt Lua noch einen besonderen Trick. Und der macht das Anlegen von Funktionen innerhalb von Tabellen erst sinnvoll. Man kann die Adresse der Tabelle beim Aufruf der Funktion als Argument mitgeben. Damit ist es selbst bei tief gestaffelten Tabellen ein Leichtes, direkt auf Elemente der Tabelle zuzugreifen, in der auch die Funktion steht. Ich möchte etwas weiter ausholen, um die Zusammenhänge möglichst durchschaubar zu machen. Als Beispiel soll noch einmal die Zugtabelle aus dem vorletzten Kapitel dienen: Zuege = { { Name = "Gueterzug_1", Geschwindigkeit = 80, Typ = "Gueter", Lok = { Name = "V200", Typ = "Diesel", Kupplung_vorne = false, Kupplung_hinten = true }, Waggons = { { Name = "G10", Typ = "Kasten", Kupplung_vorne = true, Kupplung_hinten = true }, { Name = "Kbs", Typ = "Rungen", Kupplung_vorne = true, Kupplung_hinten = true }, { Name = "OVP", Typ = "Tank", Kupplung_vorne = true, Kupplung_hinten = true }, { Name = "G10", Typ = "Kasten", Kupplung_vorne = true, Kupplung_hinten = false }, } } } Zuege enthält die Adresse der ganzen TabelleZuege[1] enthält die Adresse der ersten Untertabelle (in der alle Daten des ersten Zuges stehen)Zuege[1].Waggons enthält die Adresse der Untertabelle mit allen Waggons in der Untertabelle 1 der Tabelle Zuege.Zuege[1].Waggons[1] enthält die Untertabelle mit den Details des ersten Waggons innerhalb der Untertabelle aller Waggons innerhalb … Solche Adressen kann man an eine neue Variable übergeben: Dings = Zuege[1].Waggons[1] Das ist dann sinnvoll, wenn man anschließend diese Adresse mehrfach benötigt. Weil es die Schreibweise der Adressen innerhalb dieser Untertabelle jetzt vereinfacht Dings.Name Dings.Typ Dings.Kupplung_vorne Selbstverständlich wählt man im Ernstfall einen sinnvolleren Namen als „Dings“. Nun stellt euch bitte vor, dass in der Untertabelle eines Waggons eine Funktion enthalten ist, die etwas mit den Daten dieses Waggons tut. Die zum Beispiel den Namen und den Typ des Waggons ausgibt (um die Geschichte jetzt nicht ausufern zu lassen.) Dann würde man beim Aufruf der Funktion die gesamte Adresse innerhalb der Tabelle mit angeben. Zuege[1].Waggons[1].Ausgabe() Jetzt könnte man die Adresse außerdem als Argument mitgeben: Zuege[1].Waggons[1].Ausgabe( Zuege[1].Waggons[1] ) Für dieses Argument legt man in der Funktionsdefinition eine Variable an. Ein gebräuchlicher Name für diese Variable ist „self“. Aber jeder andere Name funktioniert genauso gut. Zuege[1].Waggons[1].Ausgabe = function(self) print("Mein Name ist "..self.Name.." und ich bin vom Typ "..self.Typ) end Das ist ungemein praktisch, weil es die Adressierung der Daten innerhalb dieser Tabelle so bequem macht. Die komplette Adresse der Untertabelle wird an die lokale Variable self übergeben. Also muss man innerhalb der Funktion nur noch self schreiben, wenn man Zuege[1].Waggons[1] meint Und das ist noch nicht alles. Ich kann die identische Funktion für alle Waggons benutzen, weil ich nur die jeweils passende Adresse als Argument an self übergeben muss. Und deshalb hat man in Lua die Schreibweise für den Funktionsaufruf vereinfacht. Programmierer mögen es nämlich nicht, wenn sie etwas doppelt schreiben müssen. Weil es das Risiko vergrößert, sich dabei zu verschreiben. In Lua kann man die Adresse an einer Stelle mit einem Doppelpunkt anstelle des einfachen Punkts aufteilen. Zuege[1].Waggons[1]:Ausgabe() Dann wird automatisch alles, was vor dem Doppelpunkt steht, als erstes Argument übergeben. Werte, die man in die Klammern schreibt, sind damit die Argumente 2 bis … Der Grund, warum ich diesen relativ schweren Stoff in einem Einsteiger-Tutorial anspreche, ist folgender: Die einzelnen Objekte im MBS werden mit V5 fertige Lua Funktionen enthalten. Und der Aufruf dieser Funktionen wird dem folgenden Muster entsprechen: Objektname:Funktionsname(Argumente) Das Objekt hat eigene Daten. Und diese wird die Funktion des Objekts verwenden. Wenn die Funktion ein Signal umstellen soll, dann wird sie dafür die Achsen der Signalflügel ansprechen. Wenn man an einem Kran einen Haken anheben kann, dann muss die Funktion dafür ebenfalls die entsprechenden Parameter des Krans ansprechen und verändern. Wie das im Einzelnen passiert, ist für uns unwichtig. Die Funktion ist in V5 ja fertig definiert. Die Definition müssen wir nicht selbst entwerfen. Aber der Funktionsaufruf wird diesen Gesetzmäßigkeiten folgen. Wir schreiben möglicherweise so etwas wie: Kran:Haken(0) um den Haken in Nullstellung zu bringen. Wie das konkret aussieht, weiß ich auch erst wenn der Beta-Test der V5 beginnt. Mir geht es jetzt ausschließlich darum, dass ihr anhand meiner generischen Beispiele das zugrundeliegende Prinzip durchschaut. Weil dann verständlicher wird, warum was in welcher Reihenfolge im Befehl stehen muss und was es mit dem Doppelpunkt im Funktionsaufruf auf sich hat. Darüber hinaus könnt ihr euch dieses Wissen natürlich auch in eurem eigenen Programmcode zunutze machen. Denn alles, was man rund um den Eisenbahnverkehr steuert, lässt sich wunderbar tabellarisch verwalten. Es lohnt sich wirklich, die Lua-Tabellen zu durchschauen und den Umgang damit zu üben. Weil man tabellarisch später auch sehr komplexe Situationen gut und überschaubar in den Griff bekommt.
Goetz Geschrieben 8. Juni 2019 Autor Geschrieben 8. Juni 2019 Schleifen - Teil 3 Schleifen gehören zu den wichtigsten Hilfsmitteln in der Programmierung. Sie nehmen einem viel Arbeit ab und gerade im Zusammenspiel mit einer Software wie dem 3D-Modellbahnstudio sind das genau die Arbeiten, welche überhaupt den Einsatz eines Skripts rechtfertigen. Nehmt zum Beispiel einen Schattenbahnhof mit zehn Gleisen. Ein eintreffender Zug soll in eins dieser Gleise einfahren. Dazu muss geprüft werden, welche Gleise noch frei sind, um dann eine Fahrstraße zu einem dieser freien Gleise zu legen. Zunächst muss zehnmal dasselbe getan werden. Die Prüfung, ob ein Gleis besetzt ist. Und bei jedem der zehn Durchläufe muss genau ein Parameter geändert werden: Die Gleisnummer. Für solche Zwecke ist die for ... do Schleife gedacht. Zwischen die Schlüsselworte for und do schreibt man den Namen einer Variablen, ihren Anfangswert, ihren Schlusswert und den Abstand, in dem man von Anfang bis Schluss zählen möchte. Also zum Beispiel so etwas: for Gleis = 1, 10, 1 do Beachtet bitte das = Zeichen hinter der Variablen für die Zuweisung der Werte und die Kommas für die Trennung von Anfangswert, Schlusswert und Schrittweite. In den folgenden Zeilen steht dann das, was mehrmals hintereinander ausgeführt werden soll und am Ende des Blocks steht, wie bei Lua üblich, das Schlüsselwort end. Ich weiß noch nicht, wie man in V5 prüft, ob ein Gleis besetzt ist. Deshalb bleibe ich bei meinem bisherigen Prinzip, dass ich ersatzweise einfach etwas Text ausgebe: for Gleis = 1, 10, 1 do print("Ich prüfe, ob Gleis "..Gleis.." besetzt ist.") end Wenn ihr diese drei Zeilen bei Lua-Demo eingebt und laufen lasst, dann steht im Ausgabefenster die Textzeile zehnmal untereinander. Dabei steht an Stelle der Variablen Gleis in jeder Zeile eine andere Nummer. Das ist die Zahl, welche bei jedem neuen Durchlauf der Schleife an die Variable Gleis übergeben wurde. Beim Programmieren muss man sehr genau auf das Verhalten solcher Methoden achten. Man muss zum Beispiel sehen, dass der Anfangs- und der Schlusswert beide enthalten sind. Die Schleife wird also mit den Zahlen 1 bis 10 inklusive durchgeführt. Muss man so etwas wissen? Nein! Muss man so etwas lernen? Auswendig können? Nein, auch nicht. Das ginge gar nicht. Es gibt zu viele Unterschiede, die man kennen müsste. Wenn man programmiert, dann muss man ein Bewusstsein für diese Fragen entwickeln. Dann muss man kurz innehalten und denken:"for ... do könnte sich so oder so verhalten. Es könnte inklusive oder exklusive zählen. Ich habe keine Ahnung, wie das bei Lua ist." Und dann probiert man es kurz aus. Wie einfach man solche Dinge testen kann, seht ihr im obigen Beispiel. Hier ist ein weiteres Beispiel: Was passiert, wenn man den Wert der Variablen innerhalb der Schleife ändert? Was bedeutet das für den nächsten Durchlauf?Keine Ahnung! Also probiere ich, was passiert: for Gleis = 1, 10, 1 do Gleis = Gleis + 2 print("Ich prüfe, ob Gleis "..Gleis.." besetzt ist.") end Werden jetzt Zahlen übersprungen? Oder werden alle Zahlen um 2 erhöht und dann ausgegeben? Das muss man nicht auswendig wissen. Das ist auch solange uninteressant, bis man einen Grund hat, den Wert der Variablen innerhalb der Scheife zu ändern. Aber dann will man es zuverlässig wissen. Also muss man sich jetzt bewusst machen, dass es zwei mögliche Verhaltensweisen gibt. Und man muss ausprobieren, welches von beiden das tatsächliche Verhalten ist. Programmieren ist nichts, was man auswendig lernt und dann nach Schema abspult. Programmieren ist eine sehr kreative Beschäftigung. Ständig muss man sich etwas einfallen lassen. Und immer mit der Neugier eines Detektivs betrachten, was genau passiert. Deshalb kann man Programmieren auch nur lernen, indem man sich aktiv damit beschäftigt.
Goetz Geschrieben 9. Juni 2019 Autor Geschrieben 9. Juni 2019 Schleifen - Teil 4 (für Fortgeschrittene) Die for … do Schleife kann man auch verwenden, um ganze Tabellen auszulesen: Beatles = {"John", "Paul", "George", "Ringo"} for i = 1, 4 do print("Beatle Nummer "..i.." ist "..Beatles[i]) end In Lua gibt es für diesen Zweck aber eine eigene, bessere Methode. Sie heißt in pairs(), weil sie paarweise den Index und den Inhalt zum Index liefert: Beatles = {"John", "Paul", "George", "Ringo"} for key, value in pairs(Beatles) do print("Beatle Nummer "..key.." ist "..value) end Die Namen der beiden Variablen für Index und Inhalt sind natürlich frei wählbar. Gebräuchlich sind die Buchstaben k und v für key (= Schlüssel) und value (= Wert). Deshalb habe ich im obigen Beispiel zum besseren Verständnis die Worte key und value gewählt. Die in pairs() Methode liefert alle Schlüssel/Wert Paare zurück. Auch solche, bei denen der Schlüssel keine Zahl, sondern ein String ist: Beatles = {John = "Gitarre", Paul = "Bass", George = "Gitarre", Ringo = "Schlagzeug"} for k, v in pairs(Beatles) do print(k.." spielt "..v) end Beachtet bitte, dass die Aufzählung nicht sortiert ist. Sie kann zufällig mit der Reihenfolge übereinstimmen, in der die Tabelle erstellt wurde. Aber sie muss es nicht und man weiß nie, in welcher Reihenfolge die Werte ausgelesen werden. Auch dann nicht, wenn die Indexe eine lückenlos nummerierte Aufzählung (wie im ersten Beispiel) sind. Aus diesem Grund gibt es eine zweite, sehr ähnliche Methode: in ipairs() Der Buchstabe i im Wort ipairs steht für „iterable“. Damit ist gemeint, dass nur lückenlos nummerierte Elemente der Tabelle ausgelesen werden und dass die Ausgabe sortiert stattfindet. Beatles = { "John", "Paul", "George", "Ringo", Ort = "Liverpool", Jahr = 1960, Manager = "Brian Epstein", Studio = "Abbey Road" } for k, v in ipairs(Beatles) do print("Schlüssel: "..k..", Wert: "..v) end Vergleicht die Ausgabe mal mit dem , was ihr bei in pairs() bekommt. Und lasst die in pairs() Version mehrfach laufen. Ihr werdet sehen, dass sich Reihenfolgen ändern, obwohl ihr das Skript zwischen den einzelnen Ausführungen nicht ändert. Der nummerierte Teil der Tabelle steht dabei für gewöhnlich vorne und ist sortiert. Aber garantiert ist auch das nicht! Wenn eine numerisch sortierte Aufzählung benötigt wird, dann muss man in ipairs() verwenden. Die Ausgabe von in ipairs() beginnt bei 1, endet bei der ersten Lücke in der nummerierten Liste und ignoriert namentliche Indexe. Beispiel = { Name = "Test", "Eins", "Zwei", "Drei", "Vier", "Fünf", "Sechs", "Sieben", "Acht" } Beispiel[6] = nil for k, v in ipairs(Beispiel) do print("Schlüssel: "..k..", Wert: "..v) end Eine fertige Methode für eine alphabetisch sortierte Aufzählung gibt es nicht.
Goetz Geschrieben 10. Juni 2019 Autor Geschrieben 10. Juni 2019 Da ich gerade für jemanden ein kurzes Video erstellt habe, welches im Kern denselben Aspekt behandelt wie das Kapitel "Tabellen - Teil 6" in dieser Reihe hier, möchte ich das Video auch hier anbieten:
Goetz Geschrieben 25. Juni 2019 Autor Geschrieben 25. Juni 2019 Endlich kann ich euch ein weiteres Video anbieten. Die Sprachaufnahme ist leider sehr träge geraten. Aber besser kriege ich es derzeit nicht hin. Dafür habe ich mich bemüht den Inhalt zu strukturieren. Und weil das Video recht lang ist, habe ich bei YouTube im Kommentar Sprungmarken hinterlegt. Das Video ist Anfängertauglich, denn es setzt kein Vorwissen voraus. Das heißt aber nicht, dass der Stoff einfach ist. Ich bin überzeugt, dass "Anfänger" ebenso gut Schweres lernen können wie Fortgeschrittene. Es muss nur auf ihrem aktuellen Wissensstand aufbauen. Im Video geht es um "Strings". Die werdet ihr im MBS später mal benötigen. Weil alle Namen, die ihr auslest, Strings sind. Als "String" bezeichnen Programmierer ein Stück Text. Egal, ob es sich dabei um einen Namen handelt oder um eine Nachricht. Wer nicht alles auf Anhieb versteht, der weiß zumindest später, wo er etwas zu dem Thema findet. Das Video reißt die verschiedenen Themen nur an. Es vermittelt ein prinzipielles Verständnis für die Materie, kein "alles, was man wissen muss". Es ist nämlich Humbug, alles auf einmal erklären zu wollen. Damit erreicht man nur, dass der Lernende am Ende überhaupt nichts mehr weiß. Es ist viel wichtiger, den Kern zu verstehen. Dann holt man sich zu gegebener Zeit selber das, was man noch braucht. Viel Spaß beim Lernen und Experimentieren!
Goetz Geschrieben 25. Juni 2019 Autor Geschrieben 25. Juni 2019 Hier sind die wichtigsten Beispiele aus dem Video noch einmal zum Nachlesen. Manche habe ich um nützliche Hinweise ergänzt. -- Escape Sequenzen -- \a bell -- \b back space -- \f form feed -- \n newline -- \r carriage return -- \t horizontal tab -- \v vertical tab -- \\ backslash -- \" double quote -- \' single quote -- \[ left square bracket -- \] right square bracket -- zwei Bindestriche kennzeichnen in Lua einen Kommentar Beispiel = "Die Version 5 des \"3D Modellbahn Studios\"\n stellt 'Lua' Befehle zur Verfügung" print(Beispiel) Beispiel1 = 'Die Version 5 ' Beispiel2 = 'des "3D Modellbahn Studios" ' Beispiel3 = "stellt 'Lua' Befehle zur Verfügung", print(Beispiel1 .. Beispiel2 .. Beispiel3) Beispiel = { 'Die Version', 'des "3D Modellbahn Studios"', "stellt 'Lua' Befehle zur Verfügung", Version = 5 } Muster = "%s %d %s %s" Text = Muster:format(Beispiel[1], Beispiel.Version, Beispiel[2], Beispiel[3]) print(Text) -- Muster:format(...) ist die verkürzte Schreibweise von: string.format(Muster, ...) Beispiel = 'des "3D Modellbahn Studios" ' Anfang, Ende = string.find(Beispiel, "3D") -- vereinfacht: Beispiel:find("3D") print("Die Zeichenkette '3D' im String 'Beispiel2' \nbeginnt bei Zeichen "..Anfang.. " \nund endet bei Zeichen "..Ende) Beispiel = 'des "3D Modellbahn Studios" ' Teiltext = string.sub(Beispiel, 9, 25) -- vereinfacht: Beispiel:sub(9, 25) print(Teiltext) for i = 1, 10, 1 do Formel = string.format("%2d * %d = %2d", i, 3, i*3) print(Formel) end -- die 2 im %2d füllt einstellige Zahlen mit Leerzeichen auf zwei Stellen auf -- Dadurch steht in der Ausgabe alles fein säuberlich untereinander.
Goetz Geschrieben 9. März 2020 Autor Geschrieben 9. März 2020 Das folgende Video ist ein Versuch, Einsteigern anhand eines sehr kleinen Beispiels zu zeigen wie ein Lua Skript funktioniert. Ich habe dabei bewusst auf jeglichen Bezug zum MBS verzichtet. Denn ich bin überzeugt, dass man zuerst das Prinzip in seinen Grundzügen verstehen sollte, bevor man sich an konkrete Aufgaben wagt. Außerdem birgt ein MBS-Bezug immer die Gefahr, dass man sich gedanklich zu sehr mit Detailfragen beschäftigt und dem Prinzip, nach dem alle Programm-Codes aufgebaut sind, zu wenig Aufmerksamkeit schenkt. Das Video setzt keinerlei Vorkenntnisse voraus. Aber einfach ist es trotzdem nicht. Ich meine nämlich, dass man Einsteigern durchaus Denkarbeit zumuten kann. Man muss nur darauf achten, dass man keine Vorkenntnisse voraussetzt. Ich würde mich freuen wenn das Video denen, die sich noch nicht viel unter "Programmieren" vorstellen können, eine Idee vermittelt was eigentlich dahinter steckt. https://www.youtube.com/watch?v=y_vsDTQYP7c
Hawkeye Geschrieben 8. Oktober 2020 Geschrieben 8. Oktober 2020 (bearbeitet) Am 29.5.2019 um 11:28 schrieb Goetz: Variablen im 3D-Modellbahn Studio Im MBS gibt es Daten, die man als User gerne auslesen und verwenden möchte. Zum Beispiel die Stellung eines Signals. Oder die Geschwindigkeit einer Lok. Oder der Name des Fahrzeugs auf einem Gleisstück. Damit man in der EV an diese Daten kommt, haben die Speicherplätze für diese Daten eigene Namen. Das sind also Variablen, deren Name schon im MBS festgelegt wurde. Wenn man davon absieht, dass die Namen dieser Speicherplätze schon festliegen und die Werte in diesen Speicherplätzen vom MBS stammen, unterscheiden sich diese Variablen nicht von solchen, die man selbst deklariert. Es sind Speicherplätze, die einen Namen bekommen haben, damit man sie im Programmcode oder in der EV verwenden kann. Ein Teil der Schwierigkeiten, welche manche User mit Variablen haben, stammen möglicherweise von den Namen dieser Variablen. Man muss die richtigen Namen kennen. Und das sind vielleicht nicht die Namen, welche man selbst ausgesucht hätte. An dieser Tatsache wird auch Lua nichts ändern. Hallo Götz, da hast du dir aber einen Haufen Arbeit gemacht. Wirklich sehr schön und anschaulich erklärt. Kommt mir alles sehr bekannt vor. Gibt es eine Liste der Objekt-Informationen (Speicherplätze, Namen) , die man von einem Objekt auslesen und mit LUA verändern kann? ich würde z.B. gerne die 3 Positionswerte (x,y,z) der Rotation auslesen und neu an das gewählte Objekt zurückgeben. Hab da leider auch mit "Suche" im Forum bisher nichts gefunden. Bei Suche-Eingabe "LUA", kommt als Ergebnis "0 Ergebnisse gefunden - Die Suche ergab keinen Treffer" Viele Grüße Hawkeye Bearbeitet 8. Oktober 2020 von Hawkeye
Goetz Geschrieben 8. Oktober 2020 Autor Geschrieben 8. Oktober 2020 (bearbeitet) vor 12 Stunden schrieb Hawkeye: Gibt es eine Liste der Objekt-Informationen (Speicherplätze, Namen) , die man von einem Objekt auslesen und mit LUA verändern kann? Ja, die gibt es. im Lua Editor bekommst du Vorschläge, sobald du anfängst etwas zu tippen. Die enthalten alle Funktionen, Eigenschaften und dazu kurze Hinweistexte zu ihrer Verwendung. Außerdem kannst du dein Skript mit der grafischen EV schreiben und dann mit einem Klick auf <> in ein Skript wandeln. Das erspart dir vie Schreibarbeit und du siehst auch gleich die richtigen Bezeichnungen. Die Entwickler der Skriptsprache wünschen übrigens, dass man den Namen Lua schreibt. Also nicht in Versalien. Weil es keine Abkürzung ist, sondern ein Name. Bearbeitet 8. Oktober 2020 von Goetz
Klartexter Geschrieben 2. Januar Geschrieben 2. Januar Ich komme zurück auf einen Beitrag von mir, den ich kürzlich erstellt habe: Dank eines Hinweises habe ich nicht nur einige gute und informative Videos von @Goetz auf meinen Rechner laden können, ich durfte auch feststellen, dass es hier bereits ein hervorragendes Tutorial von @Goetz gibt. Mit diesen Informationen kann man sich sehr gut in Lua einarbeiten, vor allem machen sie bestimmte Abläufe verständlicher. Ich würde es begrüßen, wenn @Neo dieses Tutorial oben festtackern könnte, denn das MBS arbeitet ja mit Lua, und da bin ich sicher nicht der Einzige, dem diese Scriptsprache noch nicht geläufig ist. Momentan schwirrt mir etwas der Kopf ob der vielen Informationen, ich habe die letzten Stunden nur Videos angeschaut und hier dann nachgelesen. Auf jeden Fall mal ein herzlicher Dank an @Goetz für die ganze Arbeit, die mir beim erlernen der Scriptsprache eine große Hilfe darstellt. Walter
Empfohlene Beiträge
Erstelle ein Benutzerkonto oder melde dich an, um zu kommentieren
Du musst ein Benutzerkonto besitzen, um einen Kommentar verfassen zu können
Benutzerkonto erstellen
Neues Benutzerkonto für unsere Community erstellen.
Neues Benutzerkonto erstellenAnmelden
Du hast bereits ein Benutzerkonto? Melde dich hier an.
Jetzt anmelden