Progettare una classe (elemento) che applica i bonus a un'altra classe (giocatore)

0

Ho cercato di essere il più chiaro possibile nel titolo, ma sarò più specifico della mia situazione.

Problema 1 : Ho un giocatore con alcune slot che possono contenere oggetti. Ogni slot è un Slot<Equippable> dove Equippable è un'interfaccia solo per raggruppare elementi diversi insieme: Armatura, Arma, ecc. Ora vengo ad affrontare un problema: il Player ha alcuni parametri (ad es. Destrezza, Forza, ecc.) E quando un oggetto è indossato, può influenzare uno di questi parametri. Fino ad ora, avevo elementi semplici che aggiungevano un bonus a un parametro, che era determinato dallo slot su cui si trovava l'oggetto (ad es. Hands - > Forza, Piedi - > Destrezza); quindi ho appena controllato il bonus nell'oggetto usurato e calcolato il parametro giusto, quando ne avevo bisogno. Ma ho bisogno di cambiare questo : ho bisogno di un modo più versatile per gestire questa situazione, perché non voglio legare il parametro allo slot e io non posso controllare ogni oggetto indossato in qualsiasi momento ho bisogno di ottenere un parametro. Invece, penso che dovrei essere in grado di eseguire converse , ad esempio aggiornare il parametro corretto quando un oggetto è indossato. So che questo può richiedere molto tempo per progettare completamente e, naturalmente , non sto chiedendo questo. Ho solo bisogno del giusto input perché sono bloccato.
Per dirla in parole semplici, ho bisogno di qualcosa come: il giocatore indossa un oggetto, l'oggetto dà un bonus o più? Se sì , applica bonus ai parametri corretti. Se non , fai qualcos'altro.
Possibile soluzione : crea un metodo di aggiornamento che viene chiamato ogni volta che un oggetto viene indossato o rimosso. Contro : Devo fare attenzione in ogni posto che dovrei chiamare questo metodo. Inoltre, questo metodo dovrebbe verificare quale tipo di oggetto è, se dà un bonus o più (e cosa), o se fa qualcosa di completamente diverso.

Problema 2 : questo è legato al primo problema, quindi lo metto nella stessa domanda. Concettualmente, ho diviso i parametri in indipendente e dipendente . I primi dipendono solo dal Player, quindi sono memorizzati lì, i secondi sono calcolati dai primi e, possibilmente, dagli elementi (direttamente). Fino ad ora, ho mantenuto i parametri dipendenti solo come proprietà, il cui getter ha calcolato la giusta formula quando necessario. Quindi i parametri dipendenti non vengono memorizzati , ma solo calcolati come "output" quando richiesto.
Ma introdurre gli oggetti mi richiede di cambiare quei valori, secondo gli articoli. Qui seguivo lo stesso ragionamento di prima: ho controllato l'articolo giusto e calcolato direttamente nella formula. Da ora ho bisogno di cambiare direzione (come nel problema 1), ho bisogno di aggiornarli ogni volta che viene indossato l'elemento corretto.
Due possibili soluzioni :

  • Memorizza un campo Bonus e prendilo in considerazione nel calcolo. Pro : cambiamento immediato; Contro : potrei dover memorizzare vari bonus diversi, per finire con un pasticcio.
  • Salva anche i parametri dipendenti. Pro : potrei usare lo stesso ragionamento del Problema 1, quando risolto. Contro : ora ho un parametro memorizzato e non solo il risultato di un calcolo, quindi ho bisogno di cambiarlo in qualsiasi momento i parametri indipendenti sono cambiato. Questo probabilmente può essere risolto come nel Problema 1.

Spero che tu possa davvero aiutarmi con questo. Forse sto solo esagerando e può essere risolto con un approccio più semplice o eseguendo un'implementazione intelligente degli articoli.

Addendum : darò il tuo più contesto, su come vengono implementati gli articoli. Per ora, contengono solo un semplice bonus (o più) e lo slot in cui sono posizionati determina il parametro. Ad esempio, un'armatura mi dà due bonus che devono essere aggiunti a ArmorClass (parametro) e un altro valore implicato nel calcolo. Poiché solo uno slot contiene Armor, so dove controllare. Per evitare di dipendere dallo slot, ho intenzione di includere una chiave per ogni bonus che mi dice cosa modificare con esso. Inoltre, altri elementi (come gli anelli, ecc.) Non hanno tre valori fissi come Armatura ma hanno un numero variabile di essi. Probabilmente avrò bisogno di un dizionario. Quindi l'operazione sarà: wear item - > controlla i bonus - > controlla i parametri corrispondenti nella chiave - > modificarlo in Player; e questo è più precisamente quello che sto chiedendo nel Problema 1.

    
posta Harnak 22.04.2017 - 01:31
fonte

1 risposta

1

Questa è solo una cosa rapida che mi viene in mente. Spero che aiuti e spero di aver compreso correttamente i tuoi problemi:)

Per un approccio a "risolvere" entrambi i problemi e le cose che hai affermato nell'addendum, questo potrebbe essere un possibile progetto:

// Create an enum of possible stats
enum StatType {
    Strength, Dexterity, ...
};

// This is the basic idea of a stat/parameter. 
struct Stat {
    StatType Id;  // Example: Strength
    int Value;  // Example: 10
    // Whatever other fields you want to 
}

class Stats {
    public Stat GetStat(StatType Id) { 
        return statsDict[Id]; // Think about what you wanna do if the stat doesn't exist. You might wanna create that stat and initialize its value with 0 and then return it.
    }

    public void SetStat(StatType Id, Stat val) {
        // Set stat in dict
    }

    private Dictionary<StatType , Stat> statsDict;
}

Nell'interfaccia di Equippable, aggiungi le statistiche per memorizzare le statistiche interessate dall'attrezzatura:

interface Equippable {
    Stats AffectedStats;
    ...
}

Quindi nella classe del giocatore potresti avere dei campi che memorizzano le statistiche di base del giocatore e le statistiche combinate. Quando un giocatore equipaggia un oggetto, dovrai ricalcolare le statistiche combinate.

class Player {
    Stats BaseStats;
    Stats CombinedStats;

    void Equip(...) {
        // Code to equip item
        // Then recalculate the CombinedStats
        this.CalculateCombinedStats();
    }

    void CalculateCombindedStats() {
        // Add Base Stats + all Equipment Stats and store the results to this.CombinedStats
    }

    void PlayerStatsChange(...) {
       // Change Player's base stats (LevelUp, ...)
       // The recalculate the CombinedStats
       this.CalculateCombinedStats();
    }
}

In questo modo puoi sempre accedere alle statistiche Base e Combinata separatamente (il che risolve il problema 2) e aggiorni solo le statistiche combinate quando cambiano effettivamente (il che risolve il problema 1). Un elemento che incrementa più statistiche non è più un problema, dal momento che il dizionario è flessibile.

    
risposta data 22.04.2017 - 11:22
fonte

Leggi altre domande sui tag