In order to deactivate and activate chunks, I check each of their cells for movement; if there are no moving objects in this chunk, then I turn it off. However, for some reason unknown to me, the chunks turn off on their own. Help solve the problem.
Chunk code
internal class OptimizationSystem
{
private const byte CHUNK_SIZE = 8;
private const byte MAP_HEIGHT = 25;
private const byte MAP_WIDTH = 40;
private ParticleSystem particleSystem;
public struct Chunk
{
private int posX, posY;
public int PosX { get { return posX; } set { posX = value; } }
public int PosY { get { return posY; } set { posY = value; } }
public Chunk(int x, int y)
{
posX = x;
posY = y;
}
}
private Chunk[,] chunks = new Chunk[MAP_HEIGHT, MAP_WIDTH];
public List<Chunk> activeChunks = new List<Chunk>();
private List<Chunk> deactivatingChunks = new List<Chunk>();
public OptimizationSystem()
{
for (int x = 0; x < MAP_WIDTH; x++)
{
for (int y = 0; y < MAP_HEIGHT; y++)
{
chunks[y, x] = new Chunk(x, y);
activeChunks.Add(chunks[y, x]);
}
}
}
public void LoadParticleSystem(ParticleSystem particleSystem)
{
this.particleSystem = particleSystem;
}
public void UpdateChunks(uint frameCount)
{
bool frameCountEven = frameCount % 2 == 0;
for (int i = 0; i < activeChunks.Count; i++)
{
bool willDeactivate = true;
//Checking chunk for inactive tiles. If all tiles is inactive chunk will be deactivated
for (int y = ((activeChunks[i].PosY + 1) * CHUNK_SIZE) - 1; y >= activeChunks[i].PosY * CHUNK_SIZE; y--)
{
for (int x = activeChunks[i].PosX * CHUNK_SIZE; x < (activeChunks[i].PosX + 1) * CHUNK_SIZE; x++)
{
if (particleSystem.GetTileAt(x, y).IsMoving)
{
willDeactivate = false;
break;
}
if (!willDeactivate)
{
break;
}
}
}
////////////////////////////////////////////////////////////////////////////////////////
if (willDeactivate)
{
if (!deactivatingChunks.Contains(activeChunks[i]))
{
deactivatingChunks.Add(activeChunks[i]);
}
}
else
{
for (int y = ((activeChunks[i].PosY + 1) * CHUNK_SIZE) - 1; y >= activeChunks[i].PosY * CHUNK_SIZE; y--)
{
for (int x = frameCountEven ? activeChunks[i].PosX * CHUNK_SIZE : (activeChunks[i].PosX + 1) * CHUNK_SIZE - 1; frameCountEven ? x < (activeChunks[i].PosX + 1) * CHUNK_SIZE : x >= activeChunks[i].PosX * CHUNK_SIZE; x += frameCountEven ? 1 : -1)
{
particleSystem.UpdateTile(x, y, false);
}
}
}
}
}
public void DeactivateChunks()
{
if (deactivatingChunks.Count > 0)
{
foreach (Chunk chunk in deactivatingChunks)
{
activeChunks.Remove(chunk);
}
}
deactivatingChunks.Clear();
}
public void ActivateChunk(int x, int y)
{
double curX = x / CHUNK_SIZE;
double curY = y / CHUNK_SIZE;
if (!activeChunks.Contains(chunks[(int)Math.Floor(curY), (int)Math.Floor(curX)]))
{
activeChunks.Add(chunks[(int)Math.Floor(curY), (int)Math.Floor(curX)]);
}
}
public Chunk GetChunkAt(int x, int y)
{
double curX = x / CHUNK_SIZE;
double curY = y / CHUNK_SIZE;
return chunks[(int)curY, (int)curX];
}
public ushort GetMapWidth()
{
return CHUNK_SIZE * MAP_WIDTH;
}
public ushort GetMapHeight()
{
return CHUNK_SIZE * MAP_HEIGHT;
}
}
Code for tiles
public bool UpdateTile(int x, int y, bool fromUpToDown)
{
Particle curParticle = particleMap[y, x];
bool isFirstCheckLeft = rnd.Next(0, 101) >= 50 ? true : false;
if (curParticle == pSand)
{
int distance = rnd.Next(1, 50);
if (IsTileFree(x, y + 1))
{
particleMap[y, x].IsMoving = true;
MoveTile(x, y, x, y + rnd.Next(1, 50), pSand);
}
else if (isFirstCheckLeft)
{
if (IsTileFree(x - 1, y + 1))
{
particleMap[y, x] = pEmpty;
MoveTile(x - 1, y + 1, x - distance, y + 1, pSand);
}
else if (IsTileFree(x + 1, y + 1))
{
particleMap[y, x] = pEmpty;
MoveTile(x + 1, y + 1, x + distance, y + 1, pSand);
}
else
{
particleMap[y, x].IsMoving = false;
}
}
else
{
if (IsTileFree(x + 1, y + 1))
{
particleMap[y, x] = pEmpty;
MoveTile(x + 1, y + 1, x + distance, y + 1, pSand);
}
else if (IsTileFree(x - 1, y + 1))
{
particleMap[y, x] = pEmpty;
MoveTile(x - 1, y + 1, x - distance, y + 1, pSand);
}
else
{
particleMap[y, x].IsMoving = false;
}
}
}
return particleMap[y, x].IsMoving;
}
private Random rnd = new Random();
//Map setup
private OptimizationSystem optimizationSystem;
private Particle[,] particleMap;
//---------
//Defining particles and their ID's
public enum ParticleType { SOLID, LIQUID, GAS, PHYS_SOLID };
public struct Particle
{
private ushort id;
private int minFriability;
private int maxFriability;
private bool isMoving;
private ParticleType type;
//private Color color;
public ushort ID { get { return id; } set { id = value; } }
public int MinFriability { get { return minFriability; } }
public int MaxFriability { get { return maxFriability; } }
public bool IsMoving { get { return isMoving; } set { isMoving = value; } }
public byte r, g, b;
public Particle(ushort id, int minFriability, int maxFriability, bool isMoving, byte r, byte g, byte b, ParticleType type)
{
this.id = id;
this.minFriability = minFriability;
this.maxFriability = maxFriability;
this.isMoving = isMoving;
this.type = type;
this.r = r;
this.g = g;
this.b = b;
}
public static bool operator ==(Particle particle1, Particle particle2)
{
return particle1.id == particle2.id;
}
public static bool operator !=(Particle particle1, Particle particle2)
{
return !(particle1.id == particle2.id);
}
}
public Particle pEmpty = new Particle(0, 0, 0, false, 0, 0, 0, ParticleType.SOLID);
public Particle pSand = new Particle(1, 150, 7000, true, 200, 200, 0, ParticleType.PHYS_SOLID);
//--------------------------------
public void LoadOptimizationSystemAndMap(OptimizationSystem optimizationSystem)
{
this.optimizationSystem = optimizationSystem;
particleMap = new Particle[optimizationSystem.GetMapHeight(), optimizationSystem.GetMapWidth()];
for (uint x = 0; x < optimizationSystem.GetMapWidth(); x++)
{
for (uint y = 0; y < optimizationSystem.GetMapHeight(); y++)
{
particleMap[y, x] = pEmpty;
}
}
}
//Basic operations with particles
public Particle GetTileAt(int x, int y)
{
if (InBounds(x, y))
{
return particleMap[y, x];
}
return pEmpty;
}
public bool InBounds(int x, int y)
{
return x >= 0 && y >= 0 && y < optimizationSystem.GetMapHeight() && x < optimizationSystem.GetMapWidth();
}
public bool IsTileFree(int x, int y)
{
return InBounds(x, y) && particleMap[y, x] == pEmpty;
}
public void MoveTile(int fromX, int fromY, int toX, int toY, Particle particle)
{
int moveX = 0;
int moveY = 0;
bool fromXisLessThanToX = fromX <= toX;
bool fromYisLessThanToY = fromY <= toY;
/*if (fromX != toX && fromY != toY)
{
int distanceX = Math.Abs(toX - fromX);
int distanceY = Math.Abs(toY - fromY);
bool distanceYisLessOrEvenThanDistanceX = distanceX >= distanceY;
float slope = distanceYisLessOrEvenThanDistanceX ? Math.Abs((toY - fromY) / (toX - fromX)) : Math.Abs((toX - fromX) / (toY - fromY));
if (distanceYisLessOrEvenThanDistanceX)
{
moveY = fromYisLessThanToY ? 1 : -1;
for (int x = fromXisLessThanToX ? fromX + 1 : fromX - 1; fromXisLessThanToX ? x <= toX : x >= toX; x = fromXisLessThanToX ? x + 1 : x - 1)
{
int slopeY = (int)(x * slope);
if (IsTileFree(fromXisLessThanToX ? x + 1 : x - 1, slopeY))
{
moveX += fromXisLessThanToX ? 1 : -1;
moveY = slopeY;
}
else
{
break;
}
}
}
else
{
moveX = fromXisLessThanToX ? 1 : -1;
for (int y = fromYisLessThanToY ? fromY + 1 : fromY - 1; fromYisLessThanToY ? y <= toY : y >= toY; y += fromYisLessThanToY ? y + 1 : y - 1)
{
int slopeX = (int)(y * slope);
if (IsTileFree(slopeX, fromYisLessThanToY ? y + 1 : y - 1))
{
moveY += fromYisLessThanToY ? 1 : -1;
moveX = slopeX;
}
else
{
break;
}
}
}
}*/
if (fromY != toY)
{
for (int y = fromY; fromYisLessThanToY ? y < toY : y > toY; y += fromYisLessThanToY ? 1 : -1)
{
if (IsTileFree(fromX, fromYisLessThanToY ? y + 1 : y - 1))
{
moveY += fromYisLessThanToY ? 1 : -1;
optimizationSystem.ActivateChunk(fromX + moveX, fromY + moveY);
}
else
{
break;
}
}
}
else if (fromX != toX)
{
for (int x = fromX; fromXisLessThanToX ? x < toX : x > toX; x += fromXisLessThanToX ? 1 : -1)
{
if (IsTileFree(fromXisLessThanToX ? x + 1 : x - 1, fromY))
{
moveX += fromXisLessThanToX ? 1 : -1;
optimizationSystem.ActivateChunk(fromX + moveX, fromY + moveY);
}
else
{
break;
}
}
}
if (IsTileFree(fromX + moveX, fromY + moveY))
{
particleMap[fromY, fromX] = pEmpty;
particleMap[fromY + moveY, fromX + moveX] = particle;
}
if (InBounds(fromX + moveX, fromY + moveY))
{
optimizationSystem.ActivateChunk(fromX + moveX, fromY + moveY);
}
}
//--------------------------------
I wanted that when a particle enters the chunk's field, it "activates" it, and the chunk is processed.