Я работаю с несколькими друзьями над Dungeon-игрой и работаю над поиском пути. Игра основана на тайлах, и поиск пути, который мы планируем реализовать, заключается в следующем:
Класс PathMapper генерирует сетку расстояния, на котором каждая плитка от данной плитки
Класс Monster использует эту сетку для перемещения к данной плитке (прямо сейчас, всегда игрок)
Мы планируем иметь 4 игроков, но мы хотели бы, чтобы скрипт поддерживал динамическое число. У каждого игрока есть идентификатор в виде целого числа.
Для каждого игрока требуется одна сетка, сгенерированная PathMapper, и все монстры могут делиться ими (так же медленно, как генерирование сетки, делать это только один раз для игрока для всех монстров, кажется достойным решением для поиска пути).
У меня есть класс под названием «PathMapper», который генерирует сетки из плиток расстояний от начального тайла. Теоретически, 4 из них будут созданы — по одному для каждого игрока. Чтобы противник мог найти путь к игроку, он запрашивал идентификатор игрока, а затем запрашивал соответствующую сетку тайлов, которую он использовал бы для поиска пути. Сервер обновляет эти сетки с помощью «createMap (playerID, playerXPosition, playerYPosition)».
Таким образом, каждая сетка представляет собой вектор векторов, который сопоставляется с идентификатором игрока в частной карте «pathMap», значения которой монстры будут получать с помощью «getLocalPath ()»
Проблема в том, что, хотя «createMap» компилируется нормально, после попытки копирования первой стены («pathMap [ID] [x] .push_back (9000);») я получаю «EXE_BAD_ACCESS». Я должен отметить, что он проходит около дюжины итераций, прежде чем пытаться (и не может) вставить «9000». Я уверен, что dungeon-> width и dungeon-> height верны (сейчас обе равны 20; вероятно, ~ 100 для настоящая игра), и «правильность» идентификатора не должна влиять на доступ к коду, верно?
Я немного сбит с толку, потому что, по-моему, я делаю то, что резервирую пространство, перебираю его и пытаюсь получить доступ к памяти, которую я ПРОСТО зарезервировал:
reserve(20)
for(i=0; i<20; i++)
reserve(20)
for(j=0; j<20; j++)
access(i,j) // error!?
Вот код:
class PathMapper{
public:
PathMapper(Dungeon* d);
void createMap(int ID, int x, int y);
// returns values of the surrounding tiles (up, right, down, left)
std::vector<int> getLocalPath(int ID, int x, int y);
private:
Dungeon* dungeon;
std::vector< std::vector<bool> > wallBitmap;
std::map<int, std::vector< std::vector<int> > > pathMap;
}
PathMapper::PathMapper(Dungeon* d) {
dungeon = d;
wallBitmap = dungeon->getWalls(); // bools tell if there is a wall on a tile
}
void PathMapper::createMap(int ID, int x, int y) {
pathMap[ID].reserve(dungeon->width());
for(int x=0; x<dungeon->width(); x++) {
pathMap[ID][x] = std::vector<int>();
pathMap[ID][x].reserve(dungeon->height());
for(int y=0; y<dungeon->height(); y++) {
if(wallBitmap[x][y]) {
pathMap[ID][x].push_back(9000); // error is here
}
else {
pathMap[ID][x][y] = -1;
}
}
}
// code to calculate values here; shouldn't affect the code above
}
резерв не меняется размер вектора (только емкость), нужно изменить размер.
Или
использование resize
:
pathMap[ID].resize(dungeon->width());
...
pathMap[ID][x] = std::vector<int>();
pathMap[ID][x].resize(dungeon->height());
или передайте размер прямо в конструкторе:
pathMap[ID].resize(dungeon->width());
...
pathMap[ID][x] = std::vector<int>(dungeon->height());