Vielen Dank für eure Hilfe. Sehr ausführliche Erklärungen.
Vielleicht hätte ich allerdings die Frage in Kontext mit ihrer Verwendung in meinem Projekt stellen sollen.
Was ich nämlich zu erreichen suche ist die AI für gewisse Feinde zu erstellen.
Meine bisherige Methode war diese:
Ich habe die einzelnen Zeilen für den AI-Code als Strings in ein Array gespeichert. Jeder Feind kannte seinen AI-Index.
In dem Update-Prozess des Feindes wurde dann über:
der AI-Code aufgerufen.
Es hat funktioniert.
Allerdings habe ich mich selbst gestern gefragt, nachdem ich die Hilfsdatei des RMXP durchstöbert habe, ob es nicht über ein Proc Objekt eleganter zu lösen wäre.
Da diese Funktionen allerdings sehr sehr oft durchgeführt werden, pro Frame werden mehrere Zeilen Code für jeden Feind auf der Map durchgeführt, wollte ich bevor ich mit der Umsetzung beginne fragen ob es denn für die Performance irgendwelche Vorteile, oder noch wichtiger, sogar Nachteile geben würde.
Nebenbei gibt es ja den einen Nachteil, dass ich über die eval(line) Methode den Feind im AI-Code als self ansprechen kann, mit dem Proc Objekt müsste ich es wohl über eine Globale Variable lösen denke ich.
Wo ich gerade dabei bin, kann ich einem Proc Objekt einen Parameter in der .call Funktion angeben?
eval dürfte hier schon sehr viel Performance fressen. Zumal du es für jede Zeile neu ausführst (der Overhead also noch größer ist, als würdest du alle Zeilen gleichzeitig evaluieren).
Erstmal zu deiner Frage mit Procs und Parametern: Natürlich kannst du call Parameter mitgeben:
Weiterhin kannst du Procs über instance_eval an einen Objekt-Kontext binden (mir fällt gerade ein: auch eval-Strings kannst du an jedes beliebige Binding binden, in dem du als weiteren Parameter ein Binding übergibst. So gesehen war also meine vorherige Behauptung, Procs wären mächtiger als eval, falsch).
Hier wird also block innerhalb von $game_player ausgeführt. Er hat also auch Zugriff auf alle Instanzvariablen und Methoden von $game_player, gleichzeitig aber auch Zugriff auf alle lokalen Variablen im Scope.
btw. gibt es noch eine weitere Möglichkeit, wie du deinen Gegnern "KI-Code" mitgeben kannst:
Diese Lösung ist hochgradig performant (performanter als Procs und deutlich performanter als eval). Außerdem lassen sich deine Gegner-Objekte problemlos abspeichern (Procs lassen sich nämlich nicht abspeichern!). Weiterhin ist das ein recht üblicher Ansatz für derlei Probleme, auch in anderen Programmiersprachen, wo es eval und Procs nicht gibt.
Ah, vielen Dank. Das ist ein ganzer Haufen von Informationen die für mich sehr sehr nützlich sind.
Mein Hauptproblem war es eigentlich, dass ich, wenn ich den Code als Text gespeichert hatte und ihn über eval(code) aufrufen ließ auf alle Variablen zugreifen, und den Feind über self ansprechen konnte.
Als ich versucht hatte es auch Proc Objekte zu übertragen musste ich den Feind, mit meinem begrenzten Wissenstand, als globale Variable definieren um auf ihn zugreifen zu können.
Nun kann ich also entweder den Code aus dem Proc Objekt über .instance_eval direkt in meinen Feind einbinden als auch Parameter im .call Befehl durchgeben um dadurch meinen Feind als Parameter zu übergeben.
Eine Frage habe ich jedoch. Für jeden Feind ein neues Objekt der AI Klasse zu erzeugen, wie in deinem letzten Beispiel, anstatt die AI als Konstante zu definieren und jeden Feind auf den selben Code zugreifen zu lassen, ist dieser Weg nicht aufwendiger für den Computer?
Ich meine, ich könnte das Proc Objekt ja als Konstante speichern und jeden Feind dieses Proc Objekt als AI Code benutzen lassen. Wäre dies nicht besser als eine AI-Instanz im Feind zu erzeugen und zu speichern?
Du kannst die AI-Objekte auch als Konstanten speichern. Dann verbrauchst du weniger Speicherplatz. Aber das ist jetzt nicht soo~ tragisch, denn soviel Speicher kosten die Objekte nicht.
Du kannst auch das Singleton-Pattern anwenden und deinen KI-Klassen eine Methode geben, welche immer dieselbe Instanz zurückgibt.
Du solltest dich auf diese Identität aber nicht verlassen. Beim Abspeichern und Neuladen der KIs haben die wieder eine eigene Instanz. Aber wie gesagt: du sparst dadurch letztlich nur etwas Speicher, mehr nicht.
Nun, falls es nur Vorteile bringt doch keine Nachteile dann ist es mir recht.
Vielen Dank für die ausführliche Hilfe.
Ich habe noch eine kleine Frage, könntest du mir genau erklären was dieses "&" Zeichen in folgender Zeile bedeutet?
Dass es nicht funktioniert ohne das Zeichen zu verwenden habe ich bereits feststellen müssen.