Você pode usar as funções de ruído para gerar alturas aleatórias. O mais simples deles é o ruído de valor, que funciona exatamente como a sua descrição: você gera algumas alturas inteiras aleatórias e depois interpola as alturas entre elas. O método de interpolação mais frequentemente usado é o mapeamento cúbico da curva S:
Suponha que você tenha altura h0
no ponto x0
e altura h1
no ponto x1
. Para obter a altura em qualquer ponto x
( x0<=x<=x1
), use
t = (x-x0)/(x1-x0); // map to [0,1] range
t = t*t*(3 - 2*t); // map to cubic S-shaped curve
h = h0+t*h1;
As alturas obtidas dessa maneira serão suaves, aleatórias, mas não realmente interessantes. Para melhorar seu terreno, você pode usar ruído fractal . Funciona assim: suponha que você tenha gerado uma função h(x)
que retorna a altura em uma determinada coordenada (usando o método acima). Esta função possui uma frequência, determinada pela frequência das alturas originais do intergerador. Para criar um fractal, você combina funções com várias frequências:
fbm(x)=h(x) + 0.5*h(2*x) + 0.25*h(4*x) + 0.125*h(8*x);
Neste exemplo, eu combino quatro frequências - original, dupla, 4 vezes e 8 vezes original, com frequências mais altas com menos peso. Teoricamente, os fractais vão até o infinito, mas na prática apenas alguns termos são necessários. O fbm
na fórmula significa movimento browniano fracionário - este é o nome dessa função.
Esta é uma técnica poderosa. Você pode tocar com multiplicador de frequência, com pesos de frequências diferentes ou adicionar algumas funções para distorcer o ruído. Por exemplo, para obter uma sensação mais "estriada", h(x)
pode ser alterado para 1-abs(h(x))
(supondo -1<=h(x)<=1
)
No entanto, enquanto tudo isso é bom, essa técnica tem uma limitação séria. Com uma abordagem baseada na "altura da linha", você nunca pode ter "saliências" no terreno. E eu imagino que eles sejam um recurso muito bom para ter em um jogo parecido com o "Moon Buggy".
Adicionar saliências agradáveis é uma tarefa difícil. Uma coisa em que consigo pensar - você pode começar com uma "linha de altura" fractal e "separá-la" em uma série de splines ou curvas mais escuras. Então a linha do terreno será definida por vários "pontos-chave". Aplique alguma instabilidade a esses pontos-chave - isso resultará em deformação aleatória do terreno, provavelmente formando algumas formas interessantes. No entanto, auto-interseções de terreno podem se tornar um problema com essa abordagem, especialmente com grandes quantidades de tremulação.
Minha idéia seria criar uma função de ruído suavizado. Primeiro com um método intNoise (int) que retorna um int "aleatório", mas que depende da entrada. Se você usar a mesma entrada duas vezes, o resultado será o mesmo.
Em seguida, use um método de suavização para criar um floatNoise (float) que usa os dois números inteiros ao redor da entrada para criar um valor aleatório.
Em seguida, use a posição X como entrada e Y como saída. O resultado será uma curva suavizada, mas com altura aleatória.
fonte