Chunks not working in my project, some chunks don`t activating in time

33 views Asked by At

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);
            }

        }
        //--------------------------------

How it looks

I wanted that when a particle enters the chunk's field, it "activates" it, and the chunk is processed.

0

There are 0 answers