Come si salva lo stato del gioco?


27

Qual è la procedura seguita dai programmatori di giochi per salvare e riprendere lo stato del gioco? come file / mappature. Voglio salvarlo per il gioco di difesa della torre e sto usando un motore di gioco unity3D.

Risposte:


16

In genere non penso in termini di un'istantanea della memoria, ma piuttosto faccio solo un elenco di quali valori devono essere salvati tra le sessioni e salvarli in un file esterno.

Questo dipende ovviamente dalle esigenze del tuo gioco specifico, ma di solito semplicemente salvo lo stato del livello attuale (cioè dove sono tutti i nemici, qual è la loro salute, ecc.) E quindi cose di livello superiore come a quali livelli il giocatore ha già completato.


3
+1 Ecco come lo faccio. Scrivo ciò di cui ho bisogno in un file binario. E, se devo aggiungere qualcosa di nuovo, lo aggiungo alla fine in modo da non rompere i vecchi file di salvataggio.
caos Tecnico,

Questo è un buon consiglio per non rompere i vecchi file di salvataggio, anche se l'aggiunta di dati alla fine è irrilevante per il modo in cui li salvo. Lo faccio serializzando / deserializzando un Dizionario e l'ordine è irrilevante in quella struttura di dati.
scherzando il

(fondamentalmente, il codice nella risposta di jonas, con il mio oggetto che è un dizionario)
jhocking

10

Questa risposta è specifica per Unity3d .
In Unity, la maggior parte delle classi è serializzabile, ciò significa che è possibile eseguire lo streaming di oggetti Unity completi su disco. Il seguente codice UnityScript è un modo per serializzare un oggetto, salvarlo su disco e caricarlo di nuovo (dopo il caricamento è necessario eseguire il cast dell'oggetto):

import System;
import System.IO;
import System.IO.Stream;
import System.Runtime.Serialization;
import System.Runtime.Serialization.Formatters.Binary;

class SaveLoad {
        public static function SaveFile(filename:String, obj:Object):void {
                try {
                        Debug.Log("Writing Stream to Disk.", SaveLoad);
                        var fileStream:Stream = File.Open(filename, FileMode.Create);
                        var formatter:BinaryFormatter = new BinaryFormatter();
                        formatter.Serialize(fileStream, obj);
                        fileStream.Close();
                } catch(e:Exception) {
                        Debug.LogWarning("Save.SaveFile(): Failed to serialize object to a file " + filename + " (Reason: " + e.ToString() + ")");
                }
        }

        public static function LoadFile(filename:String):Object {
                try {
                        Debug.Log("Reading Stream from Disk.", SaveLoad);
                        var fileStream:Stream = File.Open(filename, FileMode.Open, FileAccess.Read);
                        var formatter:BinaryFormatter = new BinaryFormatter();
                        var obj:Object= formatter.Deserialize(fileStream);
                        fileStream.Close();
                        return obj;
                } catch(e:Exception) {
                        Debug.LogWarning("SaveLoad.LoadFile(): Failed to deserialize a file " + filename + " (Reason: " + e.ToString() + ")");
                        return null;
                }       
        }
}

2
Oltre a usare C #, dovresti anche usare PlayerPrefs. Sono multipiattaforma, non puoi fare IO su Web / iOS / Android. unity3d.com/support/documentation/ScriptReference/… ( bell'esempio però!)
TJHeuvel

PlayerPrefs è molto meno flessibile, sono davvero multipiattaforma e sono perfetti per memorizzare valori singoli o non correlati. Ma su Windows PlayerPrefs sono memorizzati nel registro, in chiaro.
jonas,

7
Se stai già serializzando, perché non serializzarlo su una stringa e archiviarlo in PlayerPrefs. Certo, è meno flessibile, ma è praticamente l'unica soluzione per un gioco multipiattaforma.
TJHeuvel,

2
PlayerPrefs è ottimo per la memorizzazione di piccoli dati come le impostazioni, ma per interi savegame dovresti usare Application.persistentDataPath docs.unity3d.com/ScriptReference/…
jhocking

2
@TJHeuvel: "Non puoi fare IO su Web / iOS / Android" Sicuramente puoi fare IO su cellulare
Przemysław Wrzesiński

2

Per un TD probabilmente risparmierei esclusivamente tra le onde. In questo modo tutto ciò a cui devi pensare sono le torri. Inserisci alcuni punti di salvataggio automatico nei livelli, tra non più di 10 minuti, ma probabilmente è preferibile meno.

Ovviamente se i tuoi livelli sono abbastanza brevi non potresti semplicemente salvare altro che lo stato della campagna.


1

Quando mi riferisco allo stato attuale del gioco, mi riferisco all'istantanea della memoria al momento del salvataggio. Devi essere in grado di ricrearlo dai dati che memorizzerai sul tuo HDD.

È più semplice serializzare tutte le classi che contengono dati che devono essere persistenti e scaricarle sull'HDD, eseguendo essenzialmente un dump della memoria. Il problema è che l'alterazione delle classi cambierà il numero / tipi di valori serializzati e interromperà i vecchi salvataggi. Anche perché stai salvando tutto ciò aumenta i tempi di caricamento. È più efficiente contrassegnare i singoli campi che sono effettivamente necessari per ricostruire l'attuale "istantanea della memoria" con qualsiasi sistema di attributi utilizzato dal serializzatore / IDE. Quindi ricostruire lo "snapshot di memoria" da quei dati salvati.

Inoltre non ho mai usato Unity prima, quindi potrebbe avere qualcosa incorporato. Tuttavia, questo è l'approccio tipico.


vuoi dire che devo memorizzare i miei stati in un file?
Syed

1
@Syed sì, alla fine della giornata deve essere scritto in un file di qualche tipo poiché lo stato dell'app non verrà salvato in memoria. Con Unity in particolare è possibile utilizzare la classe PlayerPrefs (che a mio avviso memorizza effettivamente le cose nel registro su Windows) se si desidera evitare l'intera lettura / scrittura di file.
Tetrad
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.