Jump to content

Goetz

Mitglieder
  • Gesamte Inhalte

    6150
  • Benutzer seit

  • Letzter Besuch

Alle erstellten Inhalte von Goetz

  1. Mir fehlte der richtige Funktionsaufruf um zu einem auslösenden Fahrzeug in Lua den kompletten Zugverband zu erhalten. Deshalb hatte ich den Umweg in Kauf genommen, Mittel- und Hinterteil in Objekt-Variablen im Vorderteil zu speichern. Vielleicht war das auch für den Anfang ganz gut so, weil nachvollziehbar. Aber inzwischen habe ich Neo um den nötigen Tipp gebeten. Die Funktion heißt layout:getVehiclesGroup(Fahrzeug_im_Zugverband) Richtiger: In der Tabelle layout steht eine Funktion getVehiclesGroup(), der man beim Aufruf ein Element aus dem Zugverband übergeben muss. Man bekommt eine Liste aller Objekte zurück, die den Zugverband ergeben. Bitte achtet auf den Doppelpunkt zwischen layout und getVehiclesGroup() damit die Funktion Zugriff auf die Tabelle aller Elemente der Anlage hat. Damit kann man auf die Variablen im Vorderteil verzichten. Vorteil: Es besteht kein Unterschied mehr zwischen Einzel- und Doppeltraktionen. Hier ist eine neue Beispielanlage, in der ich diese Liste nutze. Das enthaltene Skript sieht so aus: local Blinker = {} local Tueren = {} local Zug = layout:getVehicleGroup(vehicle) for k, Waggon in ipairs(Zug) do if Waggon.animations["Blinker rechts"] then table.insert(Blinker, Waggon.animations["Blinker rechts"]) end if Waggon.animations["Tür rechts vorne"] then table.insert(Tueren, Waggon.animations["Tür rechts vorne"]) end if Waggon.animations["Tür rechts hinten"] then table.insert(Tueren, Waggon.animations["Tür rechts hinten"]) end end local Bremslicht = Zug[#Zug].animations["Bremslicht hinten"] if not deferredCall then vehicle.deceleration = 2 vehicle.acceleration = 3 vehicle.targetSpeed = 0 Bremslicht:stop(1) defer(3, "Blinker an") elseif deferredCall == "Blinker an" then for k, Blink in ipairs(Blinker) do Blink:play(0, 1) end defer(4, "Tür auf") elseif deferredCall == "Tür auf" then for k, Tuer in ipairs(Tueren) do Tuer:play(0, 1) end defer(7, "Tür zu") elseif deferredCall == "Tür zu" then for k, Tuer in ipairs(Tueren) do Tuer:play(1, -1) end defer(2, "Abfahrt") elseif deferredCall == "Abfahrt" then vehicle.targetSpeed = 50 Bremslicht:stop(0) defer(1.5, "Blinker aus") elseif deferredCall == "Blinker aus" then for k, Blink in ipairs(Blinker) do Blink:stop(0) end end Ich habe mich entschlossen, zunächst die Adressen der Blinker und Türen des auslösenden Zuges in lokalen Tabellen zu sammeln. Das hat meines Erachtens den Vorteil, dass ich anschließend diese Tabelle in einem Rutsch ansprechen kann. In Zeile 3 fordere ich die Fahrzeugliste zum auslösenden vehicle an. In den Zeilen 5 bis 15 prüfe ich, welches der Fahrzeuge überhaupt einen "Blinker rechts", eine "Tür rechts vorne" oder eine "Tür rechts hinten" hat. Alle Blinker und Türen, die ich dabei finde, übertrage ich in zwei lokale Tabellen "Blinker" und "Tueren" Ab Zeile 19 passiert dann weiter nichts neues im Vergleich zur ersten Version. Ich bediene mich jetzt nur aus den oben angelegten Tabellen und nicht mehr aus Variablen im Vorderteil. Zeile 17 ist noch eine kleine Besonderheit. Mit Zug[#Zug] bekomme ich das letzte Element der Tabelle. Denn #Zug ist die Anzahl der Elemente in der Tabelle Zug. Und weil Lua Tabellen mit 1 beginnen, ist die Anzahl zugleich auch der Index des letzten Elements. Das bedeutet: Mit dem Konstrukt in der Zeile 17 merke ich mir die Adresse des Bremslichts im letzten Waggon. Beispielanlage mit obigem Skript: StraBa Tabellen 01.mbp
  2. Das wird wieder ein Minimax Modul, auf das ich mich riesig freue! Das Bahnhofsgebäude ist eine Wonne.
  3. Genau. Mit einem Komma werden in Lua mehrere Parameter oder mehrere Tabellenelemente voneinander getrennt. Das Dezimaltrennzeichen ist - wie im Amerikanischen üblich - der Punkt. Meines Wissens gilt das für alle Programmiersprachen. Das erfordert aber ein anderes Prinzip. Mit dem deferredCall geht das nicht! Ich möchte als Nächstes lieber zeigen, wie man Signale in die Steuerung mit einbindet. Doppeltraktionen hebe ich mir bis zur Freigabe der Listen und Tabellen auf. Das wird damit deutlich einfacher!
  4. Ich kenne sie als D-Bahn und bin damit täglich zur Schule gefahren. Damals hatte die noch ein Speiseabteil in der Mitte. Und damals hieß die Station in Huckingen noch Huckingen und war ebenerdig.
  5. Vielleicht hilft dir dabei folgendes: Vergiss mal für einen Augenblick, dass Pausenzeiten im Spiel sind. Betrachte zunächst nur, dass diese Funktion sich selbst aufruft und in einer Verzweigung den Parameter prüft, den sie beim Aufruf mitbringt: function Beispiel(Parameter) if not Parameter then -- gleichbedeutend mit: if Parameter == nil or Parameter == false then print("erster Aufruf. Parameter war leer oder false") Beispiel("Eins") elseif Parameter == "Eins" then print("neuer Aufruf. Im Argument stand: ", Parameter) Beispiel("Zwo") elseif Parameter == "Zwo" then print("neuer Aufruf. Im Argument stand: ", Parameter) Beispiel("Dings") elseif Parameter == "Dings" then print("letzter Aufruf. Im Argument stand: ", Parameter) end end Beispiel() -- Beim ersten Aufruf ohne Parameter Der einzige Unterschied zwischen meinem Beispiel und dem defferredCall ist, dass als weiterer Parameter eine Zeit (in Sekunden) übergeben wird und das MBS den nächsten Aufruf erst dann ausführt, wenn diese Zeit abgelaufen ist.
  6. Exzellent, Hans Das ist völlig in Ordnung. Ich würde sagen, dass du es verstanden hast. Ich weiß nur nicht, ob du dem Bremslicht eine eigene Verzögerung gegeben hast, weil du das gerne so wolltest? Oder ob du nicht wusstest, dass du das Bremslicht mit in einen anderen, vorhandenen Abschnitt einbauen könntest. Auf jeden Fall hast du aber bewiesen, dass du auch das Prinzip des deferredCall richtig verstanden hast. Im Gegenteil Das finde ich sogar sehr gut, weil so die Dinge zusammenbleiben, die zusammen gehören. Die Idee mit der Nachtzeit ist übrigens klasse. So sieht man viel besser, wann Bremslicht oder Blinker an- bzw. ausgehen. Nur eine Kleinigkeit. Da es nur ein Bremslicht gibt, kannst du auf die Tabelle verzichten und der Achse einfach einen Namen geben: local Bremslicht = vehicle.variables["Hinterteil"].animations["Bremslicht hinten"] -- .... Bremslicht:play(0, 1) -- .... Bremslicht:stop(0) -- .... Ich freue mich riesig über deine Version der Testanlage Götz
  7. Das freut mich, Hans Genau so war das gedacht. Es ist gar nicht wichtig, welche Dinge du dir rauspickst, solange du nur Kleinigkeiten entdeckst, die nützlich für dich sind.
  8. Es ist in erster Linie schwer, an geeignete Geräusche dranzukommen. Das Modell kann Max mittels Maßzeichnungen selbst bauen. Aber das Geräusch kann er nicht so leicht selbst erzeugen. Er müsste es aufnehmen. Ohne Störgeräusche. Und es nützt nichts, am Bahndamm zu stehen und eine vorbeifahrende Lok aufzunehmen. Weil man ein konstantes Fahrgeräusch benötigt. Nicht eins, das an- und abschwillt. (Und geeignetes Aufnahmeequipment bräuchte man obendrein. Und dazu einen Standpunkt, wo man nur das Fahrgeräusch bekommt. Ohne Vogelgezwitscher. Ohne Hall oder Echo.) Man findet solche Geräusche auch nicht einfach im Netz. Noch weniger als kostenfreie Datei. Da findest du nur die vorbeifahrenden Züge, die eben nicht für diesen Zweck geeignet sind.
  9. Ich habe dem ersten Beitrag jetzt noch das fertige Skript aus der Sendung und die kleine Demoanlage beigefügt. Ich denke, dass das vorne im ersten Beitrag am besten aufgehoben ist.
  10. Freut mich, dass es dir gefallen hat. Danke für dein Feedback, Michael.
  11. Alleine mit der grafischen EV wäre das zwar theoretisch möglich. Aber in der Praxis scheitert man - wie Metallix schon in deinem Thread erklärt hat - daran, dass man die Achsen nicht zu fassen bekommt, wenn man über den generischen "Auslöser" jede Straßenbahn ansprechen möchte, welche die Haltestelle anfährt. Diese Hürde kann man mit Lua sehr leicht nehmen. Und es ist äußerst praktisch, dass man zuerst das Gerüst mit der grafischen EV bauen und anschließend in ein Skript umwandeln kann. So hat man im Skript schon alle Schreibweisen für die benötigten Befehle und muss nur noch Anpassungen vornehmen. In einer Twitch Sendung habe ich heute gezeigt, wie man solch eine Sequenz Stück für Stück aufbauen kann. Hier ist die bereinigte Aufnahme auf YouTube Das Skript, welches in der Sendung entstanden ist (für diejenigen, die nur was nachlesen möchten): local Blinker = { vehicle.animations["Blinker rechts"], vehicle.variables["Hinterteil"].animations["Blinker rechts"], } local Tueren = { vehicle.animations["Tür rechts vorne"], vehicle.variables["Mittelteil"].animations["Tür rechts vorne"], vehicle.variables["Hinterteil"].animations["Tür rechts hinten"] } if not deferredCall then vehicle.deceleration = 2 vehicle.acceleration = 3 vehicle.targetSpeed = 0 defer(3, "Blinker an") elseif deferredCall == "Blinker an" then Blinker[1]:play(0, 1) Blinker[2]:play(0, 1) defer(4, "Tür auf") elseif deferredCall == "Tür auf" then for Index , Tuer in ipairs(Tueren) do Tuer:play(0, 1) end defer(7, "Tür zu") elseif deferredCall == "Tür zu" then for Index , Tuer in ipairs(Tueren) do Tuer:play(1, -1) end defer(2, "Abfahrt") elseif deferredCall == "Abfahrt" then vehicle.targetSpeed = 50 defer(1.5, "Blinker aus") elseif deferredCall == "Blinker aus" then Blinker[1]:stop(0) Blinker[2]:stop(0) end Und das hier sind drei Versionen der Anlage Ohne Steuerung: StraBa Sequenz 00.mbp mit grafischer EV: StraBa Sequenz 01.mbp und die finale Version mit Lua Skript: StraBa Sequenz 02.mbp Ich hoffe, dass ich dem einen oder anderen damit ein bisschen Inspiration bieten kann.
  12. Hier ist ein Bild zu Andys Erklärung: Das Ereignis "Gleiskontakt wird betreten" hat zwei Auslöser. Denn zwei Objekte sind an diesem Ereignis beteiligt: der Kontakt, der betreten wird das Fahrzeug, welches den Kontakt betritt Deshalb muss man im Anschluss an die Auswahl "Auslöser" aus einer kleinen Liste den gewünschten Auslöser wählen. Und weil das Fahrzeug als Auslöser klar identifiziert ist, ist die Angabe eines bestimmten Gleises weder nötig noch sinnvoll.
  13. yippeeee!!!
  14. Don't, Pete. Not at the beginning. Get to grips with one aspect. Just one. When that is fully understood, tackle the next one. You're progress will be much faster that way. Begin with slowing the train at four different spots on your layout, using only a single event definition in the EM. Concentrate on that. Ignore signals, ignore stopping the train, ignore delay times, ignore barriers, switch points and what not.
  15. Clever gemacht! Und wirklich praktisch
  16. Goetz

    Neue Anlage

    Kiwi? I was under the impression that they call themselves all blacks
  17. Hi Pete, the keyword in your following sentence was "principals". That is what you ought to develop. First (though this has nothing to do with the EM) you may want to rethink your signal strategy. Don't close signals ahead of a train. Close them behind the train. Shut the door, so to speak, after a train has entered a section. That way, you keep everyone else out until the train has vacated that section. This is important because other things that I'll explain later will relate to this tactic. Now you'll want to consider that basically you're doing the same thing at every station for every train on any track. Slow it down, when it approaches the station. Stop at the station. Wait for a specified time. Release the train when conditions are right. The trick is to define each basic sets of action only once. And to find a way to use individual parameters within those action sets where needed. This is why you find the selection "trigger" as a possible target of an action. It stands for "whoever triggered this set of actions." Lets pick the contact used to slow an approaching train as a first example. The event is triggered by two elements: The contact itself and the train. One touches the other and that event causes the chain of actions which you define. You'll want to slow down any train that triggers this contact. This means, that the target of your "set speed" action is one of the triggering objects. And its location is of no interest, because the location of the contact has that covered. Of the triggering objects, only one can have a speed: the train. The contact may be of interest in a different context. That's why it is listed as one of the triggers. But in this case, it's not the trigger that you want to talk to. Choose the "set vehicle speed" action click on the cog next to the "[All vehicles]" label in the box on the right pick "Trigger" open the list under "Vehicle" pick "Vehicle" from that list specify your desired speed below You've successfully defined that any train which touches the contact, will be told to slow down to the speed you requested. Now that you've understood how to generalise the "slow the train that touched the contact" principle, you may place multiple contacts for this purpose at strategic locations. Each with a unique name. At the top of your event definition, you have the "When will the event be triggered?" selection. Here you may choose multiple objects (e.g. all contacts that you placed for this purpose.) Or - even more convenient - you add one keyword (of your choice) to all these contacts. And select this keyword to define all objects that shall trigger this particular event. See, if this makes any sense to you so far. Ask, if somethings unclear. When we know that you've come to grips with this first step, we'll take the next one. And easy does it, Pete One step at a time. Goetz example layout: first steps for Pete.mbp
  18. Small wonder, Pete. Your layout is way too big and loaded to use as a testing ground. What's more, you have way too many entries in your event manager. Some of them double and triple the same set of actions. That's not your fault, because previous versions of the 3D-Train Studio left you with little choice in that matter. But it's a great hinderance now when you're experimenting with different settings. Because you never know for sure, what other events may interfere with what you do. You'd be better off setting your large layout aside for a little while and building a plain oval with one signal on it and no decoration whatsoever. Use that for your experiments. That way, you can concentrate on understanding the V5 EM one element at a time. Step by step. And then, when you're familiar with your new tools, you may rethink your strategy for the Fairmont layout. note: I only just realised that Tom said the same thing. I missed his last sentence. Sorry! Kind regards Goetz
  19. Und an dem Punkt bin ich raus. Das ist mir zu doof ... Es stimmt zwar, dass der Unterschied nicht auf einen Rundungsfehler zurückzuführen ist, sondern auf einen Zahlendreher in meiner Formel: Ich hatte 3536 anstelle von 3563 geschrieben. Aber deine Häme ist einfach daneben gewesen!
  20. Klar - du hast einen Rundungsfehler mehr in deiner Formel, weil du erst die Wurzel ziehst und dann wieder quadrierst.
  21. Sorry - blöde Schlamperei von mir. Du multiplizierst die beiden Werte. Das muss ich dann natürlich auch tun (und sie nicht dividieren) Faktor1 = 2.25504 Bremsweg = 3536 decel_Faktor = Faktor1 * Bremsweg Speed = 150 local A = Speed ^ 2 / decel_Faktor A == 2.8217336153442 Bei dieser Vereinfachung kann man natürlich auf die Berechnung vorab verzichten: local Faktor1 = 2.25504 local Bremsweg = 3536 Speed = 150 local A = Speed ^ 2 / Faktor1 / Bremsweg A == 2.8217336153442
  22. Hallo @Timba dann hätte ich dazu noch einen anderen Tipp: könntest du einmal zu Beginn als globale Konstante im Modul-Skript ablegen, statt es bei jedem Aufruf neu zu berechnen. Den fixen Teil von folgendem Term natürlich auch. Und wenn du dabei den Zahlen 2.25504, 3563 etc. aussagekräftige Namen gibst, dann wäre das noch ein Bonus. Beispiel: Faktor1 = 2.25504 Faktor2 = 3536 decel_Faktor = Faktor1 / Faktor2 -- und an geeigneter Stelle local A = vehicle.currentSpeed^2 / decel_Faktor Ich kenne die Bedeutung der beiden Zahlen nicht. Drum habe ich sie im Beispiel Faktor1 und Faktor2 genannt. Und ich habe in deiner A Formel aufgeräumt. Wenn du erst eine Wurzel ziehst und dann das Ergebnis wieder quadrierst, machst du unnötig viele Rechenschritte.
  23. Dafür gibt es das neue Modewort "deep(l) fake"
  24. Du wirst beim ersten Einsatz von V5 gefragt, ob du deine bisherigen Anlagen übernehmen möchtest. Wenn du dazu "ja" sagst, dann werden sie automatisch für dich in ein V5-taugliches Format konvertiert. Solltest du komplexe Ereignis-Verwaltungen in diesen Anlagen haben, dann musst du die vielleicht anpassen. Aber es wäre sowieso ratsam, die EV mit den Mitteln aus V5 neu zu bauen, weil du sie jetzt viel schlanker und effizienter gestalten kannst.
  25. Er meint die Schreibweise des Namens. Lies doch bitte den ersten Satz, den er zitiert hat. Dann ist klar worauf er sich bezieht. Auszug aus der Website zu Lua:
×
×
  • Neu erstellen...