Implémentation d'un paysage 2D destructible (comme Worms)
76
Quelles étapes seraient impliquées dans la construction d'un paysage 2D destructible, comme dans Worms? Idéalement, comment pourrait-on rendre ce processus aussi efficace que possible?
Excellente question. Worms a deux défis: la destructibilité et le mouvement sur des angles étranges.
ashes999
Je pense que cela a été demandé à plusieurs reprises ici
Vishnu
2
Vish, les liens qui s’y rattachent ne semblent pas le suggérer.
Le canard communiste
3
Vous pouvez vérifier comment cela se passe dans Hedgewars - c'est un clone opensource Worms.
GvS
Pas assez pour une réponse, mais vous voudrez peut-être aussi consulter Clonk . C'est un ancien jeu en 2D d'un développeur allemand qui présentait également un paysage destructible, jusqu'à des pixels spécifiques. Ce n'est plus en développement, mais le code source est disponible sous le lien ci-dessus. Il y a aussi le successeur Open Source OpenClonk, mais d'après les vidéos, il semble s'être éloigné de la destruction au pixel près pour prendre une tournure dans la direction de Terraria avec une sorte de bloc pouvant être détruit.
Christian
Réponses:
47
Je ne sais pas comment le paysage dans les vers a été implémenté exactement, mais je suis sûr qu'ils ont utilisé une image bitmap pour le paysage (du moins dans les jeux plus anciens de la série).
Une approche très basique serait une image bitmap (N / B) où les pixels noirs représentent l’ air et les pixels blancs le sol . La destruction du paysage peut être facilement effectuée en utilisant des opérations de pixel. Donc, si une fusée touche le sol, tracez un cercle noir radius = blastRadiusau point d'impact.
Vous pouvez ensuite rendre votre monde (ou une partie de celui-ci) à l'aide de cette image. Pour de meilleures performances, je vous suggère de l'implémenter de manière à ne mettre à jour / restituer qu'une partie du "monde". Par exemple. si certaines parties du paysage sont détruites par une fusée, restaurez les zones touchées, pas le monde entier.
Au lieu d’une image en noir et blanc comme "carte de collision", vous pouvez également utiliser une image 24 bits dans laquelle vous utilisez deux canaux pour stocker la surface normale (x, y) par pixel et un canal pour stocker la "collision- carte". Avoir la surface normale à portée de main vous aidera grandement à calculer les grenades qui rebondissent ou à déterminer si un personnage peut se déplacer dans une direction donnée.
Stocker des informations supplémentaires est que la carte de collision est une belle idée.
deft_code
6
Une possibilité qui m'est venue à l'esprit:
Utilisez une représentation de chemin graphique vectoriel pour stocker le contour du "terrain" destructible. Lorsqu'un événement de destruction se produit (par exemple, une grenade s'éteint), la zone de tir, représentée par un cercle, serait supprimée du chemin terrestre via une opération de soustraction booléenne. Le chemin résultant représente le nouveau "terrain" pour la détection de collision au sol et éventuellement un masque pour dessiner le terrain.
Je pense que c'est comme ça que Hedgewars le fait. @ Bill, vous pouvez y jeter un coup d'oeil, puisqu'il est opensource.
Gastón
2
@ Gastón Les cartes dans Hedgewars sont toutes des images (PNG). Je doute qu'ils soient convertis en graphiques vectoriels. En outre, l'utilisation de graphiques vectoriels (splines, Bézier, etc.) est beaucoup plus lourde en ressources processeur pour la détection de collision ou la soustraction de formes. Regarder la source est une bonne idée cependant (bien que le style de codage soit plutôt mauvais :))
bummzack
4
Une telle géométrie peut devenir TRÈS compliquée, TRÈS rapide!
Adam Harte
Googler "box2d destructible terrain" donne maintenant quelques démonstrations vectorielles exécutables.
Ciro Santilli a annoncé le 14/10
6
Utiliser une géométrie solide constructive
J'ai écrit une preuve de concept qui utilisait une géométrie solide constructive pour gérer un terrain destructible. J'ai utilisé le GLU Tessellator pour effectuer les opérations booléennes. La documentation explique comment, recherchez "Règles d'utilisation du CSG pour le bobinage" .
J'ai introduit le triangle du tessellator sous forme de polygones statiques dans Box2D. Le PoC a très bien fonctionné. J'ai pu soustraire et ajouter du terrain de manière arbitraire en temps réel et le terrain a continué à se comporter de manière appropriée avec Box2D. Le seul hic, c'est que le tessellator GLU peut produire des triangles dégénérés que Box2D n'aime pas, alors j'ai dû les filtrer à la main.
La prochaine étape de la PoC (à laquelle je n’avais jamais pensé) consistait à utiliser l’ algorithme SCC de la bibliothèque de graphes boost pour détecter le moment où une partie du terrain avait été coupée (couper le sommet d’une montagne). Le terrain coupé serait toujours destructible, mais représenté maintenant par un corps Box2D dynamique (non statique) avec les triangles attachés sous forme de formes. Le design était finalisé, mais j'avais perdu tout intérêt lorsque j'ai commencé à fouiller dans la documentation de boost. Je "prévois" de revisiter l’idée quand je ferai un jour un jeu de terre brûlée / Worms.
Toutes les réponses ci-dessus parlent de la mise en œuvre du cas le plus simple, comme dans les vers. En d’autres termes, lorsque la zone d’impact est détruite et que tout le reste n’est pas touché. Avez-vous pensé que votre paysage pourrait éventuellement être divisé en deux? Dites, il y a une montagne et les joueurs en coupent le fond avec un lance-roquettes. Maintenant, la montagne ne devrait-elle pas tomber? En outre, il serait naturel qu'un paysage soit un peu élastique. Au temps de Worms (du moins, je me souviens d’eux, je n’ai pas joué à Worms pendant de nombreuses années), les ordinateurs n’étaient pas assez puissants pour le faire correctement. Mais ils sont maintenant.
Bien sûr, cela dépend totalement des ambitions de votre projet. Mais si vous voulez que ce soit vraiment génial, vous devriez peut-être essayer Box2D en tant que moteur physique. Vous pouvez faire beaucoup avec cela.
Dans les vers, vous pouvez creuser un trou dans le paysage à l'aide d'une torche. Ce ne serait pas drôle si ce tunnel s'effondrait sur votre pauvre ver à torche. Il était également possible d'avoir des morceaux du paysage "flottant" dans les airs. Votre proposition ressemble à une idée amusante, mais pas à un jeu de Worms.
Bummzack
C’était l’essentiel, je pensais aux variations de ce gameplay. De plus, certaines parties du paysage peuvent être indestructibles et / ou suspendues en permanence dans les airs, ce qui vous permettrait de créer des blocs "flottants". En outre, certains pourraient se voir appliquer une force constante, les tirant vers le haut ou de côté, comme ce que font des boules d'air dans le monde de Goo.
Septagram
C'est drôle parce que j'envisageais de faire un jeu comme celui-ci, ce serait une tournure amusante pour le mécanicien Worms. L'idée de corps rigides bitmap serait certainement un sujet intéressant en soi, mais la complexité est un peu au-dessus de ma tête.
William Casarin
Eh bien, dans ce cas, les corps rigides bitmap seraient un non-lieu, au lieu de cela, je ferais un paysage comme une grille triagonale de sommets, liés de manière élastique. Avez-vous joué au monde de goo? Sinon, voir les captures d'écran: vgchartz.com/games/pics/6644424aaaaj.jpg doublegames.de/images/screenshots/world-of-goo_1_big.jpg . Non, non, non, non, si vous ne jouez pas, vous devez absolument :) Maintenant, imaginez qu'au lieu de balles gluantes, chaque triangle affiche une partie de la texture de votre paysage, et elles sont beaucoup plus petites. Traquez des constantes et votre paysage sera soit assez dur, soit doux comme une gelée
Septagram
2
Regardez le moteur physique . L'ensemble du moteur repose sur l'idée que tout est un réseau déformant / destructible (comme une tour de goo).
deft_code
3
Comme bummzack dit Bitmaps. Bien que vous puissiez utiliser des transparents 1 bit ou si vous ne disposez pas de ce support, utilisez une couleur rose horrible que vous n'utiliserez pas dans votre jeu.
Le point d’impact peut être calculé en vérifiant simplement la couleur du pixel. et lorsqu'un impact se produit, changez la couleur (ou supprimez-la) du bitmap.
En ce qui concerne le rayon de souffle, mon premier arrêt serait l’ algorithme du cercle de Bresenham , très rapide et efficace. Bien que je ferais une suppression brute d'abord avec quelque chose comme un carré et mettre le cercle autour de lui pour obtenir les bords.
Réponses:
Je ne sais pas comment le paysage dans les vers a été implémenté exactement, mais je suis sûr qu'ils ont utilisé une image bitmap pour le paysage (du moins dans les jeux plus anciens de la série).
Une approche très basique serait une image bitmap (N / B) où les pixels noirs représentent l’ air et les pixels blancs le sol . La destruction du paysage peut être facilement effectuée en utilisant des opérations de pixel. Donc, si une fusée touche le sol, tracez un cercle noir
radius = blastRadius
au point d'impact.Vous pouvez ensuite rendre votre monde (ou une partie de celui-ci) à l'aide de cette image. Pour de meilleures performances, je vous suggère de l'implémenter de manière à ne mettre à jour / restituer qu'une partie du "monde". Par exemple. si certaines parties du paysage sont détruites par une fusée, restaurez les zones touchées, pas le monde entier.
Au lieu d’une image en noir et blanc comme "carte de collision", vous pouvez également utiliser une image 24 bits dans laquelle vous utilisez deux canaux pour stocker la surface normale (x, y) par pixel et un canal pour stocker la "collision- carte". Avoir la surface normale à portée de main vous aidera grandement à calculer les grenades qui rebondissent ou à déterminer si un personnage peut se déplacer dans une direction donnée.
la source
Une possibilité qui m'est venue à l'esprit:
Utilisez une représentation de chemin graphique vectoriel pour stocker le contour du "terrain" destructible. Lorsqu'un événement de destruction se produit (par exemple, une grenade s'éteint), la zone de tir, représentée par un cercle, serait supprimée du chemin terrestre via une opération de soustraction booléenne. Le chemin résultant représente le nouveau "terrain" pour la détection de collision au sol et éventuellement un masque pour dessiner le terrain.
la source
Utiliser une géométrie solide constructive
J'ai écrit une preuve de concept qui utilisait une géométrie solide constructive pour gérer un terrain destructible. J'ai utilisé le GLU Tessellator pour effectuer les opérations booléennes. La documentation explique comment, recherchez "Règles d'utilisation du CSG pour le bobinage" .
J'ai introduit le triangle du tessellator sous forme de polygones statiques dans Box2D. Le PoC a très bien fonctionné. J'ai pu soustraire et ajouter du terrain de manière arbitraire en temps réel et le terrain a continué à se comporter de manière appropriée avec Box2D. Le seul hic, c'est que le tessellator GLU peut produire des triangles dégénérés que Box2D n'aime pas, alors j'ai dû les filtrer à la main.
La prochaine étape de la PoC (à laquelle je n’avais jamais pensé) consistait à utiliser l’ algorithme SCC de la bibliothèque de graphes boost pour détecter le moment où une partie du terrain avait été coupée (couper le sommet d’une montagne). Le terrain coupé serait toujours destructible, mais représenté maintenant par un corps Box2D dynamique (non statique) avec les triangles attachés sous forme de formes. Le design était finalisé, mais j'avais perdu tout intérêt lorsque j'ai commencé à fouiller dans la documentation de boost. Je "prévois" de revisiter l’idée quand je ferai un jour un jeu de terre brûlée / Worms.
la source
Toutes les réponses ci-dessus parlent de la mise en œuvre du cas le plus simple, comme dans les vers. En d’autres termes, lorsque la zone d’impact est détruite et que tout le reste n’est pas touché. Avez-vous pensé que votre paysage pourrait éventuellement être divisé en deux? Dites, il y a une montagne et les joueurs en coupent le fond avec un lance-roquettes. Maintenant, la montagne ne devrait-elle pas tomber? En outre, il serait naturel qu'un paysage soit un peu élastique. Au temps de Worms (du moins, je me souviens d’eux, je n’ai pas joué à Worms pendant de nombreuses années), les ordinateurs n’étaient pas assez puissants pour le faire correctement. Mais ils sont maintenant.
Bien sûr, cela dépend totalement des ambitions de votre projet. Mais si vous voulez que ce soit vraiment génial, vous devriez peut-être essayer Box2D en tant que moteur physique. Vous pouvez faire beaucoup avec cela.
la source
Comme bummzack dit Bitmaps. Bien que vous puissiez utiliser des transparents 1 bit ou si vous ne disposez pas de ce support, utilisez une couleur rose horrible que vous n'utiliserez pas dans votre jeu.
Le point d’impact peut être calculé en vérifiant simplement la couleur du pixel. et lorsqu'un impact se produit, changez la couleur (ou supprimez-la) du bitmap.
En ce qui concerne le rayon de souffle, mon premier arrêt serait l’ algorithme du cercle de Bresenham , très rapide et efficace. Bien que je ferais une suppression brute d'abord avec quelque chose comme un carré et mettre le cercle autour de lui pour obtenir les bords.
la source