Dispersion de l'eau !

Dispersion de l'eau !

Ajouté le mardi 16 juillet 2019 par MrSinaf
  • Auteur du tutorial: MrSinaf

Nouvelle mise-à-jour 2.0:

  • L'optimisation a été plus ou moins effectué. (Explication à la fin.)

Mais doit-être mise-à-jour car:

  • La longueur des 'courants d'eau' doit pouvoir être varié. (Très simple à faire.)
  • Le temps de propagation doit pourvoir être varié. (Très simple à faire.)
  • [LA PAGE] Doit être entièrement revu, pour vos beaux yeux (Vraiment beaux ces yeux !). (Ca a déjà commencé... et (encore) recommencé...)

Ancienne mise-à-jour:

  • [Vers 1.5]Plus beau qu'avant (Le fond passe de 'blanc' à 'noir' et les lignes de 'noir' à 'bleu foncé'.)
  • [Vers 1.5]L'eau prend en compte le fait que vous ajoutiez ou supprimez un 'mur'. (La version 1, le faisait seulement avant de poser l'eau.)
  • [Vers 1.5]La vitesse de propagation de l'eau est plus facilement modifiable.
  • [Vers 1.8]Peut prendre en compte plusieurs courant d'eau à la fois.
  • [Vers 1.8]Démonstration d'un effet de profondeur d'eau. (Plus foncé au centre et de moins en moins jusqu'au bout. (Peut être modifié dans les 'images'.).)
  • [Vers 1.8]Ajoute une transition de transparence sur la création et la destruction de l'eau.
  • [Vers 1.8]Sauvegarde (et supprime) l'emplacement initiale de l'eau dans un fichier 'ini'. (Peut être contourner, mais c'est déconseillé.)
  • [Vers 1.9]Les 'courants d'eau' ne sont plus indépendante l'une de l'autre, et peuvent s’assembler. 

Pourquoi aurais-je besoins de ce tuto ?

Bonjour à toi !
Ce "tuto" peut aider certaine personne voulant représenter du liquide ou du gaz sur leur jeu. Tout cela en une vu 'aérienne':


Comme vous pouvez le voir; les couleurs signifie sont intensité:

  • 1 & 2= Forte
  • 3 & 4=Moins forte

Et ainsi de suite, selon les configurations que vous fixez sur la "longueur" de propagation, disponible sur l'actif: ("Valeurs LOCAL").
Etant un seul actif, vous pouvez remplacer facilement cela par une animation, ou juste changer la couleur par exemple du 'Vert' pour simuler du poison ou comme ici du 'bleu' pour simuler l'eau.

(A savoir que vous n'êtes obligé d'avoir un style visuel, il peut fonctionner sans actif.)


La méthode utilisé peut énormément ressembler à celle sur Minecraft (Bien qu'ici, je me suis basé sur une méthode de "pathfinding". Peut-être, comme Minecraft, mais Minecraft prend en compte les 'plus' du 3D, comme les trous.):



En mettant simplement la même longueur que "l'eau" sur Minecraft (qui est '7'), j'ai exactement le même résultat:



Mais comment tout ça fonctionne ?

Comme j'ai pu le dire plutôt: "Bien qu'ici, me suis basé sur une méthode de "pathfinding".", mais alors qu'es-ce que le Pathfinding:

La Pathfinding:
Qui se traduis plus ou moins par: "Chercher un chemin".
Permet qu'un point "A", va vers un point "B" de la manière la plus rapide et en prenant en compte les 'obstacles'.

Je vous épargne les détails, mais si vous voulez comprendre entièrement son fonctionnement aller voir ça: https://fr.wikipedia.org/wiki/Recherche_de_chemin


J'utilise plusieurs choses, pour permettre un résultat parfait:

  1. 2 tableaux: L'un pour marquer les obstacles, et l'autre pour marquer l'intensité de l'eau.
  2. 2 actifs: L'un pour "l'eau", et l'autre pour les "murs".
  3. 1 Ini++: Pour les sauvegardes de l'eau. (Il est présent pour une optimisation, à savoir qu'il peut être contourner, mais c'est conseillé de le laisser. De plus qu'il peut être fusionner avec un autre fichier (ini), car il utilise est met tout ce qu'il a besoins dans un "groupe".)
  4. 1 liste: S'utilise avec le fichier ("ini++"), et sert aussi pour une optimisation.
  5. D'autres objets, pas très important servant seulement à vous donner des infos durant son lancement

Son fonctionnement est en théorie ainsi:

Ces chiffres ont été rajouter par dessus cette capture.
Ainsi vous pourrez mieux comprendre son fonctionnement, même si je n'ai pas mis tout les chiffres. Mais c'est chiffre existe, ils sont tous marqué dans un tableau. Ceci permet à l'eau de savoir quel couleur 'image' doit-il afficher et aussi à limité la propagation; ici tout s'arrête sur le (8) et tout commence à partir du (1), donc la longueur est de 7.
Cette "longueur" peut être modifié ici:


Maintenant, voici sont fonctionnement si un autre "courant d'eau" est présent:

Ils vont tout simplement s'unir. Et peu importe l'ordre ou le moment qu'on décide de les placers.
Pour cela, il va regarder si il y a chiffre, et si c'est le cas il le remplace seulement si il est > que celui qu'on souhaite placer. Alors il place le nouveau.


Enfin, voilà comment l'eau agi fasse à des "obstacles" multiples:

Comme vous pouvez le voir là où un obstacle est posé, un (0) restera fixe. L'eau va donc passer tout autour, de la manière que vous pouvez ci-dessus^.
A noté que peut importe si l'obstacle est posé après ou avant l'eau, l'eau le prendra toujours en compte. Vous pouvez aussi détruire un obstacle, ceci ne causera aucun problème. (Fonctionne naturellement avec plusieurs "courant d'eau".)

Vous pouvez aussi voir cette vidéo, pour une démonstration:



Explication des "événements".

Bien que tout cela est fait en 29 lignes (hors les "informations"), les événements peuvent être plus ou moins compliquer à comprendre sans explication.
Si vous vous rendez dans "Editeur d'événement", vous allez voir ceci:

4 groupes, et une ligne à pars (Pour aller vite la ligne 1: C'est pour aller chercher le "fichier ini" pour sauvegarder, et supprimer tout sont contenus. Pour enlever la suppression retirer "Clear all".).

On ne va pas voir le groupe "Infos", car il est extrêmement simple et ne sert que "d'information", donc inutile sur d'autre application. Nous allons donc voir:

Ajout/Suppression de mur

En seulement 4 lignes, ce groupe permet de gérer la suppression et l'ajout d'un mur.



Ajout un mur.

Bon comme certaines choses sont simples, on va juste voir ce qui peuvent causer problème (A noter que je ne me répéterai pas sur les même actions):

  • Si: ValueAtXY ("Obstacle", Xmouse/32, Ymouse/32) <>1
        Il va regarder dans le tableau ("Obstacle") à la position de la sourie/32, si il y a un (1) ou non (32 va signifier la taille de notre objet, si votre objet est     d'une autre taille il va falloir changer tout les (32) par la taille de votre objet). Ce (1) va signifier le fait qu'il a déjà un obstacle. Donc, si un obstacle est     déjà placé on ne va pas en rajouter un autre par dessus.

  • "Obstacle"; Ecrire valeur (1) en (XMouse/32, Ymouse/32)
        Il va signifier que maintenant il y a un 'obstacle' en notant (1) sur le tableau ("Obstacle") à la position de la sourie/32.

  • Démarrer la boucle "Area_R" DimX("Ecoulement") * DimY("Ecoulement") fois
        Nous verrons l'utilité de cette boucle, un peu plus tard. Mais elle va se répéter par la 'longueur * largeur du tableau ("Ecoulement")'.

  • Démarrer la boucle "Nombre" Nombre("Valeurs LOCAL") fois
        Nous verrons l'utilité de cette boucle, un peu plus tard. Mais elle va se répéter autant de fois qu'il y a de source d'eau.

  • Mettre Coule sur ON
    Ceci nous permettra par la suite d'activer l'effet de l'eau. (A désactiver si vous ne voulez pas d'actif d'eau ou autre.)


Supprime un mur.

Comme certaines choses sont simples, on va juste voir ce qui peuvent causer problème (A noter que je ne me répéterai pas sur les même actions):

  • "Obstacle"; Ecrire valeur (0) en (XMouse/32, Ymouse/32)
        Il va signifier que maintenant il n'y a plus un 'obstacle' en notant (0) sur le tableau ("Obstacle") à la position de la sourie/32

Supprime l'eau se trouvant en dessous du mur.

Comme certaines choses sont simples, on va juste voir ce qui peuvent causer problème (A noter que je ne me répéterai pas sur les même actions):

  • "Ecoulement"; Ecrire valeur (0) en (XMouse/32, Ymouse/32)    
        Il va signifier que maintenant il n'y a plus de 'l'eau' en notant (0) sur le tableau ("Ecoulement") à la position de la sourie/32

Effectue des actions durant la boucle "Area_R".

Comme certaines choses sont simples, on va juste voir ce qui peuvent causer problème (A noter que je ne me répéterai pas sur les même actions):

  • Si: ValueAtXYZ("Ecoulement"), LoopIndex(Area_R") mod DimX("Ecoulement"), LoopIndex("Area_R")/DimY("Ecoulement"),<>1
        On arrive sur quelque chose d'incompréhensible pour certain et pour d'autre quelque chose de tout à fait logique. (J'ai mis des choses en gras pour vous     aider. Chaque virgule, va marqué une étape, voici ce que dois représenter les chiffres:
        >Nom du Tableau<, >Position X<, >Position Y<, >Position Z<  <> 1    (Si vous avez de la difficulté avec les tableaux voici une vidéo qui vous aidera à     comprendre, tout comme elle a pu le faire pour moi: https://www.youtube.com/watch?v=gxTMoB0SJ7A )
        
        Dans la ">Position X<" j'utilise mod. (Pour comprendre les fonctionnalités de "mod" voici un vidéo qui m'avait beaucoup aidé à l'époque, même si c'est     pour "Scratch", il fonctionne de la même manière sur Clickteam Fusion: https://www.youtube.com/watch?v=X4LdvoAUk1c&t=50s )
        
        Et tout ces calcules avec "mod" et "/", permet de récupérer l'air d'un rectangle/carré. Et ici l'air de notre tableau.
        Ainsi il va vérifier sur chacune des cases du tableau si c'est bien différent de 1, avec 1 seul boucle.
        (A noté qu'il y a une autre méthode pour 'vérifier' toutes les cases d'un tableau, vous le verrez à peu plus bas.)

  • "Ecoulement"; Ecrire valeur (0) en (LoopIndex(Area_R") mod DimX("Ecoulement"), LoopIndex("Area_R")/DimY("Ecoulement"),1)
        Permet de remplacer tout ce qui n'est pas (1) en (0), pour plus tard ne pas avoir de problème sur la réécriture.

[Je peux comprendre que pour certains ceci est compliqué, alors n'hésitez à me le souligner si vous rencontrez de la difficulté. Je tiens à que tout le monde puissent comprendre le fonctionnement. S'il le faut, on communiquera en 'privé' voir 'vocal', pour COMPRENDREIL FAUT COMPRENDRE pour l'utilisé, voir même l'améliorer.]


TOUJOURS EN travaux ! (naturellement)


Sur la question de l'optimisation: Quand je parle d'optimisation, c'est surtout sur le "nombre de courant". Je considère optimisé au moment où le moins de courant possible est pris à chaque modification.

Frame 1= Non optimisé, à chaque mur ajouter ou détruit, à chaque courant créé il repense à tout les autres courants. Mais garanti sans bug technique.
Frame 2= Optimisé à moitié, un peu plus dur à expliquer, mais le seul problème est dans l'ajout de "mur", sinon tout le reste est optimisé à 100%. Personnellement je n'ai vu aucun bug, mais je ne le garanti pas.
Frame 3=totalement optimisé, mais cause quelques des problèmes sur l'ajout de "mur". 100% optimisé, mais des bugs techniques peuvent arriver sur certaines conditions....

Je vous conseil fortement d'utiliser la Frame 2, je compte minimiser le nombre de "courant" pris en compte à l'ajout d'un mur par la suite !
Et les explications seront que pour cette Frame 2.