I have been trying to implement 2D tile based water into my game. I started out making the tiles appear on screen etc. I have a drawing function that draws each tile type. The problem I'm having is that when I call this function the Tiles that are water don't change position. Which makes me believe that this code isn't functioning properly. This code is called on every loop. This should update the masses of all the water tiles. For some reason nothing is happening. The water is staying in its original positions. My tiles are in a vector of the tile class is just
Tiles()
{
TileProp // the type of tile (GROUND,AIR,WATER)
Mass
NewMass
}
void App::SimulateCompression()
{
float Flow = 0;
float remainingmass = 0;
int ID = 0;
//Calculate and apply flow for each block
for (int X = 0; X < MAP_WIDTH; X++)
{
for(int Y = 0; Y < MAP_HEIGHT; Y++)
{
//Skip inert ground blocks
if(TileList[ID].TileProp == TILE_GROUND) continue;
//Custom push-only flow
Flow = 0;
remainingmass = TileList[ID].Mass;
if(remainingmass <= 0) continue;
//The block below this one
if(TileList[Rect2Lin(TILE_SIZE,X,(Y-1))].TileProp != TILE_GROUND)
{
Flow = GetStableWaterState(remainingmass + TileList[Rect2Lin(TILE_SIZE,X,(Y-1))].Mass /*mass[x][y-1]*/) - TileList[Rect2Lin(TILE_SIZE,X,(Y-1))].Mass;
if(Flow > MinFlow){Flow *= 0.5; /*leads to smoother flow*/}
int tempA = Min(MaxSpeed, remainingmass);
if(Flow > tempA){Flow = tempA;}
if(Flow < 0){Flow = 0;}
TileList[ID].NewMass -= Flow;
TileList[Rect2Lin(TILE_SIZE,X,(Y-1))].NewMass += Flow;
remainingmass -= Flow;
}
if(remainingmass <= 0) continue;
//Left
if(TileList[Rect2Lin(TILE_SIZE,(X - 1),Y)].TileProp != TILE_GROUND)
{
//Equalize the amount of water in this block and it's neighbour
Flow = (TileList[ID].Mass - TileList[Rect2Lin(TILE_SIZE,(X - 1),Y)].Mass)/4;
if(Flow > MinFlow){Flow *= 0.5;}
if(Flow > remainingmass){Flow = remainingmass;}
if(Flow < 0){Flow = 0;}
TileList[ID].NewMass -= Flow;
TileList[Rect2Lin(TILE_SIZE,(X - 1),Y)].NewMass += Flow;
remainingmass -= Flow;
}
if(remainingmass <= 0) continue;
//Right
if(TileList[Rect2Lin(TILE_SIZE,(X + 1),Y)].TileProp != TILE_GROUND)
{
//Equalize the amount of water in this block and it's neighbour
Flow = (TileList[ID].Mass - TileList[Rect2Lin(TILE_SIZE,(X + 1),Y)].Mass)/4;
if(Flow > MinFlow){Flow *= 0.5;}
if(Flow > remainingmass){Flow = remainingmass;}
if(Flow < 0){Flow = 0;}
TileList[ID].NewMass -= Flow;
TileList[Rect2Lin(TILE_SIZE,(X + 1),Y)].NewMass += Flow;
remainingmass -= Flow;
}
if(remainingmass <= 0) continue;
//Up. Only compressed water flows upwards
if(TileList[Rect2Lin(TILE_SIZE,X,(Y + 1))].TileProp != TILE_GROUND)
{
Flow = remainingmass - GetStableWaterState(remainingmass + TileList[Rect2Lin(TILE_SIZE,X,(Y + 1))].Mass);
if (Flow > MinFlow){Flow *= 0.5;}
int tempB = Min(MaxSpeed, remainingmass);
if(Flow > tempB){Flow = tempB;}
if(Flow < 0){Flow = 0;}
TileList[ID].NewMass -= Flow;
TileList[Rect2Lin(TILE_SIZE,X,(Y + 1))].NewMass += Flow;
remainingmass -= Flow;
}
ID++;
}
}
ID = 0;
//Copy the new mass values
for (int X = 0; X < MAP_WIDTH; X++)
{
for (int Y = 0; Y < MAP_HEIGHT; Y++)
{
TileList[ID].Mass = TileList[ID].NewMass;
ID++;
}
}
ID = 0;
for(int X = 0; X < MAP_WIDTH; X++)
{
for(int Y = 0; Y < MAP_HEIGHT; Y++)
{
//Skip ground blocks
if(TileList[ID].TileProp == TILE_GROUND) continue;
//Flag/unflag water blocks
if(TileList[ID].Mass > MinMass)
{
TileList[ID].TileProp = TILE_WATER;
}else
{
TileList[ID].TileProp = TILE_AIR;
}
ID++;
}
}
//Remove any water that has left the map
for(int X = 0; X < MAP_WIDTH; X++)
{
TileList[X].Mass = 0;
TileList[Rect2Lin(TILE_SIZE,X,MAP_HEIGHT - 1)].Mass = 0;
}
for(int Y = 0; Y < MAP_HEIGHT; Y++)
{
TileList[Rect2Lin(TILE_SIZE,0,Y)].Mass = 0;
TileList[Rect2Lin(TILE_SIZE,(MAP_WIDTH - 1),Y)].Mass = 0;
}
}