2

エンティティ ベース コンポーネント システムを使用しています。

私は多くの種類のstationary objects例 を持っています

  1. 壁=ブロック
  2. 火の塔 = ブロック + 射手
  3. ウォーター タレット = ブロック + シューター
  4. バンカー = ブロック + スポナー

ここにの工場がありstationary objectsます:-

class StationaryObject{
    enum typeOfObject_enum{WALL,FIRE_TURRET, ....};
    Entity* create(typeOfObject_enum theType){ //it is enum
        switch(theType){
            case WALL: ... create some mesh, some physic body  ....
            case FIRE_TURRET: .... create some mesh, some physic body+ unique logic 20 lines ....
            ....
        }
    }
}

それは本当にうまくいきます。

質問:
100 種類の を作成したいのですがStationary objects、どこに保存すればよいですか?
それらをすべてクラスに格納するとStationaryObject、クラスが大きくなりすぎます(?)。

オブジェクトの各タイプには、小さいながらも固有のロジックがあることに注意してください。

4

2 に答える 2

4

各オブジェクト ファクトリへのマップを作成し、typeOfObject_enum必要に応じてファクトリをマップに登録できます。

各オブジェクト ファクトリは次のようになりますstd::function<std::unique_ptr<Entity>()>

enum class StationaryObjectType{WALL, FIRE_TURRET, WATER_TURRET};
const size_t STATIONARY_OBJECT_TYPE_COUNT = 3;
using EntityFactory = std::function<std::unique_ptr<Entity>()>;

class StationaryObjectFactory {
    std::array<EntityFactory, STATIONARY_OBJECT_TYPE_COUNT> factory_map; 
public:
    void registerFactory(StationaryObjectType type, EntityFactory factory){
        factory_map[static_cast<size_t>(type)] = std::move(factory); 
    }
    std::unique_ptr<Entity> create(StationaryObjectType type){
        auto factory = factory_map[static_cast<size_t>(type)];
        if (!factory)
            return nullptr;
        return factory();
    }
};

int main() {
    StationaryObjectFactory factory;

    // Register lambdas as the factory objects
    factory.registerFactory(StationaryObjectType::WALL, []{
        return std::make_unique<Wall>(); 
    });    
    factory.registerFactory(StationaryObjectType::FIRE_TURRET, []{
        return std::make_unique<FireTurret>(); 
    });

    auto wall = factory.create(StationaryObjectType::WALL);    
    auto fire_turret = factory.create(StationaryObjectType::FIRE_TURRET);
    auto water_turret = factory.create(StationaryObjectType::WATER_TURRET);

    assert(wall != nullptr);    
    assert(fire_turret != nullptr);
    assert(water_turret == nullptr);  // No WATER_TURRET factory registered
}

ライブデモ。

または、必要に応じて、抽象ファクトリ クラスの実装を使用できます。

class EntityFactory {
public:
    virtual ~EntityFactory(){}
    virtual std::unique_ptr<Entity> operator()() = 0;
};

class WallFactory : public EntityFactory {
public:
    std::unique_ptr<Entity> operator()() override {
        return std::make_unique<Wall>();
    }
};

class FireTurretFactory : public EntityFactory {
public:
    std::unique_ptr<Entity> operator()() override {
        return std::make_unique<FireTurret>();
    }
};

ライブデモ。

于 2016-09-01T08:51:43.923 に答える