Bagaimana Anda menyimpan status permainan?

27

Bagaimana prosedur yang diikuti oleh pemrogram game untuk menyimpan dan melanjutkan status game? seperti file / pemetaan. Saya ingin menyimpannya untuk game menara pertahanan dan saya menggunakan mesin game unity3D.

Syed
sumber

Jawaban:

16

Saya biasanya tidak berpikir dalam hal snapshot memori, tetapi saya hanya membuat daftar nilai mana yang perlu disimpan di antara sesi dan menyimpan nilai-nilai itu ke dalam file eksternal.

Ini tentu saja tergantung pada kebutuhan gim spesifik Anda, tetapi biasanya saya hanya menyimpan keadaan level saat ini (mis. Di mana semua musuh berada, seperti apa kesehatan mereka, dll.) Dan kemudian hal-hal tingkat yang lebih tinggi seperti level pemain sudah selesai.

jhocking
sumber
3
+1 Begitulah cara saya melakukannya. Saya menulis apa yang saya butuhkan untuk file biner. Dan, jika saya perlu menambahkan sesuatu yang baru, saya menambahkannya di akhir sehingga saya tidak merusak file lama.
chaosTechnician
Itu tip yang bagus tentang tidak memecah file penyimpanan lama, meskipun menambahkan data pada akhirnya tidak relevan dengan cara saya menyimpan data. Saya melakukannya dengan membuat serial / deserializing Kamus, dan ketertiban tidak relevan dalam struktur data itu.
jhocking
(pada dasarnya, kode dalam jawaban jonas, dengan Obyek saya menjadi Kamus)
jhocking
10

Jawaban ini spesifik untuk Unity3d .
Di Unity, sebagian besar kelas bisa serial, ini artinya Anda bisa melakukan streaming objek Unity ke disk. Kode UnityScript berikut adalah cara untuk membuat serialisasi objek, menyimpannya ke disk memuatnya lagi (setelah memuat Anda harus melemparkan objek):

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;
                }       
        }
}
jonas
sumber
2
Selain menggunakan C #, Anda juga ingin menggunakan PlayerPrefs. Mereka lintas platform, Anda tidak bisa melakukan IO di Web / iOS / Android. unity3d.com/support/documentation/ScriptReference/… (Contoh yang bagus!)
TJHeuvel
PlayerPrefs jauh kurang fleksibel, mereka memang lintas platform dan mereka sempurna untuk menyimpan nilai-nilai tunggal atau tidak terkait. Tetapi pada Windows PlayerPrefs disimpan dalam registri, plaintext.
Jonas
7
Jika Anda sudah membuat cerita bersambung, mengapa tidak membuat cerita bersambung ke String dan menyimpannya di PlayerPrefs. Tentu ini kurang fleksibel, tapi itu satu-satunya solusi untuk game lintas platform.
TJHeuvel
2
PlayerPrefs sangat bagus untuk menyimpan data kecil seperti pengaturan, tetapi untuk seluruh savegames Anda harus menggunakan Application.persistentDataPath docs.unity3d.com/ScriptReference/…
jhocking
2
@TJHeuvel: "Anda tidak dapat melakukan IO di Web / iOS / Android" Anda pasti dapat melakukan IO di ponsel
Przemysław Wrzesiński
2

Untuk TD saya mungkin akan menyimpan secara eksklusif di antara gelombang. Dengan begitu semua yang harus Anda pikirkan adalah menara. Letakkan beberapa titik penyimpanan otomatis di level-level tersebut, tidak lebih dari 10 menit, tetapi mungkin lebih sedikit.

Tentu saja jika level Anda cukup singkat, Anda hanya dapat menyimpan apa pun selain status kampanye.

aaaaaaaaaaaa
sumber
1

Ketika saya merujuk pada kondisi saat ini dari permainan saya merujuk snapshot memori pada saat menyimpan. Anda harus dapat membuatnya kembali dari data yang akan Anda simpan pada HDD Anda.

Cara termudah adalah dengan membuat serial semua kelas Anda yang memiliki data yang perlu persisten dan membuangnya ke HDD, yang pada dasarnya melakukan dump memori. Masalah dengan hal ini adalah bahwa mengubah kelas Anda akan mengubah jumlah / jenis nilai serial dan menghancurkan penyimpanan lama. Juga karena Anda menyimpan semua itu meningkatkan waktu pemuatan. Lebih efisien untuk menandai masing-masing bidang yang sebenarnya diperlukan untuk membangun kembali "snapshot memori" saat ini dengan sistem atribut apa pun yang digunakan oleh serializer / IDE Anda. Kemudian buat kembali "snapshot memori" dari data yang disimpan.

Juga saya belum pernah menggunakan Unity sebelumnya sehingga mungkin ada sesuatu yang tertanam di dalamnya. Namun, ini adalah pendekatan yang khas.

ClassicThunder
sumber
Maksudmu aku harus menyimpan statusku di file?
Syed
1
@Syed ya, pada akhir hari itu harus ditulis ke file karena status aplikasi tidak akan disimpan dalam memori. Dengan Unity khusus Anda dapat menggunakan kelas PlayerPrefs (yang saya pikir sebenarnya menyimpan hal-hal di registri pada Windows) jika Anda ingin menghindari seluruh file membaca / menulis barang.
Tetrad