Creazione di oggetti con nomi di variabili definiti dall'utente

1

Contesto:

Sto facendo un progetto di apprendimento in XNA. Quello che vorrei essere in grado di fare è permettere al gioco di essere moddabile permettendo agli utenti di inserire valori arbitrari in un file di dati JSON che viene letto nel gioco. Il fatto è che voglio evitare hardcoding se possibile e farlo funzionare automaticamente per qualsiasi cosa l'utente lanci al motore.

Problema:

Non ho idea di come progettare le classi che possono ospitare questo tipo di comportamento, poiché la mia comprensione è che qualunque cosa carichi il JSON deve mapparlo a variabili esistenti sull'oggetto:

public class SomeGameEntity
{
    public float Strength { get; set; }
    public bool IsStrong { get; set; }
}

Ma quello che voglio è che il codice client sia in grado di fare qualcosa del tipo:

SomeGameEntity.Stats["Strength"] = 16;
SomeGameEntity.Stats["IsStrong"] = true;

La mia soluzione:

A titolo di considerazione, definirei solo alcuni tipi di dati validi, probabilmente float , bool e string (altri tipi, ad esempio XNA.Color , dovrebbe probabilmente essere dedotto da una combinazione di oggetti fluttuanti RGB sull'oggetto.)

Quindi, ciò che ha senso è creare una classe come la seguente:

public class EntityStatComponent
{
    private readonly Dictionary<string, float> _floatValues;
    private readonly Dictionary<string, string> _stringValues;
    private readonly Dictionary<string, bool> _boolValues;

    public float GetValue(string name) { }
    public void SetValue(string name, float value) { }

    public string GetString(string name) { }
    public void SetString(string name, string value) { }

    public bool GetFlag(string name) { }
    public void SetFlag(string name, bool value) { }
}

Ma questo sembra un approccio ambiguo, specialmente con tre dizionari per oggetto attivo . Probabilmente direi che ci sono meno di 250 oggetti sullo schermo alla volta (personaggi, proiettili, ecc.)

Sfortunatamente, non penso che la tipizzazione generica sia la strada da percorrere per questo, poiché per T, dovrebbe accettare un singolo tipo di dati nel dizionario. In alternativa, se permettessi di usare qualsiasi valore T tramite il metodo get / set, dovrei usare la roba if(someArg is float) , che capisco essere disapprovata.

Sto trascurando qualcosa, o c'è un modo migliore per farlo?

    
posta Kyle Baran 22.05.2014 - 02:40
fonte

1 risposta

4

Il caricamento dei valori da JSON è utile solo se a un certo punto qualcosa utilizza questi valori. Dato che vuoi permettere ai modder di usare strutture "arbitrarie" (che presumo significhi "loro stesse strutture"), è chiaro che non è il tuo codice che userà i dati da quel JSON - sarà il codice dei modder.

Ora, ci sono due modi per far sì che i modder aggiungano il loro codice al tuo gioco: modulo dinamico che carica e linguaggio di scripting incorporato .

Se usi il caricamento dinamico del modulo - il che significa che i modder scrivono il codice C # con un'API che fornisci, lo compila alla DLL, e il tuo gioco carica quella DLL - dovresti usare classi con codice duro per rappresentare la struttura dati. Tuttavia, non sarai tu quello che definisce queste classi - i modder le definiranno nei loro moduli e le invieranno come parametri generici al tuo metodo di caricamento JSON (che dovrebbe usare il reflection generico per delegarlo a una libreria JSON). In questo modo non imposterai la struttura sui modder, ma saranno comunque in grado di utilizzare una struttura tipizzata statica ben definita.

Se utilizzi un linguaggio di scripting incorporato (come LUA o JavaScript), dovresti semplicemente utilizzare una string - >% con una mappa di% in%. Sì, so che le mappe object - > string sono considerate un odore di codice nei linguaggi tipizzati staticamente, ma i linguaggi di scripting sono tipicamente dinamici. Stai per perdere comunque tutta la struttura statica quando passi i dati al linguaggio di scripting, e non hai intenzione di accedervi da C #, quindi perché non ti risparmia il problema e butta la struttura (solo per i valori di JSON, ovviamente) dall'inizio?

    
risposta data 22.05.2014 - 03:18
fonte

Leggi altre domande sui tag