Sortowanie obiektów do renderowania - czyli sortowanie względem typu i pozycji y
Ostatnio zmodyfikowano dzisiaj: 4h » 26 min
tBane Temat założony przez niniejszego użytkownika |
Sortowanie obiektów do renderowania - czyli sortowanie względem typu i pozycji y » 2026-09-03 22:00:41 Cześć. Mam różne obiekty do renderowania. Chciałbym je posortować względem typu,a potem względem pozycji y. Czy optymalnie napisałem sortowanie względem typu? void GameObjectsOnMap::sort() { std::vector < ObjectType > types = { ObjectType::BuildingSkeleton, ObjectType::WallMounted, ObjectType::Window, ObjectType::Door, ObjectType::Roof, }; auto getIndex =[ & types ]( ObjectType type )->int { auto it = std::find( types.begin(), types.end(), type ); if( it != types.end() ) return it - types.begin(); return - 1; }; std::sort( _visibleGameObjectsOnMap.begin(), _visibleGameObjectsOnMap.end(),[ & types, getIndex ]( const std::shared_ptr < GameObjectOnMap > & a, const std::shared_ptr < GameObjectOnMap > & b ) { int aIndex = getIndex( a->_type ); int bIndex = getIndex( b->_type ); if( aIndex < bIndex ) return true; if( aIndex > bIndex ) return false; sf::Vector2i posA = a->_position; if( a->_prefab.lock()->_collider->_type == ColliderType::Rectangular ) { std::shared_ptr < RectangularCollider > collider = std::dynamic_pointer_cast < RectangularCollider >( a->_prefab.lock()->getCollider() ); posA += collider->_rect.position + collider->_rect.size / 2; } else if( !dynamic_pointer_cast < MonsterPrefab >( a->_prefab.lock() ) ) { posA += a->_prefab.lock()->getOrigin(); } sf::Vector2i posB = b->_position; if( b->_prefab.lock()->_collider->_type == ColliderType::Rectangular ) { std::shared_ptr < RectangularCollider > collider = std::dynamic_pointer_cast < RectangularCollider >( b->_prefab.lock()->getCollider() ); posB += collider->_rect.position + collider->_rect.size / 2; } else if( !dynamic_pointer_cast < MonsterPrefab >( b->_prefab.lock() ) ) { posB += b->_prefab.lock()->getOrigin(); } if( posA.y == posB.y ) return posA.x < posB.x; return posA.y < posB.y; } ); }
|
|
DejaVu |
» 2026-09-03 22:45:55 Sortowanie wygląda sensownie tj. najpierw ify na index true/false jak masz, a potem druga część. Natomiast na Twoim miejscu lockowałbym cały kontener z obiektami (o ile tak masz kod zorganizowany), bo robić 2*N*log(N) locków jest bardzo nieefektywne i niewydajne. |
|
tBane Temat założony przez niniejszego użytkownika |
» 2026-09-03 22:49:13 W sensie utworzyć listę obiektów z użyciem object.lock() i dopiero na niej wykonywać operacje? |
|
DejaVu |
» 2026-09-03 22:54:06 Generalnie chodzi o to, że jeżeli tworzysz wielowątkową grę, to powinieneś mieć listę obiektów, którą lockujesz, wykonujesz operacje na całej liście i zdejmujesz locka. Lockowanie pojedynczych obiektów jest nieefektywne. Chyba, że to są lockiczegoś innego (nie widzę czym jest _prefab). W każdym razie dążyłbym też do upraszczania kodu tak, aby unikać dynamic_pointer_cast. Czyli: auto typeA = a->getType(); auto typeB = b->getType(); if( typeA < typeB ) return true;
if( typeA > typeB ) return false;
auto positionAY = a->getPosition().y; auto positionBY = b->getPosition().y; if( positionAY < positionBY ) return true;
if( positionAY > positionBY ) return false;
return false; Innymi słowy: metoda ma zwrócić Ci przygotowaną cząstkową informację, aby złożoność sortowania była prosta do implementacji. |
|
tBane Temat założony przez niniejszego użytkownika |
» 2026-09-03 23:06:33 Dobra. Dynamic pointery cast da się zastąpić porównaniem typu. |
|
| « 1 » |