2013-09-16 4 views
1

Я чувствую, что это очень простой, почти глупый вопрос. Я просто забыл, что я должен знать, как это сделать.Какой тип контейнера следует использовать для хранения целого числа ObjectID?

У меня есть GameObjects, которые хранятся в универсальном GameObjectManager. Эти GameObjects имеют ObjectID, который является простым int.

Мне нужно уметь вставлять или удалять эти GameObjects в мире с 2D-плиткой, где каждая ПЛИТКА содержит контейнер ObjectID.

Таким образом, я могу захватить конкретную плитку (например, плитка [10] [10]), а затем посмотреть, какие объекты GameObject находятся на Tile [10] [10], прочитав из контейнера. (например, «Ах, поэтому персонаж № 4302 и № 123 находятся на плитке [10] [10]!»)

Прямо сейчас, каждая «Плитка» представляет собой структуру в массиве MAP из Плитки.

struct MapTile 
{ 
    std::vector <int> GameObject_MapList ; //list of Objects on this map location 
    TileTerrainType tileTerrainType; //GFX to display Grass, Sand, Water, Swamp, etc. 
}; 

MapTile mlMap[100][100]; //map array 

Однако, я читал, что векторы не должны использоваться при произвольном добавлении/удалении переменных. Это не похоже на то, что я удалю первую или последнюю переменную в массиве. Вместо этого мне придется вызвать определенный ObjectID и удалить его из любого места в массиве.

По этой причине я думал об использовании другого контейнера. Возможно, я просто слишком устал, но я мог бы использовать некоторые советы о том, какой контейнер использовать, и как перейти к удалению SPECIFIC переменных в контейнере.

Например, GameObject имеет ObjectID "422". Плитка [2] [8] содержит контейнер, который имеет следующие целые числа по порядку: 420, 421, 422, 433, 486, 800.

У меня есть функция: RemoveGameObjectFromMap (int ObjectID); Поэтому мне нужно, чтобы удалить 422, всякий раз, когда я печатаю (RemoveGameObjectFromMap (422).

Я имел обыкновение использовать контейнер карты, но это не является необходимым Vector, согласно cplusplus.com было бы плохо для этого

.
+0

Возможно, я смущен, потому что я неправильно обрабатываю свои классы. Чем больше я думаю об этом, тем больше я понимаю, что я должен, вероятно, позволить классу MAP получить полный доступ к GameObjectManager класса WORLD. Я делаю это только потому, что мой прежний способ справиться с этим (MAP, который содержал фактические игровые объекты), состоит в том, что TILES больше не удерживают фактические GameObjects, а вместо этого просто удерживают их int ObjectID. – Carter81

+1

Является ли вектор хорошим или плохим, зависит от ряда факторов. Как и количество идентификаторов на каждый фрагмент (в среднем), насколько часто вставляются, удаляются и ищутся, сколько нужно для минимизации использования памяти и 100 других соображений. Короче говоря, простых ответов нет.Очевидная альтернатива std :: vector в этом случае будет std :: unordered_set (я предполагаю, что вы никогда не хотите, чтобы один и тот же идентификатор в одной и той же плитке более одного раза). – john

+0

Вставки и удаления являются постоянными. В любое время, когда игрок немного перемещается, они будут удалены и вставлены в новый MapTile. – Carter81

ответ

0

Является ли вектор хорошим или плохим, зависит от ряда факторов. Как и количество идентификаторов на каждый фрагмент (в среднем), как часто вставляются, удаляются и ищутся, сколько нужно, чтобы минимизировать использование памяти, и 100 других Короче говоря, простых ответов нет. Очевидной альтернативой std::vector в этом случае будет std::unordered_set (я предполагаю, что вы никогда не захотите, чтобы один и тот же идентификатор в одной и той же плите был более одного раза).

0

Если вы собираетесь хранить около 10-20 элементов - используйте вектор. Особенно для элементов POD. Я не уверен в std::unordered_set, но карта даст вам много распределений памяти, которые поглотят любое ускорение скорости от быстрой вставки и стирания. Чтобы ускорить поиск, вы можете сортировать вектор и использовать некоторый бинарный поиск (lower_boundupper_boundequal_range).

+0

Что делает дополнительное выделение памяти (потерянная память) в зависимости от скорости при выполнении функций вставки/стирания? Потребление памяти и скорость обработки не связаны так, не так ли? Я думал, что для этого были созданы Карты. Вы говорите, что сортировка вектора и использование бинарного поиска превосходят карту, несмотря на то, что карта сделана именно по этой причине? С веб-сайта Cplusplus: «Карты обычно реализуются как двоичные деревья поиска». Возможно, я слишком новичок, чтобы понять, что вы говорите? Если карта настолько ужасна в своих силах, почему она существует? – Carter81

+0

@ Carter81: Кэш - это ответ. Все, что я сказал, подходит для дела 10-20 элементов. Карта и список превосходят большие размеры, но предметы могут быть разбросаны по всей памяти. На небольших ценах на копирование мало, и преимущества от кеш-бэка великолепны. Поэтому, если ваш контейнер будет небольшим - используйте вектор. –

Смежные вопросы