Проблема:
Когда основной генератор требует, чтобы плитки нашли своих соседей, я получаю исключение нулевой ссылки. в строке nextArray[0] = world.GetNodeOrNull(nameNW);
Странная вещь:
Это происходит только с узлами первого столбца
Нет проблем, если КАЖДАЯ плитка в GiveBiomeType задан биом Лес или Пустыня, но присвоение остаткам типа биома None только останавливает ошибку, возникающую в первых нескольких итерациях.
Что я делаю:
Я экспериментирую с базовый объектно-ориентированный генератор мира. Главный генератор создает сетку «плиток», создает их экземпляры, присваивает заданному количеству из них биом (перечисление) и вызывает в них функцию, чтобы найти их соседей и «распространить» их тип биома.
Я думал, что проблема в get_node_or_null, и попробовал has_node, но цикл for в нижней части функции поиска соседей доказывает, что это не так.
Я подозревал, что массив создается случайным образом. удалено, но использование списка ничего не меняет.
Вот основной фрагмент основного генератора:
Код: Выделить всё
IEnumerator GenerateNew()
{
// foreach (Node2D t in tilesArray)
// {
// if(t != null){t.QueueFree();}
// }
yield return Timing.WaitForSeconds(0.5);
GD.Print("-Gen: Starting gen");
yield return Timing.WaitUntilDone(Timing.RunCoroutine(InitialiseGrid().CancelWith(this)));
GD.Print("Gen: Tiles placed, giving biome types");
yield return Timing.WaitUntilDone(Timing.RunCoroutine(GiveBiomeTypes().CancelWith(this)));
GD.Print("Gen: Biomes given, call find neighbours ");
yield return Timing.WaitUntilDone(Timing.RunCoroutine(CallFindNeighbours().CancelWith(this)));
GD.Print("Neighburs should be found, start spread");
yield return Timing.WaitUntilDone(Timing.RunCoroutine(CallBiomeSpread().CancelWith(this)));
GD.Print("Gen: ");
// TEMP
yield return Timing.WaitForSeconds(0.2f);
GD.Print("Gen: Generating finished");
// DEBUGPrintTileArray();
}
IEnumerator InitialiseGrid()
{
int arrayIndex = -1;
for(int x = 0; x < numOfTiles; x++)
{
for(int y = 0; y < numOfTiles; y++)
{
arrayIndex++;
var newTile = tile.Instantiate();
AddChild(newTile);
var t = newTile as Node2D;
t.Position = new Vector2(x * sizeOfTiles, y * sizeOfTiles);
//Naming
string one = x.ToString();
string two = y.ToString();
t.Name = one + "-" + two;
tilesArray[arrayIndex] = t;
}
}
yield return Timing.WaitForSeconds(0.001f); // Appease coroutine
}
IEnumerator GiveBiomeTypes()
{
if(numOfForest > 0)
{
for(int f = 0; f < numOfForest; f++)
{
int rf = GD.RandRange(0,tilesArray.Length -1);
var sf = tilesArray[rf] as TestTile;
if(sf.biomeType == BiomeType.None)
{
sf.biomeType = BiomeType.Forest;
sf.world = this;
// temp
// GD.Print("Gen: Biome given to " + sf.Name);
// sf.FindNeighbours();
}
else
{
f--;
}
}
}
else {GD.Print("Gen: Number of forest is 0");}
if(numOfDesert > 0)
{
for(int d = 0; d < numOfDesert; d++)
{
int rd = GD.RandRange(0,tilesArray.Length -1);
var sd = tilesArray[rd] as TestTile;
if(sd.biomeType == BiomeType.None)
{
sd.biomeType = BiomeType.Forest;
sd.world = this;
// temp
// GD.Print("Gen: Biome given to " + sd.Name);
}
else
{
d--;
}
}
}
else {GD.Print("Gen: Number of deserts is 0");}
int leftOvers = (numOfTiles * numOfTiles) - (numOfForest + numOfDesert);
if(leftOvers > 0)
{
for(int lo = 0; lo < leftOvers; lo++)
{
int rlo = GD.RandRange(0,tilesArray.Length -1);
var slo = tilesArray[rlo] as TestTile;
if(slo.biomeType == BiomeType.None)
{
slo.biomeType = BiomeType.None;
slo.world = this;
// temp
// GD.Print("Gen: Biome given to " + sd.Name);
}
else
{
lo--;
}
}
}
yield return Timing.WaitForSeconds(0.001f); // Appease coroutine
}
IEnumerator CallFindNeighbours()
{
foreach(Node2D t in tilesArray)
{
GD.Print("\n Tiles array tile : " + t.Name);
var ts = t as TestTile;
ts.FindNeighbours();
}
yield return Timing.WaitForSeconds(0.001f); // Appease coroutine
}А вот проблемная функция, вызываемая на наших экземплярах плиток:
А вот проблемная функция, вызываемая на наших экземплярах плиток:
А вот проблемная функция, вызываемая на наших экземплярах плиток:
А вот проблемная функция, вызываемая на наших экземплярах плиток: p>
Код: Выделить всё
public void FindNeighbours()
{
GD.Print("Tile " + Name + " with type " + biomeType + " finding neighbours: ");
string name = Name;
int x = name[0] - '0';
int y = name[2] - '0';
// GD.Print("\n Name broken up is : " + x + " and " + y + "\n");
int w = x-1;
int e = x+1;
int n = y-1;
int s = y+1;
string nameNW = w + "-" + n;
string nameN = x + "-" + n;
string nameNE = e + "-" + n;
neighbourArray[0] = world.GetNodeOrNull(nameNW); //Should not matter if its null
neighbourArray[1] = world.GetNodeOrNull(nameN);
neighbourArray[2] = world.GetNodeOrNull(nameNE);
string nameW = w +"-" + y;
string nameE = e + "-" + y;
neighbourArray[3] = world.GetNodeOrNull(nameW);
neighbourArray[4] = world.GetNodeOrNull(nameE);
string nameSW = w + "-" + s;
string nameS = x + "-" + s;
string nameSE = e + "-" + s;
neighbourArray[5] = world.GetNodeOrNull(nameSW);
neighbourArray[6] = world.GetNodeOrNull(nameS);
neighbourArray[7] = world.GetNodeOrNull(nameSE);
// When sum of numOfForst + numOfDesert == total tiles, everything works fine. This loop shows that
for(int i = 0; i < neighbourArray.Length -1; i++)
{
if(neighbourArray[i] != null)
{
GD.Print(neighbourArray[i].Name);
}
else
{
GD.Print("Found null node");
}
}
}Я в растерянности. Любые идеи приветствуются
Подробнее здесь: https://stackoverflow.com/questions/792 ... -3-c-sharp
Мобильная версия