Objekte speichern

  • GM 8

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

  • Objekte speichern

    Hi,
    besitze GM Studio und versuche gerade mir eine Speichern/Laden Funktion zu schreiben.
    Speichere in einer .ini Datei ab.
    Spielerposition, Punkte, Leben usw sind kein Problem. Möchte aber den ganzen Raum abspeichern. Darin gibt es unzerstörbare Objekte, welche die Levelbegrenzung bilden und zerstörbare Objekte einer Sorte, einsammelbare Objekte einer Sorte und Gegner. Es geht also haupsächlich darum zu speichern, ob die Objekte zerstört sind doer vorhanden und ob die Objekte eingesammelt wurden oder nicht. Da es aber immer die gleichen Objekte sind (z.B. Juwelen zum einsammeln), kann ich nicht einfach sagen es sollen die juwelenobjekte gespeichert werden, da dann nur eines gespeichert wird und beim laden alle anderen weg sind. Gibt es eine Möglichkeit beliebig viele gleiche Objekte an unterschiedlichen Positionen abzuspeichern?

    Bisher bin ich so vorgegangen zum speichern: (wenn F1 gedrückt wird)
    Spoiler anzeigen

    GML-Quellcode

    1. //Speichern
    2. ini_open("save.ini")
    3. //Spieler
    4. ini_write_real("Spieler", "Juwelen", score)
    5. ini_write_real("Spieler", "Leben", lives)
    6. ini_write_real("Spieler", "X-Position", obj_spieler.x)
    7. ini_write_real("Spieler", "Y-Position", obj_spieler.y)
    8. ini_write_real("Spieler", "H-Geschwindigkeit", hspeed)
    9. ini_write_real("Spieler", "V-Geschwindigkeit", vspeed)
    10. //Ende
    11. ini_close()
    Alles anzeigen



    Und zum laden: (wenn F4 gedrückt wird)
    Spoiler anzeigen

    GML-Quellcode

    1. //Laden
    2. ini_open("save.ini")
    3. //Spieler
    4. score = ini_read_real("Spieler","Juwelen",0)
    5. lives = ini_read_real("Spieler","Leben",0)
    6. obj_spieler.x = ini_read_real("Spieler","X-Position",0)
    7. obj_spieler.y = ini_read_real("Spieler","Y-Position",0)
    8. hspeed = ini_read_real("Spieler","H-Geschwindigkeit",0)
    9. vspeed = ini_read_real("Spieler","V-Geschwindigkeit",0)
    10. //Ende
    11. ini_close()
    Alles anzeigen



    Weis nun leider nicht weiter mit den Objekten und Gegnern. Ausser ich würde für 10 sammelbare Juwelen 10 Juwelenobjekte unterschiedlich benenen...

    Hoffe das war verständlich... Freu mich über jede Hilfe.
  • Ich würde sagen da muss man erst die anzahl der Objekte Speichern und dann kann jedes Object x und y und evtl leben speichern.

    Edit und schau am besten auch mal bei GML-Die Einsteigerreferenz nach.
    Kopiere dies in deine Signatur, um es in deiner Signatur zu haben.
    Achtung: Dieser Beitrag läuft ende des Monats ab, bitte lese ihn noch vor dem Monatswechsel...
    Nach langer zeit wieder im Forum aktiv :D

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von Larsi ()

  • Danke schonmal für die Antwort.
    Leider bekomme ich beim Starten deines Spiels folgende Fehlermeldung:

    Spoiler anzeigen


    ___________________________________________
    FATAL ERROR in
    action number 1
    of Create Event
    for object ball:

    ############################################################################################
    VMError!! Occurred - Push :: Execution Error - Variable Get -5.collected(100000, 0)
    at gml_Object_ball_Create_0 (line 4) - if string_pos("Ball:"+string(x)+":"+string(y)+":"+room_get_name(room)+";", global.collected)>0
    ############################################################################################
    Self Variables :
    collected(100000) = 0



    Aber was ich genau suche:

    Kann ich irgendwie alle Objekte in einem Raum abfragen und sofern sie noch vorhanden sind ihre Position abspeichern in eine ini Datei?

    In dem Raum befinden sich zb.:

    40 obj_wand, solid, unzerstörbar. Als Raumbegrenzung. Die sind immer da.
    1 obj_spieler. Die Werte von diesem Objekt bekomm ich ja gespeichert so wie ich es jetzt habe.

    10 obj_juwelen. Werden bei Berührung durch den Spieler zerstört und erhöhen den score um 1.
    30 obj_block. Werden bei Berührung durch den Spieler zerstört (man gräbt sich quasi durch die Blöcke).
    5 obj_gegner. Werden durch die obj_block begrenzt und folgen dem Spieler wenn er sie befreit. Senken bei Berühren die lives um 1 und werden zerstört.

    Wenn ich also im laufenden Spiel 5 Juwelen eingesammelt habe, 10 zerstörbare Blöcke zerstört habe und 2 Gegner weg sind und dann speichere, soll es beim laden wieder genau dieser Zustand sein (also die eingesammelten juwelen sollen weg sein, die restlichen noch da. genauso die Blöcke und die Gegner).
    Gibt es evtl einen Befehl der alle Objekte in einem Raum abfragt und sie dann mit Name, Position und Geschwindigkeit abspeichert?
  • Kann ich irgendwie alle Objekte in einem Raum abfragen und sofern sie noch vorhanden sind ihre Position abspeichern in eine ini Datei?

    Dafür gibt es das with-Konstrukt :

    GML-Quellcode

    1. with(all) { //für jede Instance im derzeitgen Raum
    2. //diesen code ausführen
    3. }


    Du kannst nun mit diesem Code alle Instancen durchgehen und diese in Text-, INI- oder Binären-Form speichern. Wobei sich hier die Binäre-Form bevorzugt (Mit DLLs kann man solche Datein einfach schreiben und wieder lesen, z.B. die 39dll).
    wupto.net/ Nicht meine Seite!
    We love Koalas.

    GM-D-Spam-o-Meter: 32%
  • ok, das klingt genau nachdem was ich suche...
    leider hab ichs wohl noch nicht ganz verstanden :(

    habe es jetzt mal nur für die juwelen getestet und das in speichern reingeschrieben:

    Spoiler anzeigen

    GML-Quellcode

    1. //Speichern
    2. ini_open("save.ini")
    3. //Spieler
    4. ini_write_real("Spieler", "Juwelen", score)
    5. ini_write_real("Spieler", "Leben", lives)
    6. ini_write_real("Spieler", "X-Position", obj_spieler.x)
    7. ini_write_real("Spieler", "Y-Position", obj_spieler.y)
    8. ini_write_real("Spieler", "H-Geschwindigkeit", hspeed)
    9. ini_write_real("Spieler", "V-Geschwindigkeit", vspeed)
    10. with (all)
    11. {
    12. ini_write_real("Objekte", "Alle", obj_juwel.x)
    13. ini_write_real("Objekte", "Alle", obj_juwel.y)
    14. }
    15. //Ende
    16. ini_close()
    Alles anzeigen



    und das in laden:

    Spoiler anzeigen

    [gml]
    //Laden

    ini_open("save.ini")

    //Spieler

    score = ini_read_real("Spieler","Juwelen",0)
    lives = ini_read_real("Spieler","Leben",0)
    obj_spieler.x = ini_read_real("Spieler","X-Position",0)
    obj_spieler.y = ini_read_real("Spieler","Y-Position",0)
    hspeed = ini_read_real("Spieler","H-Geschwindigkeit",0)
    vspeed = ini_read_real("Spieler","V-Geschwindigkeit",0)


    with (other)
    {
    obj_juwel.x = ini_read_real("Objekte", "Alle", 0)
    obj_juwel.y = ini_read_real("Objekte", "Alle", 0)
    }



    //Ende

    ini_close()


    [/gml
    ]


    wenn ich es so mache, sieht die ini so aus:

    Spoiler anzeigen

    [Objekte]
    Alle=576.000000
    [Spieler]
    V-Geschwindigkeit=0.000000
    H-Geschwindigkeit=0.000000
    Y-Position=282.000000
    X-Position=522.000000
    Leben=3.000000
    Juwelen=1.000000


    beim laden sind dann alle juwelen auf einer stelle, an der vorher gar keiner war.
  • So funktionieren INI-Datein nunmal nicht, du überschreibst den Wert "Objekte.Alle" immer wieder mit einen neuen. Du kannst z.B.

    GML-Quellcode

    1. ini_write_real("Object", string(id)+"_x", x);
    2. ini_write_real("Object", string(id)+"_y", y);


    benutzen um die Objekte mit deren x und y Koordiante zu speichern, laden funktioniert dann mit:

    GML-Quellcode

    1. x=ini_read_real("Object", string(id)+"_x", x);
    2. y=ini_read_real("Object", string(id)+"_y", y);


    das setzt aber vorraus das die ID nicht bei jedem Spielneustart ändert.
    wupto.net/ Nicht meine Seite!
    We love Koalas.

    GM-D-Spam-o-Meter: 32%
  • Das müsste gehen ist aber nicht getestet

    GML-Quellcode

    1. //Speichern
    2. ini_open("save.ini")
    3. //Spieler speichern
    4. ini_write_real("Spieler", "Juwelen", score)
    5. ini_write_real("Spieler", "Leben", lives)
    6. ini_write_real("Spieler", "X-Position", obj_spieler.x)
    7. ini_write_real("Spieler", "Y-Position", obj_spieler.y)
    8. ini_write_real("Spieler", "H-Geschwindigkeit", hspeed)
    9. ini_write_real("Spieler", "V-Geschwindigkeit", vspeed)
    10. //Juwelen speichern
    11. ini_write_real("Juwelen","Anzahl",obj_juwel.instance_count)
    12. with(obj_juwel){
    13. ini_write_real("Juwelen",string(instance_number(self))+".x",x)
    14. ini_write_real("Juwelen",string(instance_number(self))+".y",y)
    15. }
    16. ini_close()
    Alles anzeigen


    GML-Quellcode

    1. //Alten Speicher löschen
    2. with(obj_juwel){
    3. instance_destroy()
    4. }
    5. //laden
    6. ini_open("save.ini")
    7. //Spieler laden
    8. score = ini_read_real("Spieler", "Juwelen", 0)
    9. lives = ini_read_real("Spieler", "Leben", 3)
    10. obj_spieler.x = ini_read_real("Spieler", "X-Position", obj_spieler.x)
    11. obj_spieler.y = ini_read_real("Spieler", "Y-Position", obj_spieler.y)
    12. obj_spieler.hspeed = ini_read_real("Spieler", "H-Geschwindigkeit", 0)
    13. obj_spieler.vspeed = ini_read_real("Spieler", "V-Geschwindigkeit", 0)
    14. //Juwelen laden
    15. while ini_read_real("Juwelen","Anzahl",10) < obj_juwel.instance_count+1 {
    16. instance_create(ini_read_real("Juwelen",instance_number(obj_juwel)+".x",0),ini_read_real("Juwelen",instance_number(obj_juwel)+".y",0),obj_juwel)
    17. }
    18. ini_close()
    Alles anzeigen
    Kopiere dies in deine Signatur, um es in deiner Signatur zu haben.
    Achtung: Dieser Beitrag läuft ende des Monats ab, bitte lese ihn noch vor dem Monatswechsel...
    Nach langer zeit wieder im Forum aktiv :D

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von Larsi ()

  • hi larsi,
    habs gerade mal kurz getestet, beim laden kommt folgende fehlermeldung:

    Spoiler anzeigen


    ___________________________________________
    FATAL ERROR in
    action number 1
    of Keyboard Event for F4 Key
    for object obj_world:

    ############################################################################################
    VMError!! Occurred - Push :: Execution Error - Variable Get 11.instance_count(111, 0)
    at gml_Object_obj_world_Keyboard_115 (line 22) - while ini_read_real("Juwelen","Anzahl",10) < obj_juwel.instance_count+1
    ############################################################################################



    und die ini sieht dann so aus:

    Spoiler anzeigen

    [Juwelen]
    1.y=320.000000
    1.x=576.000000
    Anzahl=144.000000
    [Spieler]
    V-Geschwindigkeit=0.000000
    H-Geschwindigkeit=0.000000
    Y-Position=192.000000
    X-Position=192.000000
    Leben=3.000000
    Juwelen=0.000000
  • Oh ha da weiß ich auch nicht weiter.

    Ich glaube es währe leichter eine text-Datei zu nehmen ( wie z.b. txt )
    Kopiere dies in deine Signatur, um es in deiner Signatur zu haben.
    Achtung: Dieser Beitrag läuft ende des Monats ab, bitte lese ihn noch vor dem Monatswechsel...
    Nach langer zeit wieder im Forum aktiv :D

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von Larsi ()

  • Zum einen gibt instance_number einen Real zurück und dieser muss beim Laden zu einem string gemacht werden, zum anderen führt "obj_juwel.instance_count+1" dazu das versucht wird die Variable "instance_count" von obj_juwel zu bekommen, was natürlich zu einem Fehler führt.

    instance_count gibt die komplette Anzahl aller Instance im Raum zurück, instance_number(obj) gibt die Anzahl von obj zurück, demnach kann der Code nicht stimmen.

    GML-Quellcode

    1. var i;
    2. i=0;
    3. with(obj_juwel) {
    4. ini_write_real("Juwel", string(i)+"_x", x);
    5. ini_write_real("Juwel", string(i)+"_y", y);
    6. i+=1;
    7. }


    GML-Quellcode

    1. var i;
    2. for (i=0;ini_key_exists("Juwel", string(i)+"_x");i+=1) {
    3. instance_create(ini_read_real("Juwel", string(i)+"_x", 0),
    4. ini_read_real("Juwel", string(i)+"_y", 0),
    5. obj_juwel);
    6. }
    wupto.net/ Nicht meine Seite!
    We love Koalas.

    GM-D-Spam-o-Meter: 32%
  • Funktioniert beinahe...

    Würde noch gerne wissen ob ich auch alles verstanden habe:
    Speichern:
    Spoiler anzeigen

    GML-Quellcode

    1. var i; //Variable i wird erzeugt...
    2. i=0; //...mit dem Wert 0.
    3. with(obj_juwel) //Das folgende wird mit allen Instancen obj_juwel gemacht:
    4. {
    5. ini_write_real("Juwel", string(i)+"_x", x); //Es wird in die ini geschrieben: unter Juwel, ein String (zeichenfolge) wird geschrieben bestehend aus dem Wert der Variable i und dem Text _x, gespeichert wird die X-Position
    6. ini_write_real("Juwel", string(i)+"_y", y); //Es wird in die ini geschrieben: unter Juwel, ein String (zeichenfolge) wird geschrieben bestehend aus dem Wert der Variable i und dem Text _y, gespeichert wird die Y-Position
    7. i+=1; //Danach wird der Wert der Variable i um 1 erhöht. So werden die Strings durchnummeriert.
    8. }



    Laden

    Spoiler anzeigen

    GML-Quellcode

    1. var i; //Variable i wird abgefragt:
    2. for (i=0;ini_key_exists("Juwel", string(i)+"_x");i+=1) //i = 0. Existiert der Key (in dem Fall der String) mit der Nummer 0 dann wird die Instance
    3. //erzeugt mit X und Y wie es zwischen den {} steht. Existiert der Key nicht, wird i um 1 erhöht und mit dem neuen Wert abgefragt. usw.
    4. {
    5. instance_create(ini_read_real("Juwel", string(i)+"_x", 0), ini_read_real("Juwel", string(i)+"_y", 0),obj_juwel);
    6. }



    Hoffe so stimmts. Und schonmal vielen Dank dafür.

    Das Problem, welches ich jetzt noch habe, ist das jedesmal beim Laden zuviele Objekte entstehen. Die Position an der die gespeicherten Juwelen erscheinen ist richtig, aber an jeder Position befinden sich dann statt 1 Juwel mehrere. Beim ersten Laden sind an einer Stelle 4-6 (man sieht halt nur eins, deshalb ists mir erst später aufgefallen). Beim zweiten Laden sinds dann 11 an der Stelle usw.

    Dieser Beitrag wurde bereits 4 mal editiert, zuletzt von dankell ()

  • Vor dem laden Juwelen löschen

    GML-Quellcode

    1. //Alten Speicher löschen
    2. with(obj_juwel){
    3. instance_destroy()
    4. }
    5. //Jetzt dein Ladescript
    Kopiere dies in deine Signatur, um es in deiner Signatur zu haben.
    Achtung: Dieser Beitrag läuft ende des Monats ab, bitte lese ihn noch vor dem Monatswechsel...
    Nach langer zeit wieder im Forum aktiv :D
  • Benutzer online 2

    2 Besucher