Я пытаюсь случайным образом генерировать блоки на плоской карте и делать это так, чтобы они не перекрывали друг друга. Я сделал матрицу (массив C#) размера карты (500x500), блоки имеют шкалу от 1 до 5. Код работает, но если сгенерированный блок перекрывает другой, он уничтожается и не регенерируется где-то остальное.Произвольное создание блоков на плоской карте
Только около 80 из 1000 блоков, которые я пытаюсь сгенерировать, не перекрывают другой блок.
Вот изображение карты с около 80 блоков генерируется, зеленые квадраты блоки
void generateElement(int ratio, int minScale, int maxScale, GameObject g) {
bool elementFound = false;
for (int i = 0; i < ratio * generationDefault; i++) {
GameObject el;
// Randomly generate block size and position
int size = Random.Range(minScale, maxScale + 1);
int x = Random.Range(0, mapSizex + 1 - size);
int y = Random.Range(0, mapSizey + 1 - size);
// Check if there is already an element
for (int j = x; j < x + size; j++)
for (int k = y; k < y + size; k++)
if (map[j][k] != null)
elementFound = true;
if (elementFound)
continue;
else {
el = (GameObject)Instantiate(g, new Vector3(x + (float)size/2, (float)size/2, y + (float)size/2), Quaternion.Euler(0, 0, 0));
el.transform.localScale *= size;
}
// Create element on map array
for (int j = x; j < x + size; j++)
for (int k = y; k < y + size; k++)
if (map[j][k] == null) {
map[j][k] = el.GetComponent<ObjectInterface>();
}
}
}
я думал, 3 возможных исправлений
- I следует установить размер блока в зависимости от места, которое он имеет.
- Я должен использовать другой алгоритм рандомизации.
- Я не делаю это правильно.
Как вы думаете, а лучше всего?
UPDATE
Я получил код работает гораздо лучше. Теперь я пытаюсь создать несколько блоков при необходимости (максимум 5 на данный момент), и я исправил ошибки. Если на карте уже много элементов, они не всегда будут созданы, и это то, что я хотел, я просто должен найти нужное количество раз, чтобы попытаться создать экземпляр блока.
Я попытался создать 1280 элементов на карте 500x500. Он занимает всего около 1,5 секунд, и он создавал 1278/1280 блоков (99,843%).
void generateElement(int ratio, int minScale, int maxScale, GameObject g) {
bool elementFound = false;
int cnt = 0;
// Generate every block
for (int i = 0; i < ratio * generationDefault; i++) {
GameObject el = null;
// Randomly generate block size and position
int size, x, y, tryCnt = 0;
// Try maximum 5 times to generate the block
do {
elementFound = false;
// Randomly set block size and position
size = Random.Range(minScale, maxScale + 1);
x = Random.Range(0, mapSizex + 1 - size);
y = Random.Range(0, mapSizey + 1 - size);
// Check if there is already an element
for (int j = x; j < x + size; j++)
for (int k = y; k < y + size; k++)
if (map[j][k] != null)
elementFound = true;
tryCnt++;
} while (elementFound && tryCnt < 5);
if (tryCnt >= 5 && elementFound) continue;
// Instantiate the block
el = (GameObject)Instantiate(g, new Vector3(x + (float)size/2, (float)size/2, y + (float)size/2), Quaternion.Euler(0, 0, 0));
el.transform.localScale *= size;
// Create element on map array
for (int j = x; j < x + size; j++)
for (int k = y; k < y + size; k++)
if (map[j][k] == null) {
map[j][k] = el.GetComponent<ObjectInterface>();
}
cnt++;
}
print("Instantiated " + cnt + "/" + ratio * generationDefault);
}
Один из способов я могу думать для этого (хотя бы потребовать дополнительную математики), это разделить область карты в сетку регионов, равно количество блоков, которые вы хотите отложить. Затем произвольно выберите позицию в каждой области (с учетом ожидаемой шкалы блока) и поместите туда блок. К сожалению, вы также столкнетесь с проблемой «регулярности» с этим подходом (особенно, когда число блоков увеличивается относительно размера карты) ... в зависимости от ваших потребностей, однако, средняя плотность населения не так уж плоха. = P – Serlite
Hi Serlite. Это очень известный подход. В самом деле, это то, что в моем ответе ниже. Как вы точно наблюдаете, вы получаете «регулярный взгляд» в зависимости от размеров (иногда это прекрасно). Простое решение - нарушить приведенный ниже код блоков. Заметка! Действительно, другой подход - это просто ... просто выкладывайте все равномерно (даже не рандомизируйте позиции), а затем возмущайтесь. Просто попробуйте с 1, 2, 3 или более «пертурбами» и посмотрите, как это происходит. – Fattie