2
\$\begingroup\$

Currently my game needs a top ocean view. Can this ocean effect done using box2d? or should I dive into write my own physics (liquid/water simulation). Ideas and suggestions are welcome.

\$\endgroup\$
1
  • \$\begingroup\$ Can you provide a sample (reference) what you are trying to achieve? \$\endgroup\$ – Felsir Sep 30 '16 at 10:52
3
\$\begingroup\$

Water physics and graphics are two completely different concepts. It is unclear which one you are asking about, so I'll consider both.

Physics

To simulate top-down objects you have to set the gravity in your physics engine to [0, 0] and manually apply forces for movement. The rest depends on your goals.

You probably want to have wind/waves in your game that affect objects' movement. For "global" force, which affects the whole map, you could actually use the engine's gravity (set it to a desired value instead of [0, 0]) and have this force applied automatically to all your objects on every tick.

To have different wind/waves in different parts of the map, a more sophisticated approach is required (e.g. keep a low-resolution map of wind vectors over your game field and manually apply the forces by looping through all floating objects). For sailing ships you could take into account things like sail direction relative to the wind, so that the wind affects a ship stronger the more perpendicular it is to the sail and the bigger the sail is (just take a dot product of wind force vector and a perpendicular to a vector representing the ship's sail).

You may want to simulate water drag, otherwise your objects will preserve their velocities indefinitely until changed by some other force (wind, user input, etc). You can use Box2d's linearDamping property on your bodies and easily get constant damping for any object, or, again, do it manually to achieve more accurate results. A nice approximation for drag is

Fdrag = -x * (0.1v + 0.01v2)

where x is your object's width perpendicular to the movement direction and v is its velocity (relative to the water's velocity, if you want that kind of accuracy). You should tweak the 0.1 and 0.01 coefficients to better suit your application.

Graphics

The easiest way to draw water in top-down 2d is to make a water tile and fill the whole water surface with it. It is possible to generate the water texture procedurally (you can use caustics generation algorithm, e.g. the one from this GPU Gems article; noise generation algorithms like Perlin/Simplex Noise can also come in handy). General techniques for tiles apply, so you can use multiple layers (one layer with tiled water texture, another layer for waves, etc) or choose tiles randomly. If your water is of different colors/textures in different places, you can blend between them by applying a blending mask.

A nice trick can be found in this article by twolivesleft. They make an animated texture where each frame is seamlessly tileable with every other frame (total of 16 frames in their case). They then arrange 16 tiles in a 4x4 square, initialize each at random frame and start animating. It looks consistent (due to all frames being tileable with each other) and not repetitive (animations are same, but they start at different frames). This square can then be used to tile your whole water surface.

You could also write a shader that combines your water tiles with an animated normal map.

These are just some techniques off the top of my head, though for many applications this is enough. Of course, there are many more.

\$\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.