oyun durumu kaydetme / yükleme?


12

oyun durumunu (profilleri) kaydetmek için en çok kullanılan yöntem veya algoritma nedir, şifreleme nasıl yapılır metin dosyaları ve ilgili şeyler veritabanları.

Sezar IV'ün mySQL kullandığını gördüm.

herhangi bir öneri.

Yanıtlar:


20

Çoğunlukla özel (ikili) bir formatta yapıldığından eminim, sadece bir dosyaya kullandığınız oyun durumu yapısından her değişkeni yazıyor veya bu dosyayı yapının bir örneğine geri okuyor. Örneğin C ++ 'da bir nesneye bayt dizisi gibi davranabilir ve sadece bir dosyaya fwrite () ya da dosyadan fread () oluşturabilir ve nesne formuna geri döndürebilirsiniz.

Java veya başka bir dil kullanıyorsanız , görevi gerçekten kolaylaştırmak için serileştirmeyi kullanmayı seçebilirsiniz . Java açıklaması bu cevabın altındadır; diğer diller (C ++ 'dan daha yüksek düzey) mutlaka kendi serileştirme kitaplıklarına veya yerleşik işlevlere sahiptir; Serileştirme rutini ne kadar verimsiz olursa olsun, günümüzde sabit disk alanı ucuzdur, özellikle de oyun durumu çok büyük olmamalı ve kendi serileştirme rutinlerinizi yazmanızı ve korumanızı engeller .

Kesinlikle gerekir değil (sadece ilk cümlesini okumak MySQL kullanmayı Bu derlemede ). Herhangi bir nedenle gerçekten ilişkisel bir veritabanına ihtiyacınız varsa , SQLite kullanın ; hafif bir veritabanı sistemidir ve tek bir veritabanı dosyasında bulunur. Ancak çoğu oyun için ilişkisel veritabanları gitmenin yolu değildir ve bunları kullanmaya çalışan şirketler genellikle gerçek bir ilişkisel veritabanı yerine anahtar / değer arama tablosu olarak kullanılır.

Yerel disk dosyalarının her türlü şifrelenmesi sadece gizlidir ; herhangi bir hacker programınızın şifresini çözdükten hemen sonra verileri koklar. Şahsen ben bu tür şeylere, özellikle de tek oyunculu oyunlara karşıyım. Benim görüşüme göre, oyun sahiplerinin (ödeme yapan müşteriler, aklınızda olsun) isterse oyuna hack etmelerine izin verilmelidir. Bazı durumlarda daha büyük bir topluluk hissi yaratabilir ve oyununuz için size daha fazla müşteri çekecek "modlar" geliştirilebilir. Akla gelen en yeni örnek , yakın zamanda piyasaya sürülen Minecraft'ta Portal modudur. İnternet üzerindeki oyuncu haber sitelerinde yayınlandı ve Minecraft'ın satışlarını artırdığını iddia edebilirsiniz.


Herhangi bir nedenden dolayı benim gibi oyun geliştirme için Java'yı kullanmak için yeterince çılgınsanız, Java'da seri hale getirmenin hızlı bir açıklaması:

Bir sınıfta oyun durumu tüm verileri tutun uygulayarak sınıf seri hale getirilebilir yapmak Serializable, kullanmak transientsize (geçici nesneler tefrika değildir) sınıfa özel örneklenmiş değişkenler karıştırın eğer anahtar kelime ve sadece kullanım ObjectOutputStreamdosyaya yazma ve ObjectInputStreamdosyadan okuma . Bu kadar.


2
Hehe, The Witcher verilerini şifrelemedi. Çok kolay bir hex editörü kaydetmek oyun dosyasını açmak, onunla biraz karışıklık ve tüm çıplak civciv kartları almak ... oh tanrım, çok üzgünüm!
Anthony

Oyunları kaydetmek için .NET ikili serileştirmesini kullandım ve C #, belki de oyun geliştirmek için Java'dan biraz daha makul bir platform. Tüm nesne grafiğini otomatik olarak nasıl kaydettiğini seviyorum. Bu eskiden çok daha zor olurdu. Tabii ki şimdi dokular gibi gereksiz parçaları hariç tutmanın zorluğu var, ancak bu başarılması gereken bir şey değil.
BlueMonkMN

Oyun geliştirmek için C # 'ın Java'dan biraz daha popüler olduğunu kabul etmiyorum . Daha makul bazı öznellik anlamına gelir ve hem XNA hem de Java'nın geliştiricisi olarak Java'yı tercih ederim. İsterseniz, serileştirme ile ilgili talimatları C # 'da listelemekten çekinmeyin, hiç yapmadım ama cevabımı düzenleyebilirim. Java'nın serileştirmesi tüm nesne grafiğini kaydeder ve değişkenler üzerindeki 'geçici' anahtar kelime dokular gibi gereksiz parçaları hariç tutar; geçici olmayan tüm üyelerin Serializable olması gerekir ya da bu sorunu çözmek için özel bir writeObject yöntemi yazabilirsiniz.
Ricket

Python'un turşusu sizin için tüm nesne grafiğini de kaydedecek ve kullanımı son derece kolay. Serileştirmeyi kaldırma zamanı geldiğinde, tamamen sulandırılmış nesneleri geri alırsınız
drhayes

Yerleşik ikili biçimlendiriciyi kullanırken, belirli alanları C # /. NET'te serileştirmeden hariç tutmak, [NonSerialized] özniteliğiyle onları süslemek kadar basittir. Bununla birlikte, gözden kaçırılması kolay olan, derleyici tarafından oluşturulan olayların (yani, özel ekleme / kaldırma operatörleri olmayan herhangi bir olay) abonelerini depolamak için bir destek alanı oluşturmasıdır. Bu nedenle, olay işleyicilerini serileştirilmiş bir nesne grafiğine yanlışlıkla (ve bilmeden) dahil etmek kolaydır. Bu sorunu aşmak için, olay bildirimine NonSerialized özniteliğini eklemeniz gerekir, ancak "field:" niteleyicisini eklemeniz gerekir:[field: NonSerialized]
Mike Strobel

3

C ++ 'da kendi kodunuzu yazıyorsanız, ikili dosyaları kullanabilirsiniz . İkili dosyalar, gizleme yoluyla size bir şifreleme biçimi sağlar. Ancak tüm internette belgelendiği gibi, bu çok zayıf bir güvenlik şeklidir.

VEYA, insan tarafından okunabilir bir çözüm istiyorsanız RapidXML gibi bir şey kullanabilirsiniz .

Bir çeşit çerçeve kullanıyorsanız, dosya destek işlevlerine bakın. HTH


0

Gördüğüm çoğu oyun ikili dosyaları okumak / yazmak için sadece elle yazılmış kodu kullanır. Genellikle, disk üzerinde format, bir nesnenin bellek düzeninin tam bir kopyası olacaktır, bu nedenle yükleme sadece:

  1. Dosyayı belleğe okuyun.
  2. İşaretçiyi nesne türüne arabelleğe al.

Hızlı, ancak bakımı, platforma özgü ve esnek olmayan bir angarya.

Son zamanlarda, birkaç oyunun SQLite kullandığını gördüm. Konuştuğum insanlar hoşuna gidiyor gibi görünüyor.


0

Serileştirme diğer bazı cevaplarda belirtilmiştir ve bunun makul bir çözüm olduğunu kabul ediyorum. Başarısız olmasının bir yolu sürüm oluşturmadır.

Oyununuzu serbest bıraktığınızı ve insanların oynadığını ve bazı kaydetme oyunları oluşturduğunu varsayalım. Daha sonra bir yamada bir hatayı düzeltmek veya bazı özellikler eklemek istersiniz. Basit bir ikili serileştirme yöntemi kullanırsanız ve sınıflarınıza bir üye eklerseniz serileştirmeniz, müşteriler düzeltme ekinizi yüklediğinde eski kaydetme oyunlarıyla uyumlu olmayabilir.

Bu nedenle, hangi yaklaşımı kullanırsanız kullanın, oyunu ilk kez bırakmadan önce bu sorunu düşündüğünüzden emin olun! Müşteriler bir yama uyguladıktan sonra baştan başlamak zorunda kalmazlarsa mutlu olmazlar.

Bundan kaçınmanın bir yolu, her temel veri türünün, oyunun her sürümü için hangi verilerin kaydedileceğini ve yükleneceğini bilecek kadar akıllı olan Kaydet (sürüm) ve Yükle (sürüm) yöntemlerini uygulamasını sağlamaktır. Bu şekilde, kaydetme oyunlarınızın geriye dönük uyumluluğunu destekleyebilir ve bir kullanıcı, oyunun çalıştığından daha yeni bir sürümünden bir kaydetme oyunu yüklemeye çalışırsa zarif bir şekilde başarısız olabilirsiniz.


1
Kısa bir not olarak: Oyunun her sürümü için "kaydet" ve "yükle" işlevlerini uygulamak hızlı bir şekilde bakım kabusu haline gelir. Bir sürüm numarası gömmek, oyunun mevcut sürümü için "kaydet / yükle" işlevlerini yazmak ve en güncel olmayan sürümden geçerli sürüme bir "dönüştürme" işlevi yazmak daha iyi bir çözüm buldum. Ardından, tüm dönüşüm işlevlerinizi yanınızda bulundurun. On sürümlü bir oyunu yüklemeye çalışmak, on dönüştürme işlevini seri olarak çalıştırır, ardından yerel "geçerli oyun sürümünü yükle" işlevi kullanılır.
ZorbaTHut

Uzun vadede bakımı çok daha kolay - bir dizi "önceki her oyun dosyasını yükle" işlevlerini hızlı bir şekilde tutmak, polinom-zaman operasyonuna dönüşüyor.
ZorbaTHut

Üzerinde çalıştığım oyunlarda bu karmaşık değil - yükleme / kaydetme yöntemlerinin birden fazla kopyasını tutmak yerine, tek bir yöntem hangi baytın okunacağını ve yazılacağını belirlemek için sürüm numarasını kullanır. Yalnızca yapıları yazmakla kalmaz, aynı zamanda ilkel veri türü düzeyinde (ör. ReadByte / ReadFload / vb.) İşlemler olarak yükleme ve kaydetmeyi uygularsanız bu daha da kolaylaşır. Daha sonra yeni bir üye eklerseniz if (version> 10) {someNewByte = ReadByte (); } Bu şekilde uygulamak, farklı endian platformlarını desteklemeyi de kolaylaştırır.
kevin42

Sürüm oluşturma desteğini iyileştirmenin bir başka yolu, nesnelerin serileştirme / serileştirme yöntemlerinin ayrı ayrı değerleri doğrudan akıştan yazmasını / okumasını önlemektir. Bunun yerine, nesneler sahip oldukları verileri anahtar / değer çiftlerini kullanarak bir özellik çantasına yazabilir ve ardından çantayı akışa yazabilir. Serileştirme sırasında nesneler torbadan değerleri isimle okuyabilir. Ancak kevin42 gibi belirli sürüm numarası kontrollerine sahip olmak yerine, eksik değerlerin nasıl işleneceğine dair kurallarınız olabilir (yani, gerekli değer çantada olmadığında standart bir varsayılan değer kullanın).
Mike Strobel

0

Seviyelerinizi saklamak için kullandığınız formatın aynısını kullanabiliyorsanız, bu bir bonus demektir.

Örneğin, Peggle gibi bir oyunun ilk masa düzeni, top sayısı, mevcut skoru (ilk masa için 0) vb. Olabilir. Sonra kaydedilmiş bir oyun tamamen aynı formatı kullanabilir.

Aynı biçimi kullanırsanız, oyunu kaydet ve seviye yükü işinizi kolaylaştıracak kodu paylaşabilir!

Gerçekten büyük harita dosyaları olan bir oyun için, kaydetme oyunu referans olarak harita dosyasını içerebilir. Başlangıç ​​seviyesindeki dosyalar da aynı şeyi yapabilir, bu da, bazı nedenlerden ötürü hikayenin karakteri aynı yere geri dönmesi durumunda, bu haritaya geri dönmeyi de kolaylaştırır, ancak bazı NPC'lerin ölmesi ve hepsinin yanında ölü bedenler olması bitmiş.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.