2013-06-10 15 views
6

Ho un mostro di classe e quando viene creata un'istanza deve collegare ogni mostro con l'arma. ex. Il mostro dei Gryphon dovrebbe avere attacco Grifone 1 e attacco Grifone 2, ovviamente il nome dell'attacco è TBD, ma per ora usare bene l'attacco 1 e 2. GrifoneCollegamento dati vettoriale

Currenly ho questo.

#include <vector> 

typedef enum {Living, Dead, Nature} Race; 
typedef enum {Gryphon, Oracle, Mercenary,Templar, 
       Satyr,Fallin Angel,ArcAngel,Satan,Grimreaper, 
       Unbaptized Babies,Boggart,Succubus,Meat Wagon, 
       Djinns,Manticore,Water Nymph,Plant Nymph, 
       Mother Nature, Cannibal Tribesmen,Wyvern, 
       Vegetable Lamb, Ent, Lava Worm, Alpha Dragon 
       } MonsterType; 
typedef enum {gryphon1,Oracle1, Mercenary1,Templar1, 
       Satyr1,Fallin Angel1,ArcAngel1,Satan1,Grimreaper1, 
       Unbaptized Babies1,Boggart1,Succubus1,Meat Wagon1, 
       Djinns1,Manticore1,Water Nymph1,Plant Nymph1, 
       Mother Nature1, Cannibal Tribesmen1,Wyvern1, 
       Vegetable Lamb1, Ent1, Lava Worm1,Alpha Dragon1, 
       Gryphon2, Oracle2, Mercenary2,Templar2, 
       Satyr2,Fallin Angel2,ArcAngel2,Satan2,Grimreaper2, 
       Unbaptized Babies2,Boggart2,Succubus2,Meat Wagon2, 
       Djinns2,Manticore2,Water Nymph2,Plant Nymph2, 
       Mother Nature2, Cannibal Tribesmen2,Wyvern2, 
       Vegetable Lamb2, Ent2, Lava Worm2, Alpha Dragon2 
       } Weapon; 

Class Monsters{ 

protected: 
    MonsterType type; 
    Race race; 
    std::vector<Weapon> weapon_list; 
public: 
    bool flying; 
    bool lava; 
    bool water; 
    int life; 
    int karmaCost; 
    int move; 
    int crit; 
    int defMagic; 
    int defNonMagic; 
    bool isDead; 
    bool canMove; 
    bool canAttack; 
    bool onFlag; 
    int nextTurn; 


}; 

io non sono sicuro circa il vettore, né se il suo bisogno era solo alcuni esperimenti avrei dovuto vedermela con .. Ma qual è il modo migliore per collegare l'arma al mostro? Si noti inoltre ogni arma ha valori che va con esso, in modo

gryphon attack 1 { 
    int range = 10 
    int ticks = 5 
    bool magical = false 
    int power = 23 
    bool heals = false 
} 


gryphon attack 2 { 
    int range = 5 
    int ticks = 7 
    bool magical = true 
    int power = 29 
    bool heals = true 
} 

i valori effettivi vengono letti da un ini o di rete, quindi non preoccupa ancora i valori reali, ma ho bisogno di sapere che posso aggiungere il valori gryphon->weapon1->range = 5

Sono ancora molto nuovo a questo quindi se qualcosa sembra molto sbagliato per favore dimmi.

+0

Qual è la domanda? – Spook

+0

Cercherò di rispondere "qual è il modo migliore per collegare l'arma al mostro?". Il tuo uso di 'std :: vector weapon_list' è abbastanza buono, riflette che i mostri possono avere più armi e che le relazioni" ha-a "dovrebbero essere codificate usando [composizione dell'oggetto] (http://en.wikipedia.org/wiki/Object_composition). Ti consiglio di creare un'altra classe per Arma, invece dell'enumerazione, quindi puoi associare i numeri a ciascuna arma. –

+0

sì, quella era la domanda. sono stanco di alcuni modi diversi ma nessuno sembra funzionare, penso che sia più di non conoscere l'ignoto di nulla. –

risposta

4

Per esperienza: l'approccio che hai scelto porterà a molti problemi in futuro. So che non rispondo esattamente alla tua domanda, ma lo faccio solo per risparmiarti dei problemi. Perdonami e/ord ignorare questo sotto se vuoi farlo a modo tuo.

Non creare classi specializzate per ognuno dei tuoi mostri o personaggi. Crea una singola, astratta, una sorta di classe composta con molte proprietà che descrivono vari aspetti di quell'oggetto di gioco. Un po 'come che:

// simplified class declaration, not a C++ code 
class GameActor { 
    ActorVisualization visualization; 

    vector<InventoryItems> inventory; 

    ActorStatistics stats; 

    vector<ActorEffects> appliedEffects; 
} 

Tale oggetto astratto verrà utilizzato per tutte le Actors nel vostro gioco, tra cui personaggi giocanti.

Il passaggio successivo consiste nell'utilizzare il modello di visitatore per tutte le cose che possono accadere a questo attore.

// continued 
class GameActor { 
    bool applies(Visitor& visitor); 

    void accept(Visitor& visitor) { 
    if (applies(visitor)) { 
     visitor.visit(this); 
    } 
    } 
} 

class Visitor { 
    void visit(GameActor& actor); 
} 

estendere la vostra GameActor per soddisfare le vostre esigenze, se necessario. Ogni volta che aggiungi nuove funzionalità, prova a utilizzare il meccanismo dei visitatori già implementato. Creare una nuova proprietà di GameActor solo se necessario.

Esempi di visitatori? Potrebbe essere scritto in modo diverso, ma spero che chiarisca come dovrebbero essere fatte le cose.

class DamageInflictedVisitor { 
    int amount; 
    damageType_t dmgType; 

    void visit(GameActor& actor) { 
    double res = actor.getStats().getResistances().getResistanceForType(dmgType); 
    int finalAmount = amount * (1-res); 
    actor.getStats().inflictDamage(finalAmount); 
    } 
} 

class ActorAliveVisitor { 
    void visit(GameActor& actor) { 
    if (actor.getStats().hp <= 0) { 
     if (actor.getType() == AT_MONSTER) { 
     // remove from the game, create a new ExperienceGained visitor applicable for players, etc. 
     } else if (actor.getType() == AT_PLAYER) { 
     // notify the game that the given player is dead 
     } 
    } 
    } 
} 

Utilizzando tali semplici visitatori che avete molto buona leggibilità del codice, si sa quello che ogni visitatore fa semplicemente guardando il suo nome.

+0

Iam non so al 100% so cosa vuoi dire, ma sì, non voglio solo 1 classe "Mostri" quindi in main potevo fare "addMonster (Gryphon)" e impostare tutti i dati per quel mostro. Mi piace molto come lo dici e proverai, ma non sono sicuro che funzionerà. –

+0

@GlenMorse questo approccio è un po 'difficile da capire e ancora più difficile da utilizzare correttamente. Ma è molto flessibile e versatile. Attenersi all'astrazione e utilizzare bene il visitatore. – Dariusz

+0

@GlenMores Ho esteso la risposta con i campioni – Dariusz

1

Cerca di creare una struttura gerarchica per i tuoi mostri anziché una grande lista di caratteri. Per esempio mostro di baseclass che ha solo posizione/orientamento e una razza. quindi fai una classe derivata LivingMonster, che ha aggiunto salute per esempio, e una classe LivingArmedMonster che ha l'arma. questo assicurerà che non avrai una classe gonfia e sarà più facile aggiungere mostri in seguito che usano altre funzioni senza far esplodere la grande classe mostro.

come per la tua arma: la lista è una grande idea, l'unica cosa che aggiungerei è forse usare un puntatore da allora puoi avere diverse armi (che derivano dalla classe base: arma) senza cambiare la lista. inoltre renderà più facile lo scambio di armi tra mostri (hai un deposito di armi che crea tutte le armi), quindi puoi far cadere e raccogliere l'arma, quindi devi solo spostare il puntatore dal vettore di arma di 1 mostro all'altro. questo è molto meno intenso di copiare l'oggetto completo

+0

Non sono sicuro che avere così tante classi sia buono? ma in ogni modo potrei vedere un esempio di questo .. –

+0

Non so quanto è grande il tuo gioco attualmente, o quanto sarà grande, ma vale la pena di tenerlo presente il più presto possibile nello sviluppo. perché se non pensi all'architettura in anticipo potresti trovarti nei guai più tardi causandoti di dover refactoring molto. come ho detto è più indicato come un esempio di come di solito strutturare il codice .. che è quello che hai chiesto penso che – Giel

+0

sì, al momento il gioco abbia circa 15 classi, non so se aggiungere altro per questo farà è sempre più confuso. Ma ricevo anche quello che dici, ma ho bisogno di un esempio di codice come quello che mi confonde come codificare quello che hai detto .. –

1
Class Weapon { 
    int range; 
    int ticks; 
    bool magical; 
    int power; 
    bool heals; 
    public Weapon(int range, ......){ 
     this->range = range; 
     ... 
    } 
}; 

Class Monster{ 
protected: 
    MonsterType type; 
    Race race; 
    std::vector<Weapon> weapon_list; 
public: 
    int life; 
    int karmaCost; 
    ... 
    void addWeapon(Weapon w){ 
     weapon_list.push_back(w); 
    } 
}; 

Class FlyingMonster : public Monster{ 
    public: 
    int flightSpeed; 
} 


Class MonsterFactory{ 
    static FlyingMonster *CreateGryphon(){ 
     FlyingMonster *gryphon = new FlyingMonster(); 
     gryphon.addWeapon(WeaponFactory::CreateGryphonAttack1()); 
     gryphon.addWeapon(WeaponFactory::CreateGryphonAttack2()); 
     return gryphon; 
    } 
}; 

Class WeaponFactory{ 
    static Weapon* CreateGryphonAttack1(){ 
     Weapon* w = new Weapon(gryphonAttack1BaseRange); 
     return w; 
    } 
}; 

FlyingMonster* tom = MonsterFactory::CreateGryphon(); 
tom->weapon_list[0].range = 50;