регистрировать название объекта в игре, создавать объект по игровому названию, названию класса создавать какой-либо другой объект с начальными установками из своего нутра.
Сразу оговорюсь, что это всего лишь мысли в слух и надо срочно покурить кинигу паттернов C++ на предмет паттерна завод/фабрика, дабы избежать велосипедизма с многократными имплементациями различных фабрик.
т.е есть завод с конвеерами по производству данного типа обьекта, например:
- // пример приведён псевдо кодом,
- // семантика 'L' это мой ник: Lolmen
- // во избежании пересечений с неоговоренными
- // в сообщении деталями.
- // создаём конвеер таким вот образом:
- Factory.Register( CLASS_NAME, gameName );
- // например в классе бомбы сделаем след:
- // в bomb.cpp перед непосредственной имплементацией класса LBomb
- RegisterFactory( LBomb, "fake_bomb" );
- // Добавит конвеер для рождения бомб, сделает ссылку на бомбу
- при создании оной в список игровых Entities.
- // теперь нам нужно допустим,
- // родить обьект в мире при каком-то дейтвии,
- // например при вводе в консоль entity_create "entity_name" "position[x y]"
- // например entity_create 512.0 286.0 spawn
- void LWorld::OnConsoleCmdCreateEnt( const LString &name, const LVec2D &position, bool_t bShouldSpawn )
- {
-    LEntity *pSomeObj = CreateEntityByName( name, bShouldSpawn );
-    
-    if ( pSomeObj ) // убедимся что такой конвеер есть!
-       pSomeObj->SetPosition( position );
- }
- // или в классе гранатомёта родить гранату:
- void LGrenadeLauncher::PrimaryAttack( void )
- {
-    LGrenade *pGrenade = 0;
-    // метод Create рождает энитю указывая начальные положения в мире
-    // и флаг рождать или просто создать
-    if ( Create( pGrenade, "projectile_grenade", GetShootPos(), GetAngles(), true ) )
-    {
-       pGrenade->SetMoveType( MT_FLY ); // тип перемещения
-       pGrenade->SetLifeTime( 10.0f ); // время жизни 10 секунд
-    }
- }
- // удалять тоже просто:
- void RemoveEntity( LString &name, LEntity *pEntity );
Удаление и создание работает через список конвееров завода и список созданных в мире игровых сущностей.
Удобно также осуществлять поиск какого-то класса, например поиск в сфере указанного радиуса всех Entity с именами "projectile_detonation_bomb"
Во-первых смущает отсутствие общности
ОтветитьУдалитьто LEntity *pSomeObj = CreateEntityByName( name, bShouldSpawn )
то Create( pGrenade, "projectile_grenade", GetShootPos(), GetAngles(), true )
Причем во втором случае приходится передавать ссылку на указатель, что делает невозможным любые преобразования фактического аргумента. Как следствие - придется писать отдельную ф-ю для каждого типа указателя.
Гораздо логичнее везде использовать первый вариант, он и выразительнее и намного более гибкий.
Во-вторых удивляет передача в RemoveEntity имени. Зачем это нужно? Разве указатель однозначно не идентифицирует объект?
Кстати, да, ты прав...
ОтветитьУдалитьметод Create принимает указатель на LEntity, т.е передаётся он, чтобы в последствии получить нечто вроде как и первом варианте, т.е не надо писать кучу функций... просто удобнее писать
if ( Create( pEnt, ... ), который вернёт булевый результат, и доункаст от template T чем
LGrenade* pGrenade = (LGrenade*)Create( ... );
if ( pGrenade )
{
...
}
Который вернёт LEntity
с RemoveEntity подумал, да, имя передавать лишнее.
"метод Create принимает указатель на LEntity"
ОтветитьУдалить1 Если он принимает указатель, то никакого смысла в последующем обращении через него нет. Он просто не изменится. Изменится его копия.
2 Если он принимает ссылку на указатель, то код
Create( pGrenade,...) синтаксически неверен, ибо pGrenade не является ссылкой на указатель типа LEntity. Не надейся что pGrenade автоматически приведется к LEntity, с ссылками такое не проходит...
А насчет удобства. В любом случае придется доункастить, а писать можно и не только
LGrenade* pGrenade = (LGrenade*)Create( ... );
if ( pGrenade )
можно и
if ( pGrenade = (LGrenade*)Create( ... ))
но в любом случае это лучше чем
if ( Create( pEnt, ... )) { LGrenade* pGrenade = (LGrenade*)pEnt; ... }
подскажите что значит "Завод"? и в случае создания
ОтветитьУдалитьэто кому облегчит жизнь?
Почитай про фабрики классов :)
ОтветитьУдалить