开发者

2D grid water/liquid simulation (platformer tile based)

I have a grid based game (platformer) where I've based everything on tiles. I have tiles that are solid and liquid. I'm trying to find of a good way to make water tiles simulate water in a rough way.

At the moment I have the current system: When a water tile is added above another water tile, it adds 1 to the water tile below. The number indicates the pressure.

Here's how it looks like at the moment:

[0]   <- This water tile has 0 in pressure.
[1]   <- This water tile has 1 in pressure.

if I add another water tile next to the bottom one, it searches from left, right and above if there are any water tiles and inheritates the biggest pressure around it.

Example:

[0]
[1][1]

And here's a bigger example after adding few water tiles:

[0][0]
[1][1][1][1]
[2][2][2][2][2]

Then I make every water tile that has pressure that is equal or bigger than 1 try to move left/right if there's free space, then set pressure to 0 and check if it can inheritate pressure around itself from neighbor water tiles if there are any.

This system works very well,开发者_高级运维 except for the case when water tiles are removed from the top.

If I remove the top water tiles from the last example:

[1][1][1][1]
[2][2][2][2][2] 

Then we have the top row with pressure 1, it should have 0 there now and the bottom row should have 1.

Is there some smarter system I can implement to do this more proper?

The following are the restrictions:

Each tile can only check its neighbors tiles. Tile can have any function defined. Tile can have any variable to store data.

Can you guys come up with a better system that works better than mine?

The usual test case I do is:

[]
[] should become [][]

[]
[]
[] should become [][][]

  []
[][][] should become [][][][]

Assuming the game runs for a while.

Any suggestions would be more than welcome!


Maybe you could forget about pressures (since you are not really using them as pressures) and simply use a bool tryMove or something like that.

Each simulation step should be broken in two substeps:

First loop in tiles:

  1. If space below is free, set tryMove to true, finish this tile.
  2. If has tile above, set tryMove to true else set tryMove to false.
  3. If any neighbor is trying to move, set tryMove to true.

Second loop in tiles:

  1. If trying to move and space below is free, move tile down, set tryMove to false, finish tile.
  2. If trying to move and can move sideways (free space to left or right) set neighbors tryMove as false, move it, set this tryMove as false, finish tile.

I think this should fix your issue.


If you have the resources to support it, I recommend a recursive function that tries pushing tiles left and right from above. If the function finds another tile below, it can try displacing that tile to either side. The best method would be to start stepping left and right, one tile at a time. If it keeps finding water tiles, then it keeps going. Eventually it will either run out of tiles to check (ends up at a wall) or will find a water tile with free space to move over. After multiple iterations, the water should push outward and make room for the higher water to fall down.

Let me reclarify the left then right nature of the recursion. Essentially, once the function makes it to the base level of the water, it should start choosing water tiles, alternating left and right. So it will first check the tile directly left, then directly right, then two left, then two right, etc. If it finds an air tile, it should do a displacement of the nearest water tile. If it finds something else (usually a wall) it should give up on that side. Once it's given up on both sides, you should consider other behaviors instead, such as the topmost water randomly traveling around over the surface.

If you really want the behavior to seem natural, I highly recommend a random variable deciding whether it checks left or right first. Otherwise you will probably end up with strangely regular recurring patterns.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜