Question

J'écris un jeu et il va utiliser un système d'entités basé sur des composants. Les deux premiers composants que j'implémente sont EntityRepresentation et EntityState. La représentation contient les animations et l'état décide de la manière dont l'entité doit réagir aux événements du jeu (exemples d'EtityStates: debout, sautant, attaquant, mort, tombant).

EntityRepresnetation décide quelle animation dessiner sur l'écran en fonction de EntityState de l'entité. Si l'entité est en état de "saut", l'animation correspondante sera jouée. (Voir la fonction EntityRepresentation :: changeAnimation ().)

Voici comment j'ai écrit le cours ...

class EntityRepresentation
{
  public:
    void draw(float x, float y, long currentTime, DrawingContext& dc) {
        // ...
    }

    void changeAnimation(const EntityState::Id& stateId) {
        currentAnimation = animationMap_[stateId];
    }

  private:
    map<EntityState::Id, const Animation*> animationMap_;
    const Animation* currentAnimation_;
};

Il y a quelque chose que je n'aime vraiment pas avec mon approche actuelle ...> :( La partie EntityState :: Id. Actuellement, l'EntityRepresentation mappe chaque animation qu'elle contient à un EntityState :: Id spécifique. L'ID est unique à chaque classe qui dérive d'EntityState (unique à la classe, pas à l'instance). Ces ID sont essentiellement des chaînes qui doivent être écrites à la main dans le constructeur de la classe, ce qui signifie qu'ils sont très sujets aux collisions de noms - d'autant plus que Je prévois de rendre le jeu scriptable (Python).

Quelqu'un peut-il me donner des conseils sur la façon dont je peux atténuer ce problème que j'ai avec les identifiants. J'ai vu beaucoup d'implémentations du système basé sur des composants dans des jeux qui utilisent également des identifiants, mais je ne les aime toujours pas. Cela me frotte dans le mauvais sens.

Vous pouvez peut-être suggérer une modification de conception, de sorte que EntityRepresentation ne doive pas connaître le type de EntityState, tout en préservant l'encapsulation.

Était-ce utile?

La solution

Utilisez typeid (), c'est à ça que ça sert.Vous pouvez utiliser un const type_info* comme type de clé.

Alternativement, vous savez, vous pouvez simplement utiliser l ' héritage réel , comme appeler une fonction virtuelle pour obtenir l'animation actuelle, ce qui serait beaucoup plus intelligent.

Autres conseils

En supposant que les ID associés à chaque EntityState ne sont pas nécessaires au moment de la compilation, une astuce que j'ai utilisée est d'utiliser des pointeurs comme ID.Cela fonctionne particulièrement bien si EntityState est un singleton, auquel cas vous pouvez simplement utiliser l'adresse de l'instance de singleton comme ID.Sinon, l'allocation statique d'un petit morceau de mémoire pour chaque ID fonctionne bien.

class EntityState {
public:
    EntityState(void *id) : mId(id) { }
private:
    void *mId;
};

class EntityStateJump : public EntityState {
public:
    EntityStateJump() : EntityState(getId()) { }
private:
    void *getId() {
        static void *id = new int;
        return id;
    }
};

Modifier: modification mineure pour éviter les problèmes d'ordre d'initialisation statique.

Je suggère d'implémenter la conception en utilisant modèle d'état

class EntityState
{
public:
    EntityState(const Animation* animation);
    static const EntityState* getStandingState();
    static const EntityState* getJumpingState();
    static const EntityState* getAttackingState();

    const Animation& getAnimation() const;

protected:
    const Animation* pAnymation_;
};

class EntityRepresentation
{
public:
    void draw(float x, float y, long currentTime, DrawingContext& dc) {
        // ...
        const Animation& animation(state_->getAnimation());
    }

    void changeState(const EntityState* newState) {
        state_ = newState;
    }

private:
    const EntityState* state_;
};

void EventHandler(EntityRepresentation& entity)
{
    entity.changeState(EntityState::getJumpingState());
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top