Implementando un paisaje destructible en 2D (como Worms)

76

¿Qué pasos estarían involucrados en la construcción de un paisaje 2D destructible, como en Worms? Idealmente, ¿cuáles son algunas formas en que este proceso podría hacerse lo más eficiente posible?

William Casarin
fuente
77
Excelente pregunta Worms tiene dos desafíos: la capacidad de destrucción y también el movimiento en ángulos extraños.
cenizas999
Creo que esto se ha preguntado aquí varias veces
Vishnu
2
Vish, los enlaces relacionados no parecen sugerir eso.
El pato comunista
3
Podrías comprobar cómo se hace en Hedgewars : es un clon de gusanos de código abierto.
GvS
No es suficiente para una respuesta, pero es posible que también desee consultar Clonk . Es un juego 2D más antiguo de un desarrollador alemán que también tenía un paisaje destructible, hasta píxeles específicos. Ya no está en desarrollo, pero el código fuente está disponible en el enlace de arriba. También está el sucesor de código abierto OpenClonk, pero de los videos parece haberse alejado de la destrucción perfecta de píxeles y ha dado un giro en la dirección de Terraria con un tipo de bloques que pueden destruirse.
Christian

Respuestas:

47

No sé cómo se implementó exactamente el paisaje en gusanos, pero estoy bastante seguro de que usaron un mapa de bits para el paisaje (al menos en los juegos más antiguos de la serie).

Un enfoque muy básico sería una imagen de mapa de bits (B / N) donde los píxeles negros representan el aire y los píxeles blancos representan el suelo . La destrucción del paisaje se puede hacer fácilmente usando operaciones de píxeles. Entonces, si un cohete golpea el suelo, pinta un círculo negro radius = blastRadiusen el punto de impacto.

Luego puede renderizar su mundo (o solo una parte de él) utilizando ese mapa de bits. Para un mejor rendimiento, le sugiero que lo implemente de una manera que pueda actualizar / representar solo una parte del "mundo". P.ej. Si algunas partes del paisaje son destruidas por un cohete, simplemente vuelva a renderizar las áreas afectadas, no el mundo entero.

En lugar de una imagen en B / N como su "mapa de colisión", también podría usar una imagen de 24 bits donde use dos canales para almacenar la superficie normal (x, y) por píxel y un canal para almacenar la "colisión" real mapa". Tener la superficie normal a mano te ayudará enormemente a calcular las granadas que rebotan o a determinar si un personaje puede moverse en una dirección determinada.

bummzack
fuente
3
Almacenar información adicional es el mapa de colisión es una idea hermosa.
deft_code el
6

Una posibilidad fuera de mi cabeza:

Utilice una representación de ruta de gráficos vectoriales para almacenar el contorno de la "tierra" destructible. Cuando ocurre un evento de destrucción (por ejemplo, una granada se dispara), el área de la explosión, representada como un círculo, se eliminaría del camino de tierra a través de una operación de resta booleana. El camino resultante representa la nueva "tierra" para la detección de colisión en el suelo, y posiblemente también una máscara para dibujar la tierra.

Phillip Parker
fuente
2
Creo que así es como lo hace Hedgewars. @Bill, puedes echarle un vistazo, ya que es de código abierto.
Gastón
2
@ Gastón Los mapas en Hedgewars son todas imágenes (PNG). Dudo que se estén convirtiendo en gráficos vectoriales. Además: el uso de gráficos vectoriales (splines, bezier, etc.) es mucho más pesado de la CPU para cosas como la detección de colisiones o la sustracción de formas. Sin embargo, mirar la fuente es una buena idea (aunque el estilo de codificación es bastante malo :))
bummzack
44
La geometría computacional como esta puede ser MUY complicada, ¡MUY rápida!
Adam Harte
Buscar en Google "terreno destructible box2d" ahora ofrece algunas demostraciones vectoriales ejecutables.
Ciro Santilli 新疆 改造 中心 法轮功 六四 事件
6

Usa geometría sólida constructiva

Escribí una prueba de concepto que usaba geometría sólida constructiva para manejar terrenos destructibles. Utilicé el Tessellator GLU para realizar las operaciones booleanas. La documentación explica cómo, busque "CSG Uses for Winding Rules" .

Introduje la salida triangular del teselador como polígonos estáticos en Box2D. El PoC funcionó bastante bien. Pude restar arbitrariamente y agregar terreno en tiempo real y el terreno continuó comportándose adecuadamente con Box2D. El único inconveniente real fue que el teselador GLU puede producir triángulos degenerados que a Box2D no le gustan, así que tuve que filtrarlos a mano.

El siguiente paso en el PoC (al que nunca llegué) fue usar el algoritmo SCC de la biblioteca de gráficos de impulso para detectar cuándo una porción del terreno se había cortado (cortar la cima de una montaña). El terreno cortado aún sería destructible, pero ahora está representado por un cuerpo Box2D dinámico (no estático) con los triángulos unidos como formas. Tuve el diseño resuelto pero perdí interés una vez que comencé a investigar la documentación de impulso. I "plan de" volver a examinar la idea cuando hago una tierra quemada / Worms juego algún día.

código_deft
fuente
5

Todas las respuestas anteriores hablan sobre la implementación del caso más simple, como en los gusanos. Es decir, cuando se destruye el área de impacto y todo lo demás queda intacto. ¿Consideró que su paisaje puede dividirse en dos? Digamos que hay una montaña y los jugadores cortan el fondo con un lanzacohetes. Ahora, ¿no debería caer la montaña? Además, sería natural que un paisaje sea un poco elástico. En la época de los gusanos (al menos como los recuerdo, no jugué gusanos durante, como, muchos años) las computadoras no eran lo suficientemente fuertes como para hacerlo bien. Pero lo son ahora.

Por supuesto, depende totalmente de las ambiciones de su proyecto. Pero si quieres que sea realmente increíble, tal vez deberías probar Box2D como motor de física. Hay mucho que puedes hacer con él.

Septagrama
fuente
3
En los gusanos, puedes cavar un hoyo a través del paisaje usando una antorcha. No sería tan divertido si ese túnel se derrumbara sobre tu pobre gusano que portaba antorchas. También era posible tener piezas del paisaje "flotando" en el aire. Tu propuesta suena como una idea divertida, simplemente no como un juego de Worms.
bummzack
Ese era todo el punto, estaba pensando en variaciones en ese juego. Además, algunas partes del paisaje pueden ser indestructibles y / o estar suspendidas permanentemente en el aire, lo que le permitiría crear bloques "flotantes". Además, a algunos se les podría aplicar una fuerza constante, tirando de ellos hacia arriba o hacia los lados, como lo hicieron las bolas de aire en el Mundo de Goo.
Septagram
Es divertido porque realmente estaba considerando hacer un juego como este, sería un giro divertido para la mecánica de Worms. La idea de los cuerpos rígidos de mapa de bits definitivamente sería un tema interesante en sí mismo, aunque la complejidad está un poco sobre mi cabeza.
William Casarin
Bueno, en este caso, los cuerpos rígidos de mapa de bits serían un no ir, en cambio, haría un paisaje como una cuadrícula triagonal de vértices, conectados elásticamente. ¿Has jugado world of goo? Si no, mira las capturas de pantalla: vgchartz.com/games/pics/6644424aaa.jpg doublegames.de/images/screenshots/world-of-goo_1_big.jpg . No, no, no, no, si no lo jugaste, absolutamente debes :) Ahora imagina que en lugar de bolas pegajosas, cada triángulo muestra parte de la textura de tu paisaje, y son mucho más pequeños. Juega con constantes y tu paisaje será bastante duro o suave como una gelatina
Septagram
2
Echa un vistazo al motor físico . Todo el motor se basa en la idea de que todo es una red deformable / destructible (como una torre de goo).
deft_code el
3

Como bummzack dijo Bitmaps. Aunque podría usar transparencias de 1 bit o si no tiene ese soporte, use un horrible color rosa que no usará en su juego.

El punto de impacto se puede calcular simplemente verificando el color del píxel. y cuando ocurre un impacto, cambie el color (o elimínelo) del mapa de bits.

En cuanto al radio de la explosión, mi primera parada sería el algoritmo circular de Bresenham , muy rápido y eficiente. Aunque primero haría un rought delete con algo así como un cuadrado y pondría el círculo alrededor para obtener los bordes.

PhilCK
fuente