私は2Dタイルベースの水をゲームに実装しようとしています。タイルを画面などに表示することから始めました。各タイルタイプを描画する描画機能があります。私が抱えている問題は、この関数を呼び出すと、水であるタイルの位置が変わらないことです。これは、このコードが正しく機能していないと私に信じさせます。このコードはすべてのループで呼び出されます。これにより、すべての水タイルの質量が更新されます。なんらかの理由で何も起きていません。水は元の位置にとどまっています。私のタイルはタイルクラスのベクトルにあります
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;
}
}