Aumentando a probabilidade de blocos semelhantes gerarem um ao lado do outro


9

Estou trabalhando em um sistema de mapa de peças, que se parece com isso (verde é grama, ar é branco, pedra é cinza e azul é água):

Azulejos

Ele usa um gerador de números aleatórios simples para que haja 45% de chance do azulejo ser grama, 30% de água e 25% de pedra.

Existe alguma maneira de aumentar a tendência de blocos de grama / pedra se agruparem para formar massas de terra e fazer blocos de água formar oceanos (mais ou menos como o que poderia ser visto em um jogo como o Minecraft)?

Respostas:


17

Você poderia usar um algoritmo que verifica perto de blocos e varia a probabilidade dependendo do que existe - mas acho que é em grande parte a abordagem errada.

O que você deseja observar são os tipos de ruído fractal - nesse caso, ruído perlin ou simplex. Se você gerar ruído, obterá valores de -1 a 1.

http://en.wikipedia.org/wiki/Perlin_noise

Em seguida, você pode ajustar o nível da água definindo o limiar do que faz a água. Para os outros blocos, você pode executar um segundo conjunto de ruído para alternar entre rochas e grama. (dessa forma, você pode ter grandes manchas de água, mas pequenos pedaços de pedra).

getTerrain(x,y) {
if(perlin_noise(x,y) > 0) {
    if(perlin_noise(x * scale,y * scale) > 0) {
        return rock
    } else {
        return dirt
    }
} else {
    return water
}

Como acho que o método de varredura e arremesso é excessivamente complicado e não muito robusto e escalonável, vou sugerir outro método que gostei:

Coloque uma grade em seu mapa, dividindo o mapa em quadrados grandes.

Gere um número aleatório em cada interseção (entre 0 e 1 funcionará para suas porcentagens)

Subdivida cortando cada quadrado em 4 quadrados pares - siga as linhas antigas e, onde você encontrar as linhas de subdivisão, gere um número aleatório entre os 2 pontos adjacentes, da mesma forma que para o centro da cruz, gere um ponto que fique entre os mais altos e valores mais baixos.

Enxague e repita. Você obterá a aleatoriedade inicial no primeiro passe, mas os últimos passes darão alguma uniformidade. Desculpe pelos números psuedo-random:

0-------5  0---3---5 0-1-3-4-5 011233455
|       |  |   |   | | | | | | 012344555
|       |  |   |   | 0-2-4-6-5 002445665
|       |  |   |   | | | | | | 123445666
|       |  2---5---7 2-4-5-7-7 234455777
|       |  |   |   | | | | | | 233455688
|       |  |   |   | 2-3-5-5-9 223455589
|       |  |   |   | | | | | | 233455589
2-------9  2---4---9 2-4-4-5-9 234445579

Isso funciona ainda melhor para triângulos, porque você não tem a barra cruzada perdida ao subdividir.

Obviamente, o melhor resultado absoluto virá da combinação desses métodos - camada após camada, algumas técnicas fornecerão grandes massas terrestres, outras darão impressionantes cavernas, outras funcionarão em colinas e outras funcionarão em sistemas de água.


+1 Como eu acho que o salto para o ruído geralmente é o que isso levará. Eu estou imaginando se isso pode ser um salto muito grande, então a inicial 'escanear e alterar as porcentagens' me facilitou a votação :)
James

3

O ruído é uma boa solução, como já foi mencionado. Outra opção é fazer uma segunda passagem nos dados para movê-los para o layout desejado. O Gaussian Blur é uma das muitas maneiras pelas quais você pode conseguir isso. Fazer um passe com isso deve gerar blobs "redondos" de cada tipo.

Não importa qual método você use, porém, uma coisa importante a ter em mente é armazenar os resultados do processo em um novo local. Se você modificar o mapa, as partes que você já processou começarão a afetar o algoritmo e você terá alguns padrões estranhos.


2

Uma maneira relativamente simples de fazer isso seria criar um número de núcleos em posições aleatórias. Desenhe o diagrama Voronoi desses pontos. Atribua um elemento a cada região do resultado.

Isso resulta em algo bastante feio e mecânico. Enlamear um pouco as fronteiras e você estará em boa forma.

Se você estiver gerando um mapa grande, poderá fazer isso em dois níveis. Crie seu diagrama inicial de Voronoi usando, digamos, 20 núcleos e chame cada região resultante de nação. Crie outro diagrama usando 400 núcleos e chame cada região resultante de vicaria.

Todos os vicariatos totalmente contidos em uma nação terão o elemento da nação. As vicarias parcialmente contidas em duas ou mais nações tomarão aleatoriamente um dos elementos de suas nações anexas.

Este post merece uma foto, mas estou com preguiça de fornecer uma.


2

O Polygonal Map Generator seria uma boa leitura para criar mapas com diferentes 'zonas', o que também proporcionaria mapas melhor formados. É baseado em diagramas de voronoi, mas acho que seria um bom começo para isso.


0

você pode fazer isso usando este método:

  • coloque todos os blocos na lista não especificada
  • enquanto houver um bloco na lista não especificada
  • início
  • escolha um bloco dessa lista
  • verifique os vizinhos desse bloco e selecione um tipo, dependendo dos vizinhos
  • remova esse bloco da lista não especificada
  • fim
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.