jeudi 21 juin 2018

[Unity3D][Défi50jours] Jour 3 - Génération d'un terrain

Bloup bloup blip, c'est l'heure de l'update du jour 3 !

Maintenant qu'on sait comment sauvegarder/charger, il est temps de rentrer un peu plus directement dans la mère... Dans le lard du sujet !

Ce qui nous intéresse maintenant, c'est d'avoir un support sur lequel poser nos bâtiments et autres joyeusetés. La babybase du jeu quoi, pour ceux qui suivent, on va donc essayer de générer un terrain!
Avant de s'intéresser directement à faire un truc en 3D, j'ai préféré commencer par dessiner une simple texture sur un plan. D'ailleurs, petite précision, même si le terrain passera par la suite en 3D, il sera quand même plat, pour plus de facilité au début.
Pour ceux qui avaient suivi mes précédentes aventures, j'avais déjà réalisé un algorithme permettant de générer automatiquement une map de donjon. Vous pouvez le retrouver ici #autopromo. En revanche, ce type de carte n'est pas vraiment adapté aux attentes du jeu de construction, donc autant repartir de zéro.
J'ai donc commencé par faire une simple texture de 100*100 pixels et ait essayé d'appliquer une couleur de manière aléatoire à chacun de ses pixels. Et là ben comment dire, c'était DEGUEULASSE 


J'ai oublié de faire une capture à ce moment là et j'ai un peu la flemme de revenir en arrière pour vous le montrer, mais du coup voici une image trouvée sur le net qui ressemble bien à ce que ça pouvait donner:


Comme vous pouvez le voir, oui c'est bien aléatoire, mais un peu trop justement, il n'y a aucune consistance, et jouer là dessus ça risque d'être un peu tendu. Du coup, direction internet afin de glaner quelques informations sur des méthodes de génération.
Là, autant vous dire qu'il y en a eu beaucoup, et qu'en une heure de temps je suis loin d'avoir passé tout en revue. Il y en avait même une qui se basait sur le jeu de la vie pour arriver à générer des terrains assez stylés. Cette méthode semblait être beaucoup plus que ce dont j'avais besoin ici, donc je ne l'ai pas retenue, mais je pense qu'une fois ce défi terminé, j'essaierai de voir ce que ça peut donner. Pour ceux qui ne connaissent pas le jeu de la vie, il serait assez long d'en parler ici, alors je vous invite a visionner cette vidéo explicative que je n'ai pas du tout écoutée parce que je suis au boulot mais qui j'en suis sûr est très informative parce que cet homme a une guitare et des geomags.



Bref, en continuant mes recherches, je suis finalement tombé sur quelque chose que je ne connaissais pas du tout, les diagrammes de Voronoï. 

Diagramme de Voronoi par Jean Wikipédia


Pour faire simple, un diagramme du Voronoï est une partition particulière du plan. Un certain nombre de points sont pris de manière aléatoire et sont notés comme "points centraux" ou encore "graines", ils sont en noirs sur l'image précédente. Chacun de ces points va être l'origine de ce que l'on appellera une "région". Puis pour chaque point du plan, on cherche le point central qui lui est le plus proche et on l'ajoute à la région de ce dernier. A la fin, chaque région peut être coloré d'une couleur différente. Cela permet alors d'avoir toujours de l'aléatoire, mais cette fois-ci cela créera automatiquement des régions, et visuellement ça pique moins les yeux. On sent d'ailleurs d'où s'est inspiré Picasso pour ses tableaux.

Comme cela semblait être une bonne alternative, et beaucoup plus facile à implémenter, j'ai décidé d'essayer directement. Pour ce faire j'ai du définir plusieurs choses:
  1. D'abord une liste de types que peut revêtir le sol. Pour le moment j'ai défini GRASS, DIRT, et TREE. Comme je l'avais expliqué lors du live de lancement, pour le moment je ne veux pas ajouter d'eau pour des raisons de facilités
  2. Ensuite, j'ai créé un objet "TileObject" qui comporte une position (x,y), un Type, et une variable pour indiquer s'il s'agit d'un point central.
  3. Enfin j'ai défini un nombre de points centraux à créer. Etant sur une map 100*100, donc 10 000 points possible, j'avais commencé par essayer avec 1000

Une fois cela fait, place à l'algorithme en lui même. Grâce au TileObject défini plus tôt, j'ai pu éviter d'avoir a créer des régions pour chaque point. Voici en gros comment se déroule l'algorithme:
  1. On prend un point avec des coordonnéees (x,y) au hasard.
  2. On le définit en tant que point central et on l'ajoute à une liste de point centraux
  3. On lui donne un type au hasard entre GRASS, DIRT et TREE
  4. On refait les 3 points précédents jusqu'à ce que le nombre de points centraux désiré soit atteint (pas de panique on ne le fait pas à la main bien sûr, une boucle suffit)
  5. Puis on parcourt tous les points de la carte et pour chacun:
    1. On cherche dans la liste des points centraux celui qui en est le plus proche
    2. On lui donne le le même type que ce point central
Et voilà, simple non ? 😀

Pour la visualisation, j'ai simplement défini une couleur pour chaque type, et ait appliqué le tout sur une texture de plan. Ici j'ai mis violet pour DIRT, vert pour GRASS et bleu pour TREE (oui c'est pas logique mais j'ai choisi les premières qu'on m'a proposé parce qu'il était tard). J'ai fait tourner l'algorithme plusieurs fois en changeant a chaque fois le nombre de points centraux générés, et voici les résultats (en noir ce sont les points centraux): 

Voronoi - 10 points

Voronoi - 100 points

Voronoi - 1000 point

Comme vous pouvez le constater, les dessins obtenus sont beaucoup plus agréables à regarder qu'avec de l'aléatoire complet. Un autre point à noter est que plus il y a de points centraux, plus il y aura de regions différentes. Dans le cas du jeu, je pense que 1000 points sera beaucoup trop, et qu'il faudra sélectionner une valeur entre 10 et 100 pour quelque chose de correct.

Voilà qui conclut le résumé d'hier. C'était un peu plus dense je vous l'accorde, mais j'espère que ça vous aura plu autant qu'à moi, arriver à ce résultat en à peine plus d'une heure de temps était vraiment gratifiant.
Pour ce soir, le travail consistera à assurer le passage à la 3D, et si le temps le permet à faire la sauvegarde/chargement de cette map créée. Et si je ne rentre pas trop crevé, j'essaierai de le faire en live car ça pourrait être intéressant pour tout le monde.

Sur ce, merci de votre lecture, n'hésitez pas à m'envoyer vos retours ou suggestion, et on se retrouve peut être ce soir pour un live sinon demain pour le résumé d'aujourd'hui.
(Jean michel logique est dans la place)





PS: J'ai créé un Trello pour m'organiser sur les tâches à faire, si vous voulez avoir un aperçu de ce qui vient et vérifier que je fais bien mon travail, c'est par ici https://trello.com/b/s5jmRmqs/unity-builder

Aucun commentaire:

Enregistrer un commentaire