Oyun genelinde değişkenleri saklamanın en iyi yolu


23

Zorluk, çözünürlük, tam ekran vb. Şeyler için seçenekler ekranım var, ancak çalışma sırasında bu değişkenleri saklamanın / elde etmenin "en iyi" yolunu bulmakta zorlanıyorum.

Şu anda, Constantstüm GameOptionnumaralamaları içeren bir sınıf uyguladım , ancak tüm bu seçenekler için varsayılanı nasıl seçerim? Ayrıca, seçili olan enumu nasıl alabilirim?

Çözünürlük ile ilgili olarak, özellikle değerleri saklamaya karar verdim, ancak varsayılan veya şu anda depolanan değerleri nasıl alacağımı bilmiyorum. Herhangi bir yön harika olurdu; Teşekkürler! :)

namespace V1.test.RPG
{
  public class GameOptions
  {
    public enum Difficulty { EASY, MEDIUM, HARD }
    public enum Sound { ON, QUIET, OFF }
    public enum Music { ON, QUIET, OFF }
    public enum ResolutionWidth
    {
        SMALL      = 1280,
        MEDIUM     = 1366,
        LARGE      = 1920,
        WIDESCREEN = 2560
    }
    public enum ResolutionHeight
    {
        SMALL      = 800,
        MEDIUM     = 768,
        LARGE      = 1080,
        WIDESCREEN = 1080
    }
    public Boolean fullScreen = false;
  }
}

Not: SO'ya sordum ve beni bu yere yönlendirdiler. Orada bir yorum var ama bunu yapmanın farklı yollarını / en çok kullanılan yollarını duymak istiyorum.


1
Doğru yerde sordun; Seni buraya kim gönderdiyse yanıldı. Size yardımcı olmak için soruyu yine de cevapladım, ancak bu oyun gelişimine özgü bir soru değil, bu genel bir programlama sorusu.
14'te

Ben sadece SO konuyu okudum; Scott Chamberlin'in cevabını beğendim.
14'te saat

@jhocking Sıradan bir uygulamadan farklı olabilecek oyun geliştirmeye özgü herhangi bir husus olması durumunda, bu yolu işaret ettim. Ayrıca, bu konuyla ilgili çok yaygın olduğu için kanonik bir soru cevap olabilir.
Chris Hayes,

Globals hakkındaki asıl soruya nezaketen, lütfen orada belirli bir karar seti olduğunu varsaymayın.
Lars Viklund,

Yanıtlar:


32

Büyümeyi planlama:
Sabit kodlu sabitler küçük projeler için iyidir, ancak sonunda yazılımınız büyüdükçe, bu ayarları her şeyi yeniden derlemeden değiştirmek isteyebilirsiniz. Oyun çalışırken ayarları değiştirmek isteyeceksiniz ve sabit kodlu sabitlerle bunu yapamazsınız.

Cvars:
Projeniz büyür sonra, bir göz atmak isteyebilirsiniz cvars . Bir CVAR bir "akıllı değişken" dir, tabiri caizse, çalışma süresi boyunca bir konsol, terminal veya UI ile değişiklik yapabilirsiniz. CVAR genellikle altta yatan bir değeri saran bir nesne açısından uygulanır. Böylece nesne, değeri kaydedebilir ve dosyaya kaydedebilir / yükleyebilir. CVAR nesnelerini bir adla veya başka bir benzersiz tanımlayıcıyla erişmek için bir haritaya kaydedebilirsiniz.

Konsepti biraz daha açıklamak için, aşağıdaki sözde kod, bir intdeğeri saran bir CVAR türünün basit bir örneğidir :

// just some flags to exemplify:
enum CVarFlags {
    CVAR_PERSISTENT, // saved to file once app exits
    CVAR_VOLATILE    // never saved to file
};

class CVar {
public:
    // the constructor registers this variable with the global list of CVars
    CVar(string name, int value, int defaultValue, int flags);

    int getValue();
    void setValue(int v);
    void reset(); // reset to the default value

    // etcetera...

private:
    int flags; // flags like: save-to-file, etc.
    int value; // the actual value
    int defaultValue; // the default value to reset the variable to
};

// global list of all CVars:
map<string, CVar> g_cvars;

Global erişim:
Yukarıdaki örnekte, yapıcısının CVarher zaman değişkeni global cvarsharitaya kaydettiğini varsaydım ; bu oldukça yararlıdır, çünkü böyle bir değişkeni bildirmenize izin verir:

CVar my_var = new CVar("my_var", 0, 42, CVAR_PERSISTENT);

Bu değişken genel haritada otomatik olarak kullanıma sunulur ve haritayı değişkenin adıyla indeksleyerek başka herhangi bir yerden erişebilirsiniz:

CVar v = g_cvars.find("my_var");

Kalıcılık:
Oyun kapanırken haritayı tekrarlayın ve olarak işaretlenmiş tüm değişkenleri CVAR_PERSISTENTbir dosyaya kaydedin . Oyun bir dahaki sefere başladığında, onları yeniden yükleyin.

İçtihat hukuku:
Daha sağlam bir CVAR sistemi örneği için, Doom 3'te belirtilen uygulamaya göz atın .


4

Eh ilk değerler neyi bir enum tanımlayıp kapalı olabilir , değerler değil ne vardır . Bu nedenle, enum bildirdikten sonra başka bir değişken bildirmeniz gerekir. Örneğin:

public enum Sound
{
    ON,
    QUIET,
    OFF
}

public Sound soundValue;

Bu örnekte, şimdi soundValueAÇIK, SESSİZ veya KAPALI olarak ayarlayabilirsiniz .


Sonra kodunuzu, kodunuzun diğer bölümlerinin bu "ayarlar" nesnesine erişebilmesi için yapılandırmanız gerekir. Bu kısım için de yardıma ihtiyacınız olup olmadığını bilmiyorum, ancak bu sorunu gidermek için kullanılan ortak kalıplar arasında tekiltonlar (bu günlerde kaşlarını çattıyor) veya servis yer belirleyicileri veya bağımlılık enjeksiyonu var.


1

glampert çözümü çok tamamlandı, ancak kişisel deneyimimi ekleyeceğim.

Aynı problemle karşılaştım ve çözümüm statik bir Değişkenler sınıfı kullanmaktı.

Değişkenler sınıfı dahili olarak bir dizeyi dizeden dize tutar (şimdiye kadar tüm değişkenlerim yalnızca dizelerdir) ve alıcılar ve ayarlayıcılar aracılığıyla erişilir.

Önemli olan, küresel değişkenlere erişimin, kodun tamamen alakasız kısımlarının birbirleriyle aniden etkileşime girmesi nedeniyle her türlü ince hatayı ortaya çıkarabilmesidir.

Bundan kaçınmak için, aşağıdaki anlambilimi dayattım: setbu isimde bir değişken sözlükte zaten mevcutsa , yöntemi kullanmak bir istisna atar getve değişkeni sözlükten döndürmeden önce siler.

İki ek yöntemler ne beklediğiniz sağlamak, setAndOverwriteve getAndKeep. Diğer yöntemlerin semantiğinin amacı, "bu yöntemin bu değişkeni başlatması gerekiyor, ancak başka bir yöntem daha önce yaptı" türündeki hataları kolayca tespit edebilmenizdir.

Sözlüğü başlatmak için, ilk değişkenler bir json dosyasına kaydedilir ve oyun başladığında okunur.

Maalesef oyunumla çok uzağım olmadı, bu yüzden bu yaklaşımın sağlamlığına tanıklık edemiyorum. Yine de, belki CVAR'ların üstünde ilginç bir şey sağlayabilir.

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.