5
\$\begingroup\$

The entities in my game are soft-body, amorphous cells. I'd like to create an animation where enemies are engulfed by the player's cell. That is, I want to generate a "cell eating another cell"-effect. See this video for the type of motion I want: https://www.youtube.com/watch?v=iO_vOFFf1uQ

I'm considering using fluid dynamics to achieve this, but I'm lost as to where to start. I'm working in Unity2D, and Fluvio doesn't seem to provide what I need. Does anyone have advice on the best way for me to proceed?

\$\endgroup\$
  • \$\begingroup\$ I think you need to make a lot more precise what exactly it is that you want to see. Why not make a small animation by hand? The video isn't very clear tbh, and I'm guessing the idea in your head isn't very clear yet as well. \$\endgroup\$ – Roy T. Oct 3 '14 at 8:37
7
+50
\$\begingroup\$

What may be a good way of simulating entities which may vary a lot is to use a force field that you draw with a marching square algorithm.

So the eating entity would be a set of fields that you have moving together using a flocking strategy or similar, to get a 'cell' effect. You have to use a number of force field large enough to allow for opening a 'mouth' within it. Maybe 6 - 10 fields would be ok.

The marching square can be made quite fast with careful implementation. Notice that you only need it if you need the edges of your entity, otherwise you might just draw carefully using gradients and it might look good. If you write a webgGL shader, you could most likely make all this real-time.

I just rushed a small example, re-using an old project.

jsfiddle.net/gamealchemist/7tjfhhre/

It's using the canvas's context2d, radial gradients and blend modes.
If you think about it, you can consider that the lightness of a point is the strength of the field in that point, and you can consider a radial gradient lowering to zero as a force field, ==>> drawing gradients is exactly like computing the field in each (x,y) point of the screen.
Again, you'll still need marching cubes if you want to draw the edges (more 'cartoonish') .

2 screenshots (try it live it's nicer ! )

ScreenShot when mouth closed :
enter image description here

mouyh opened :
enter image description here

\$\endgroup\$
  • 1
    \$\begingroup\$ This could look really amazing if the number of sprites was increased, and distance fields were used for the sprites. Render it to a FrameBuffer, and then use smooth steps in the fragment shader to make it look like a continuous surface with whatever other types of highlights you want. \$\endgroup\$ – TenFour04 Oct 7 '14 at 13:23
5
\$\begingroup\$

Fluid dynamics is one of those super hard things to set up, that once you've got it working allows for a whole range of interesting effects. It's probably overkill for most games, unless you actually need things to move like a fluid (as in, flow from one point to another). For soft-body masses, I would considering instead using nets of springs to simulate your bodies; much more straightforward to implement, and far easier to handle from a gameplay point of view.

As a possible initial implementation: imagine that your body would have a centroid, that you could apply forces to and move around. Around that centroid, you'd attach additional nodes, linked to the centroid with a spring, and linked to each other to form a network that holds its shape. For example a hexagon of 6 nodes around the outside, each linked to their neighbour and also the centroid via springs. As you apply forces to the centroid, the springs act to pass on that force to the outer parts of the body; the front compresses towards the centroid, the rear elongates as it is pulled with the centroid. That's not the only way to do it, you can have the movement forces applied equally to all the nodes, it all depends on how you imagine these bodies to work internally. Apply forces to all nodes equally, and the body won't deform unless it encounters something else.

And it's in encountering "something else" that things get interesting, and cause your body to deform nicely. Bear in mind you're simulating something soft and squishy, not a bunch of hard spheres connected together. So maybe instead of using rigid body collision, give each of the nodes a repulsion from the other objects in your simulation. Then, as you move your body towards an object smaller than itself, the gap between nodes will widen to allow the object to slip between them. After the object has passed through, the springs that hold the body together will cause it to reform into its original shape. Objects larger than the body won't be able to fit through the gaps, so your body should collide with the larger object and flatten against it. It's possible you want to implement rigid body physics as well, to prevent a squishy object penetrating through something that should be solid, but it should be a backup to the repulsion-based forces that are simulating the squishy exterior of your body.

In terms of rendering, you can get a nice blobby effect with a pixel shader or render-to-texture approach, basically rendering a circle around each node such that the overlaps are invisible, but around the edges there are nice soft circular edges.

So look up spring networks and Verlet integrated spring simulations, and you should be able to get the foundations of a system that will let you do 'blobby' physical mechanics without doing full on free-moving fluid simulations.

\$\endgroup\$
1
\$\begingroup\$

I'd look into spring systems first before diving straight into fluid dynamics. They can help building a somewhat stable cell structure, and you can visualize this with normal effort (e.g. using alpha-blended particles, iso-lines, image-based effects on top of convex hulls etc..)

Fluid dynamics and final-element simulations are of course much more realistic and when combined with marching cubes or squares or ray-marching, they can give stunning visuals. It also comes with sufficient complexity that will keep you entertained for quite a bit.

The trick with fluids is that you need cohesion factors for different types of fluids or objects, so that you can update the characteristics of the 'eaten' bits when enclosed by another fluid. To test whether a point is complete enclosed in 2D, you can build convex hulls for the enclosing fluid and then test each object if it is in the hull or not. Check Melkman's algorithm for a fast incremental implementation. The same works in 3D, though you probably will want to switch to voxels.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.