Я использую зубчатый массив для хранения сегментов карты (кластеров) в игре, которую я создаю. Положение в массиве соответствует положению кластера на карте. Кроме того, если внутренний массив (зубчатая часть) больше не имеет загруженных в него кластеров (кластеры удаляются из массива по истечении неиспользованного тайм-аута), этот элемент внешнего массива возвращается в нулевое значение, чтобы сохранить использование памяти картой. вниз.
Проблема возникает случайно, когда игра пытается получить кластер с карты:
public Cluster getCluster(int xIndex, int yIndex)
{
lock (xAxis)
{
loadCluster(xIndex, yIndex);
return xAxis[xIndex][yIndex];
}
}
public void loadCluster(int xIndex, int yIndex)
{
lock (xAxis)
{
if (xAxis[xIndex] == null)
xAxis[xIndex] = new Cluster[(int)worldSize.Y];
if (xAxis[xIndex][yIndex] == null)
xAxis[xIndex][yIndex] = new Cluster(this, new Vector2(xIndex * 256, yIndex * 256), worldLoader.loadClusterData(xIndex, yIndex));
}
}
Метод loadCluster(int, int)
должен гарантировать, что кластер загружен в массив до того, как метод getCluster(int, int)
извлечет его, и почти всегда это происходит, но иногда loadCluster(int, int)
каким-то образом не удается добавить кластер.
Кажется, что этого не происходит с каким-либо конкретным кластером, но всегда происходит, когда внутренний массив не был добавлен (однако большую часть времени он создает внутренние массивы без каких-либо проблем). Кроме того, когда Visual Studio перехватывает следующее исключение нулевого указателя, возврат и повторный вызов loadCluster(int, int)
всегда (по крайней мере, пока) работает как обычно. Добавление дополнительных вызовов loadCluster(int, int)
в метод getCluster(int, int)
также значительно снижает частоту появления этой ошибки.
Честно говоря, я понятия не имею, что заставляет эту довольно простую функцию не работать, даже, казалось бы, случайно. Любая помощь приветствуется
РЕДАКТИРОВАТЬ: Другой код, редактирующий xAxis [] []
public override void Update(GameTime gameTime)
{
for (int x = 0; x < worldSize.X; x++)
{
if (xAxis[x] == null) continue;
int loaded = 0;
for (int y = 0; y < worldSize.Y; y++)
{
if (xAxis[x][y] == null)
{
continue;
}
xAxis[x][y].Update(gameTime);
if (xAxis[x][y].clusterLoaded)
{
loaded++;
}
else if (xAxis[x][y].clusterTimer == 0)
{
xAxis[x][y] = null;
}
}
if(loaded == 0) xAxis[x] = null;
}
}
Cluster.clusterLoaded
- логическое значение, показывающее, используется ли кластер в данный момент. Cluster.clusterTimer
- это целое число, которое ведет обратный отсчет, когда clusterLoaded
становится ложным. Он сбрасывается, если на максимальное значение, если clusterLoaded
снова становится истинным. Он уменьшается на 1 каждый раз, когда Cluster.Update(GameTime)
выполняется, когда clusterLoaded
ложно. loaded
используется для подсчета количества загруженных кластеров в текущем внутреннем массиве.