D'un point de vue général, il existe deux façons de procéder.
-
LA MAUVAISE MANIÈRE (mais fonctionne mieux lorsque le fluide a des textures) : Créez la feuille de sprite à l'avance, puis superposez un enfant supplémentaire de l'objet SKSpriteNode. L'image dans le sprite d'animation sera une fonction de la distance entre la balle et la surface lorsque la distance entre elles est inférieure à une certaine quantité. La plage de distance souhaitée (range) devra être mise en correspondance avec le numéro d'image du sprite (frameIndex). f(range) = frameIndex. L'interpolation linéaire sera utile ici. Nous reviendrons plus tard sur l'interpolation.
-
LA BONNE FAÇON : faites du fluide un objet courbe, puis animez les points de la courbe par interpolation linéaire entre les états initial, intermédiaire et final. Cela nécessitera trois courbes ayant chacune le même nombre de points. L'état initial du fluide est F1. Modélisez les points F1 comme le fluide statique. Soit l'état du fluide F2 lorsque la balle est à moitié submergée. Modélisez les points F2 pour qu'ils ressemblent à la boule submergée à sa largeur maximale. Soit l'état du fluide F3 lorsque la balle est immergée à 75%. Remarquez que lorsque la balle est complètement submergée, le fluide semble inchangé. C'est pourquoi, lorsque la balle est immergée à 75 %, la tension superficielle qui la saisit est maximale. En ce qui concerne SpriteKit, vous pouvez utiliser ces objets :
CGMutablePathRef path = CGPathCreateMutable();
CGPathMoveToPoint(path, NULL, 0, 0);
CGPathAddQuadCurveToPoint(path, NULL, 50, 100, 100, 0);
CGPathAddLineToPoint(path, NULL, 50, -100);
CGPathCloseSubpath(path);
SKShapeNode *shape = [[SKShapeNode alloc]init];
shape.path = path;
Détectez ensuite quand la balle se trouve à l'extérieur du fluide en utilisant le produit vectoriel croisé avec des vecteurs 3D, même si votre projet est en 2D.
Ball Vector (Vb)
^
|
(V) O---> Closest Fluid Surface Vector (Vs)
V = Vb x Vs
Regardez ensuite la composante Z de V appelée Vz. Si (Vz < 0), la balle est à l'extérieur du fluide : Créez une variable t :
t = distOfBall/radiusOfBall
Ensuite, pour chaque point ordonné dans vos formes fluides, faites ce qui suit :
newFluidPointX = F1pointX*(t-1) + F2pointX*t
newFluidPointY = F1pointY*(t-1) + F2pointY*t
Si Vz > 0), la boule est à l'intérieur du fluide :
t = -(((distOfBall/radiusOfBall) + 0.5)^2) *4 + 1
newFluidPointX = F2pointX*(t-1) + F3pointX*t
newFluidPointY = F2pointY*(t-1) + F3pointY*t
Cela fonctionne parce que deux formes quelconques peuvent être mélangées en utilisant l'interpolation. Le paramètre "t" agit comme un pourcentage de fusion entre deux formes.
Vous pouvez en fait créer des mélanges sans couture entre deux formes quelconques, pour autant que le nombre de points soit le même. C'est ainsi qu'un homme se transforme en loup dans les films hollywoodiens, ou qu'un homme peut se transformer en une flaque d'eau. Le seul principe en jeu pour ces effets est l'interpolation. L'interpolation est un outil très puissant. Elle est définie comme suit :
L = A*(t-1) + B*t
where t is in between 0.0 and 1.0
and A and B is what you are morphing from and to.
Pour en savoir plus sur l'interpolation, voir : Article Wiki
Pour une étude plus approfondie. Si vous envisagez d'animer des formes dynamiques, je vous conseille de comprendre les courbes de Bézier. Pomax a un article merveilleux sur le sujet. Bien que de nombreux frameworks intègrent des courbes, une compréhension générale de leur fonctionnement vous permettra de les manipuler de manière intensive ou de créer vos propres fonctionnalités là où le framework fait défaut. Voici l'article de Pomax :
Une introduction aux courbes
Bonne chance pour vos progrès :)
1 votes
Je ne vois pas bien quel aspect de "pénétrer dans une substance épaisse" vous essayez de capturer. La vitesse de l'objet circulaire ? La couleur lorsqu'il rencontre la "substance épaisse" ? La tension superficielle de la substance plus épaisse ? Vous pouvez peut-être inclure un dessin de l'effet que vous recherchez...
2 votes
Je fais référence à la tension de surface de la substance la plus épaisse.
0 votes
Est-ce que c'est quelque chose que vous recherchez ? pasteboard.co/1zoNKPiJ.png J'y ai deux cercles que vous faites glisser et que vous reliez en douceur. Je crée une forme personnalisée entre deux cercles en utilisant un chemin de bézier et une certaine géométrie.
0 votes
@Rob Merci pour la recommandation. Je viens de mettre à jour la question.
0 votes
@konrad.bajtyngier C'est un peu similaire à ce que je veux obtenir en séparant l'objet circulaire de la surface plane.
0 votes
Je viens de remarquer votre question sur les mises à jour. Une trajectoire en bézier avec Core Graphics pourrait être une solution. Je mets à jour la trajectoire à chaque fois que mon reconnaissant de gestes appelle et se trouve dans l'état .Changed. Voici un exemple de ma forme personnalisée (en noir) pasteboard.co/1EeGoSNX.png
0 votes
Représenter la substance comme de minuscules particules, reliées les unes aux autres (simulant une tension).
0 votes
J'étudierais ce qui est offert par les moteurs de jeu disponibles sur le marché. Je suis sûr qu'entre SpriteKit, Unity et Unreal 4, il y a quelque chose que vous pouvez utiliser.
0 votes
Juste pour vous donner une idée, avez-vous jeté un coup d'oeil à "Liquid Fun". Cela pourrait vous mettre sur la bonne voie. raywenderlich.com/85515/liquidfun-tutorial-1
0 votes
Je suppose simplement qu'il faut avoir de grandes connaissances en mathématiques (chemins de Bézier ?) ou en physique (mécanique des fluides ?) pour trouver sa propre solution. Mais peut-être qu'un génie a déjà un cadre ou un code source que vous pouvez utiliser.
1 votes
@konrad.bajtyngier avez-vous réussi à séparer les deux formes dans l'image que vous avez montrée ? Si oui, pourriez-vous partager un peu plus d'informations ou de code sur la façon dont vous l'avez fait.
0 votes
Pourquoi ne pas essayer ceci github.com/MengTo/Spring
0 votes
Vous pouvez l'utiliser comme référence : designcode.io/swiftapp