GM7 Pro: Fehler mit file_text_read_real() vermeiden

    Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

    • GM7 Pro: Fehler mit file_text_read_real() vermeiden

      Mir ist aufgefallen, dass im Technikbereich oftmals die Frage gefallen ist, warum der Game Maker beim auslesen einer Real aus einer externen Datei eine Fehlermeldung anzeigt. Solche Reals sind z.B. Highscores, die man nachträglich erneut abrufen möchte, weshalb dieser Fehler extrem störend ist - schließlich tritt er ja ständig auf, wenn der Highscore aus der Datei gelesen werden soll.

      Ich habe nun, nachdem ich den Fehler selbst erlebt und eine Lösung gefunden habe, beschlossen, diese mal öffentlich bekannt zu machen ^^

      Ich werde das ganze anhand eines Highscores, der im Spiel geschrieben und dann wieder gelesen werden soll, erläutern.
      Also, fangen wir an.


      I. Eine externe Datei erstellen

      Um eine Datei im Spielordner zu erstellen wird der Befehl file_text_open_write(fname) ausgeführt, dieser öffnet nämlich die Datei [fname] zum Schreiben oder erstellt sie, falls sie noch nicht existiert.
      Also erstellen wir nun ein Objekt mit Namen controller und geben ihm folgenden Befehl:

      Create Event:

      GML-Quellcode

      1. if !file_exists("score.txt"){
      2. myfile=file_text_open_write("score.txt")
      3. file_text_close(myfile)}


      Somit haben wir eine leere Textdatei namens score.txt im Spielordner. In diese können wir nun unseren Highscore schreiben. Zunächst brauchen wir dafür eine Variable global.highscore, die wir ebenfalls im Create Event definieren:

      GML-Quellcode

      1. global.highscore=floor(random(100))

      Mit diesem Codesegment wurde die Variable automatisch zu einer Real. Ihr Wert liegt irgendwo zwischen 0 und 100, ist aber auf jeden Fall eine natürliche Zahl. Mit dieser Variable machen wir nun weiter.



      II. Highscore in die externe Datei schreiben

      Auch das ist ein einfaches Unterfangen. Es gibt mehrere Zeitpunkte, an denen der Highscore geschrieben werden könnte, ich nehme dafür jetzt mal das
      <Spacebar Pressed> Event:

      GML-Quellcode

      1. myfile=file_text_open_write("score.txt")
      2. file_text_write_real(myfile,global.highscore)
      3. file_text_close(myfile)


      Somit schreiben wir die Real "global.highscore" in die Datei. Nun müssen wir das
      Create Event um ein paar Zeilen Code erweitern, um die Real auch wieder auslesen zu können:

      GML-Quellcode

      1. if !file_exists("score.txt"){
      2. myfile=file_text_open_write("score.txt")
      3. file_text_close(myfile)
      4. }
      5. else{
      6. myfile=file_text_open_read("score.txt")
      7. global.highscore=file_text_read_real(myfile)
      8. file_text_close(myfile)
      9. }

      Wenn die Datei also existiert, wird die Real ausgelesen und wieder in global.highscore eingefügt.



      III. Der Fehler dahinter

      Achtung:
      Auch wenn das System jetzt fehlerlos scheint, sollten wir uns die Datei score.txt einmal ansehen. Lassen wir das Programm ( nachdem der controller in einen Raum gesetzt wurde) einmal ablaufen, drücken die Leertaste, beenden dann das Programm und öffnen dann die erstellte txt-Datei.
      In ihr findet sich in etwa folgender Text:
      53,0000
      Starten wir nun das Programm erneut. Es wird folgende Fehlermeldung zu sehen sein:

      ERROR in
      action number 1
      of Create Event
      for object controller:

      Error reading real.

      die Real wird aber trotzem korrekt ausgelesen und angezeigt. Woran liegt das?
      Nun, vermutlich liegt es daran, dass der Game Maker als Dezimalzeichen "." verwendet, aber "," in die Datei geschrieben wird. Man kann dies vermeiden, indem man in der Systemsteuerung die Dezimalschreibweise auf Englisch umstellt. Da aber nicht jeder User einfach mal so seine Dezimalschreibweise umstellen will/kann, muss eine alternative Lösung gefunden werden. Diese werde ich im folgenden erläutern.



      IV. Problembehebung

      Die Codezeilen auf die es hier ankommt sind,
      im Create Event

      GML-Quellcode

      1. global.highscore=file_text_read_real(myfile)

      und im <Spacebar Pressed> Event:

      GML-Quellcode

      1. file_text_write_real(myfile,global.highscore)


      Die Funktion Real umfasst nämlich auch Nachkommastellen, was sich auch nicht durch
      round(
      floor(
      oder
      ceil(
      vermeiden lässt. Was tut man da also?
      Nun, man muss die Variable natürlich als String lesen und schreiben.

      Dazu ändern wir die Events wie folgt ab:

      Create:

      GML-Quellcode

      1. if !file_exists("score.txt"){
      2. myfile=file_text_open_write("score.txt")
      3. file_text_close(myfile)
      4. }
      5. else{
      6. myfile=file_text_open_read("score.txt")
      7. global.highscore=real(file_text_read_string(myfile))
      8. file_text_close(myfile)
      9. }



      <Spacebar Pressed>:

      GML-Quellcode

      1. myfile=file_text_open_write("score.txt")
      2. file_text_write_string(myfile,string(global.highscore))
      3. file_text_close(myfile)


      Somit wird die Real als String geschrieben, was die Nachkommastellen ignoriert. Wenn wir nun die Datei score.txt löschen und das Programm erneut ablaufen lassen, gibt es keine Fehlermeldung mehr. Sehen wir uns die Datei nochmal an, sehen wir etwa diesen Text:

      27
      Die Nachkommastellen sind nun weg. Somit werden alle Fehler mit dem Lesen der Dezimalzeichen ausgehebelt.


      V. Zusammenfassung

      Schritt 1:
      Mittels file_text_open_write() eine externe Datei erstellen und eine Variable definieren

      Schritt 2:
      Einen Zeitpunkt festlegen, an dem die Variable in die externe Datei geschrieben wird.

      Schritt 3:
      Falls file_text_write_real oder file_text_read_real verwendet wurden, diese durch file_text_write_string bzw. file_text_read_string ersetzen und die Real in einen String umformen

      Schritt 4:
      Falls eine fehlerhafte Datei existiert, diese löschen und das Programm erneut starten, die Fehlermeldung sollte damit nicht mehr auftauchen

      Näheres in der



      VI. Datei

      Falls jemand noch nicht schlau daraus geworden ist, hier ist die .gmk Datei. In ihr sind bereits alle Fehler ausgebessert und das Programm liest die Real in der externen Datei problemlos als String.

      Ich hoffe, dass ich einigen unter euch helfen konnte und verabschiede mich hiermit aus meinem ersten Tutorial ^^

      -Ih³
      Dateien
      • read_real.zip

        (7,29 kB, 241 mal heruntergeladen, zuletzt: )
    • Der Highscore ist ja nur ein Beispiel, das Tutorial ist für alle Reals ohne Nachkommastellen, die in Textdateien geschrieben werden sollen, gedacht.
      z.B. wenn man das höchste erreichte Level, einen Highscore UND einen Textstring in eine Textdatei schreiben will (evtl. wenn man nicht so viele Dateien auf einmal erstellen möchte). In diesem Fall müssen eben die Reals auch zu Strings umgewandelt werden.

      Ich speicher meine Highscores ja auch net in Textdateien :D
    • Und wieso soll das nur ohne Nachkommastellen gehen?
      Wenn du das als String speicherst, dann schreibt er doch auch den Punkt und kein Komma.
      Man müsste höchstens, um alle Nachkommastellen zu erhalten, die Zahl mit string_format(val,tot,dec) in einen String verwandeln.
      Einige meiner Spiele:
    • Benutzer online 1

      1 Besucher