¿Cómo puedo generar terreno al estilo Worms?

48

Estoy trabajando en un juego estilo Worms y quiero generar un terreno de procedimiento. Anteriormente hice mucha generación de terreno usando ruido perlin, y esto es lo que comencé a usar para este juego. El único problema es que es demasiado simple y aburrido, lo que me da algunas colinas, pero no la complejidad que quiero. Me gustaría tener características como cuevas y montañas colgantes y no me importa las islas flotantes y demás. Algo así, pero incluso más loco estaría bien:

ingrese la descripción de la imagen aquí

Pensé en generar primero el terreno usando el ruido clásico de perlin, luego solo eliminar partes para crear cuevas y lo que no, pero tengo problemas para guiar la eliminación de esas partes. ¿Hay alguna alternativa para generar tal terreno?

Xeon06
fuente
¿El rojo representa cuevas o es solo parte del terreno?
Richard Marskell - Drackir
Es parte del terreno. Acabo de buscar esa imagen en Google, fue lo más cercano a lo que quiero lograr. La parte de la "cueva" podría ser ese pequeño agujero a la derecha, si se continuara más dentro del terreno hacia la izquierda.
Xeon06
@Drackir, editó la imagen.
Xeon06
Relacionado: gamedev.stackexchange.com/questions/6721/… (pero no es un duplicado, ya que parece centrarse en la implementación versus los algoritmos de generación).
Josh
@JoshPetrie de hecho. Estoy bien con la destrucción. Es la generación con la que tengo problemas.
Xeon06

Respuestas:

51

Te sugiero que comiences con 2D Perlin-noise. Algo como esto:

ruido perlin

Luego aplique un umbral en la imagen, de modo que obtenga varias islas aisladas, como se muestra aquí:

ruido perlin con umbral

Elegí un umbral de 0.04, todo por encima del umbral sería de color azul. El resto queda negro. Luego, después de eso, es hora de determinar qué "islas" mantener y cuáles desechar.

Un posible enfoque sería recorrer la imagen de izquierda a derecha a varias alturas y seleccionar "islas" que se cruzan dada una cierta probabilidad. En la imagen de ejemplo, la línea más baja tiene una probabilidad del 100%, por lo que se seleccionará cada isla que cruce (blanco lleno). La segunda línea tiene una probabilidad del 50% y la línea superior tiene una probabilidad del 10%.

Una vez que haya marcado sus islas de esa manera, puede cerrar las brechas intermedias aplicando una operación morfológica ( dilatar )

islas dilatadas

Y hay un posible paisaje.

La "granularidad" del ruido determinará cuán pequeños serán los detalles en su mundo. Entonces, probablemente sea mejor experimentar con estos valores.

Además, dónde y con qué probabilidades se ubican sus "líneas de selección", el resultado será muy diferente. Si tiene una línea cerca de la parte superior de la imagen con alta probabilidad de "seleccionar" una isla, entonces puede construir algún tipo de paisaje de cuevas, etc.

bummzack
fuente
¡Muchas gracias por la gran respuesta detallada e ilustrada! Esto es exactamente lo que voy a hacer.
Xeon06
¿Tendría algún consejo sobre la generación de ese ruido perlin, con este nivel de detalle y tal? Estuve intentando toda la noche y no llego a ningún lado.
Xeon06
@ Xeon06 Estaba usando la función de ruido Perlin proporcionada por flash . Los parámetros eran 24para baseXy baseY, 1 octava y elegí emitir ruido en escala de grises e inhabilité el "fractal". ¿En qué idioma estás implementando esto?
bummzack
Lo estoy implementando JavaScript. He estado buscando en la web una buena implementación que ofrezca resultados similares durante una semana, pero no puedo encontrar nada.
Xeon06
He hecho otra pregunta relacionada con la parte de ruido perlin gamedev.stackexchange.com/questions/20880/fast-noise-generation
Xeon06
6

Comenzaría con un ruido de perlin, filtrado cuidadosamente. Terminarías con algo como en la imagen adjunta a la pregunta, con islas flotantes. Juste elimina las islas flotantes luego usando un algoritmo de conteo como los discutidos aquí

Ravachol
fuente
Oh, creo que lo entiendo ahora. Necesito usar ruido perlin 2D, no 1D. ¿Podría dar más detalles sobre dicho filtrado?
Xeon06
2
No puedo publicar imágenes en este momento, pero solo estoy hablando de un filtro de umbral simple a la la if (0.3> pixelValue> 0.5) KeepIt () ;. El bit 'cuidadosamente' se trata de acertar 0.3 y 0.5. También podría tener un gradiente lineal (o no), comenzando con un alfa alto en la parte superior, llegando gradualmente a 0 en la parte inferior, por lo que tiene espacio para un cielo, y el suelo está mayormente lleno. Espero que ayude.
Ravachol
@Ravachol Si publica un enlace a una imagen, alguien con más representantes puede agregarlo a su publicación por usted.
Richard Marskell - Drackir
"if (0.3> pixelValue> 0.5)", supongo que esto es solo un error tipográfico, pero puede ser confuso tener cosas contradictorias en tu publicación ... ¿Puedes editar eso?
jcora
Parece que no puedo editar un comentario. Lea "if (0.3 <pixelValue <0.5)", obviamente.
Ravachol
4

De hecho, implementé esto a partir de la excelente respuesta de bummzack.

Estos son los pasos con los que terminé:

  1. Genera una imagen con ruido Perlin
  2. Inundación donde quieras un poco de terreno
  3. Dilatación + erosión para eliminar los huecos que son demasiado pequeños.
  4. Eliminar las regiones de fondo restantes dentro del terreno
  5. Antialiasing

Y este es un ejemplo del resultado: ejemplo de terreno generado

Escribí un artículo detallado sobre todo el proceso aquí y el código (JavaScript) es de código abierto, échale un vistazo si quieres algo listo para usar;)

Julian Go
fuente