Пример #1
0
 public EntityGhost(BoundingBox box, Vector2 position, SurfaceContainer surface)
 {
     this.position      = position;
     this.collisionBox  = box;
     this.collisionMask = CollisionLayer.TerrainSolid | CollisionLayer.EntityPhysical;
     this.surface       = surface;
 }
Пример #2
0
 public void GeneratePollutionVertexArray(SurfaceContainer surface, Vector2 position, int xRange, int yRange, VertexArray vA)
 {
     int[] chunkIndices = SurfaceContainer.WorldToChunkCoords(position);
     vA.Clear();
     for (int i = chunkIndices[0] - xRange; i <= chunkIndices[0] + xRange; i++)
     {
         for (int j = chunkIndices[1] - yRange; j <= chunkIndices[1] + yRange; j++)
         {
             byte  val     = Convert.ToByte(surface.GetInterpolatedPollution(i, j) * 255 / Props.maxPollution);
             Color topLeft = new Color(val, 0, 0, (byte)(val / 2));
             val = Convert.ToByte(surface.GetInterpolatedPollution(i + 1, j) * 255 / Props.maxPollution);
             Color topRight = new Color(val, 0, 0, (byte)(val / 2));
             val = Convert.ToByte(surface.GetInterpolatedPollution(i, j + 1) * 255 / Props.maxPollution);
             Color botLeft = new Color(val, 0, 0, (byte)(val / 2));
             val = Convert.ToByte(surface.GetInterpolatedPollution(i + 1, j + 1) * 255 / Props.maxPollution);
             Color botRight = new Color(val, 0, 0, (byte)(val / 2));
             int   oX       = i * Props.chunkSize;
             int   oY       = j * Props.chunkSize;
             vA.Append(new Vertex(new Vector2f(oX, oY), topLeft));
             vA.Append(new Vertex(new Vector2f(oX + Props.chunkSize, oY), topRight));
             vA.Append(new Vertex(new Vector2f(oX, oY + Props.chunkSize), botLeft));
             vA.Append(new Vertex(new Vector2f(oX + Props.chunkSize, oY), topRight));
             vA.Append(new Vertex(new Vector2f(oX + Props.chunkSize, oY + Props.chunkSize), botRight));
             vA.Append(new Vertex(new Vector2f(oX, oY + Props.chunkSize), botLeft));
         }
     }
 }
Пример #3
0
        /// <summary>
        /// Generates the entities to be placed into a chunk
        /// </summary>
        /// <param name="chunkX"></param>
        /// <param name="chunkY"></param>
        /// <param name="surface"></param>
        public void GenerateEntities(int chunkX, int chunkY, SurfaceContainer surface)
        {
            Vector2 chunkPos = new Vector2(chunkX * Props.chunkSize * Props.tileSize, chunkY * Props.chunkSize * Props.tileSize);

            for (int i = 0; i < entitiesGenerated.Count; i++)
            {
                Vector2[] poissonDiscDistribution = PoissonDiscDistribution.GetDistribution(entitiesGenerated[i].density, (chunkX * (surfaceSize / Props.chunkSize) + chunkY) + seed, 10);
                for (int j = 0; j < poissonDiscDistribution.Length; j++)
                {
                    Vector2 curPos    = poissonDiscDistribution[j].VAdd(chunkPos);
                    int     nx        = (int)(curPos.x) / Props.tileSize;
                    int     ny        = (int)(curPos.y) / Props.tileSize;
                    double  elevation = 0.5 * elevationNoise.GetNoise(1 * nx, 1 * ny)
                                        + 0.25 * elevationNoise.GetNoise(2 * nx, 2 * ny)
                                        + 0.25 * elevationNoise.GetNoise(4 * nx, 4 * ny);
                    double moisture = 0.5 * moistureNoise.GetNoise(1 * nx, 1 * ny)
                                      + 0.25 * moistureNoise.GetNoise(2 * nx, 2 * ny)
                                      + 0.25 * moistureNoise.GetNoise(4 * nx, 4 * ny);
                    double temperature = 0.5 * temperatureNoise.GetNoise(1 * nx, 1 * ny)
                                         + 0.25 * temperatureNoise.GetNoise(2 * nx, 2 * ny)
                                         + 0.25 * temperatureNoise.GetNoise(4 * nx, 4 * ny);
                    elevation   = 3 * Math.Pow(elevation, elevationFactor);
                    moisture    = 3 * Math.Pow(moisture, moistureFactor);
                    temperature = 3 * Math.Pow(temperature, temperatureFactor);

                    float lowestAffinity  = 2;
                    int   lowestPrototype = 0;

                    for (int k = 0; k < entitiesGenerated[i].prototypeVars.Length; k++)
                    {
                        float entityProb = (float)(Math.Abs(entitiesGenerated[i].elevationAffinities[k] - elevation) +
                                                   Math.Abs(entitiesGenerated[i].moistureAffinities[k] - moisture) +
                                                   Math.Abs(entitiesGenerated[i].temperatureAffinities[k] - temperature));
                        if (entityProb < lowestAffinity)
                        {
                            lowestAffinity  = entityProb;
                            lowestPrototype = k;
                        }
                    }
                    float moistureDiff    = (float)(Math.Abs(entitiesGenerated[i].moistureAffinities[lowestPrototype] - moisture));
                    float elevationDiff   = (float)(Math.Abs(entitiesGenerated[i].elevationAffinities[lowestPrototype] - elevation));
                    float temperatureDiff = (float)(Math.Abs(entitiesGenerated[i].temperatureAffinities[lowestPrototype] - temperature));
                    if (entitiesGenerated[i].moistureRange[lowestPrototype % entitiesGenerated[i].prototypeCount] > elevationDiff &&
                        entitiesGenerated[i].temperatureRange[lowestPrototype % entitiesGenerated[i].prototypeCount] > temperatureDiff &&
                        entitiesGenerated[i].elevationRange[lowestPrototype % entitiesGenerated[i].prototypeCount] > moistureDiff)
                    {
                        Entity prototype = entityCollection.GetPrototype(entitiesGenerated[i].prototypeVars[lowestPrototype]);
                        if (prototype.tileAligned)
                        {
                            curPos = new Vector2(curPos.x - curPos.x % 32 + 16, curPos.y - curPos.y % 32 + 16);
                        }
                        if (prototype != null && !BoundingBox.CheckForPlacementCollision(prototype.collisionBox, curPos, surface, entitiesGenerated[i].placementMask))
                        {
                            entityCollection.InstantiatePrototype(prototype.name, curPos, surface);
                        }
                    }
                }
            }
        }
Пример #4
0
 public LightSourceRadial(SurfaceContainer surface, float lightRange, Texture texture, IntRect bounds)
 {
     this.texture = texture;
     this.bounds  = bounds;
     this.surface = surface;
     lightScale   = new Vector2f(lightRange / bounds.Width, lightRange / bounds.Height);
     origin       = new Vector2f(bounds.Width / 2, bounds.Height / 2);
 }
Пример #5
0
 public LightSourceRadial(SurfaceContainer surface, Vector2f lightScale, Texture texture, IntRect bounds)
 {
     this.texture    = texture;
     this.bounds     = bounds;
     this.surface    = surface;
     this.lightScale = lightScale;
     origin          = new Vector2f(bounds.Width / 2, bounds.Height / 2);
 }
Пример #6
0
 public void Update()
 {
     if (focusedEntity != null)
     {
         gameView.Center   = new Vector2f(focusedEntity.position.x, focusedEntity.position.y);
         viewedSurface     = focusedEntity.surface;
         Listener.Position = new Vector3f(gameView.Center.X, 0.0f, gameView.Center.Y);
     }
 }
Пример #7
0
 public void CheckCullVertexCache(Camera camera, SurfaceContainer surface)
 {
     if (cullCounter > cullRate)
     {
         CullVertexCache(camera, surface);
         cullCounter = 0;
     }
     modifiedVertexArrays = false;
 }
Пример #8
0
 public LightSourceDirectional(SurfaceContainer surface, Vector2f lightScale, Texture texture, IntRect bounds)
 {
     this.texture    = texture;
     this.bounds     = bounds;
     this.surface    = surface;
     this.rotation   = 0.0f;
     this.lightScale = new Vector2f(lightScale.X, lightScale.Y);
     this.origin     = new Vector2f(bounds.Width / 2, bounds.Height);
 }
Пример #9
0
 public LightSourceDirectional(SurfaceContainer surface, float lightRange, float lightWidth, Texture texture, IntRect bounds)
 {
     this.texture  = texture;
     this.bounds   = bounds;
     this.surface  = surface;
     this.rotation = 0.0f;
     lightScale    = new Vector2f(lightWidth / bounds.Width, lightRange / bounds.Height);
     origin        = new Vector2f(bounds.Width / 2, bounds.Height);
 }
Пример #10
0
        public override void InitializeEntity(Vector2 position, SurfaceContainer surface)
        {
            base.InitializeEntity(position, surface);
            IntRect bounds;

            radialLight                     = new LightSourceRadial(surface, 256.0f, textureAtlases.GetTexture("lightsource", out bounds), bounds);
            radialLight.on                  = true;
            radialLight.attachedEntity      = this;
            directionalLight                = new LightSourceDirectional(surface, 2000.0f, 1024, textureAtlases.GetTexture("directionallight", out bounds), bounds);
            directionalLight.on             = true;
            directionalLight.attachedEntity = this;
        }
Пример #11
0
 public void FinalizeGame()
 {
     //Pop all menus
     menuContainer.RemoveAllMenus();
     player = null;
     camera.DetachEntity();
     camera.viewedSurface = null;
     surfaceContainer     = null;
     input.ClearGameSubscribers();
     renderer.DetachGameWorld();
     StaticSoundManager.StopAmbience();
     entityUpdateSystem.ResetSystem();
 }
Пример #12
0
        /// <summary>
        /// Gets minimap textures for a specified surface.  The position is the centered location. The range is the number of chunks x/y away from center to get.
        /// </summary>
        /// <param name="surface"></param>
        /// <param name="position"></param>
        /// <param name="ranges"></param>
        public void GenerateMinimapTextures(SurfaceContainer surface, Vector2 position, int xRange, int yRange, List <VertexArray> vertexArrays)
        {
            int[] chunkIndices = SurfaceContainer.WorldToChunkCoords(position);
            vertexArrays.Clear();
            for (int i = chunkIndices[0] - xRange; i <= chunkIndices[0] + xRange; i++)
            {
                for (int j = chunkIndices[1] - yRange; j <= chunkIndices[1] + yRange; j++)
                {
                    Chunk chunk = surface.GetChunk((i * surface.worldSize) + j, false);
                    if (chunk != null)
                    {
                        VertexArray vA;
                        if (!minimapVertexArrays.TryGetValue(i * surface.worldSize + j, out vA))
                        {
                            vA = tileCollection.GenerateTerrainMinimap(chunk, (i * surface.worldSize) + j, surface.worldSize);
                            minimapVertexArrays.Add(i * surface.worldSize + j, vA);
                        }
                        vertexArrays.Add(vA);
                        //next get entities
                        //This is very dynamic so there is no point caching it
                        List <Entity> entityList  = chunk.entityList;
                        VertexArray   entityArray = new VertexArray(PrimitiveType.Triangles);
                        int           oX          = i * Props.chunkSize;
                        int           oY          = j * Props.chunkSize;
                        for (int l = 0; l < entityList.Count; l++)
                        {
                            EntityPhysical e = entityList[l] as EntityPhysical;
                            if (e == null)
                            {
                                continue;
                            }
                            int[] pos        = surface.WorldToAbsoluteTileCoords(e.position.x, e.position.y);
                            float halfWidth  = e.tileWidth;
                            float halfHeight = e.tileHeight;
                            entityArray.Append(new Vertex(new Vector2f(pos[0] - halfWidth, pos[1] - halfHeight), e.mapColor));
                            entityArray.Append(new Vertex(new Vector2f(pos[0] + halfWidth, pos[1] - halfHeight), e.mapColor));
                            entityArray.Append(new Vertex(new Vector2f(pos[0] - halfWidth, pos[1] + halfHeight), e.mapColor));

                            entityArray.Append(new Vertex(new Vector2f(pos[0] + halfWidth, pos[1] - halfHeight), e.mapColor));
                            entityArray.Append(new Vertex(new Vector2f(pos[0] + halfWidth, pos[1] + halfHeight), e.mapColor));
                            entityArray.Append(new Vertex(new Vector2f(pos[0] - halfWidth, pos[1] + halfHeight), e.mapColor));
                        }
                        if (entityArray.VertexCount > 0)
                        {
                            vertexArrays.Add(entityArray);
                        }
                    }
                }
            }
        }
Пример #13
0
        /// <summary>
        /// Instantiates an entity and subscribes it to updating
        /// </summary>
        /// <param name="name"></param>
        /// <param name="position"></param>
        /// <param name="surface"></param>
        /// <returns></returns>
        public Entity InstantiatePrototype(string name, Vector2 position, SurfaceContainer surface)
        {
            Entity prototype;

            if (entityPrototypes.TryGetValue(name, out prototype))
            {
                Entity newEntity = prototype.Clone();
                //Initialize the Entity
                newEntity.InitializeEntity(position, surface);
                //Add to update system
                entityUpdateSystem.AddEntity(newEntity);
                return(newEntity);
            }
            return(null);
        }
Пример #14
0
 public void InitializeGame()
 {
     //Pop all menus
     menuContainer.RemoveAllMenus();
     //Game systems intialization
     surfaceContainer = new SurfaceContainer(tileCollection, surfaceGenerator);
     renderer.InitializeForGame(tileCollection);
     #region test entities
     surfaceContainer.GenerateStartingArea();
     player = entityCollection.InstantiatePrototype("player", surfaceContainer.spawnPoint, surfaceContainer);
     IInputSubscriber playerSubscriber = player as IInputSubscriber;
     if (playerSubscriber != null)
     {
         playerSubscriber.SubscribeToInput(input);
     }
     #endregion
     //Attaching the camera to something!
     camera.SetFocusedEntity(player, menuFactory);
     this.SubscribeToInput(input);
     renderer.SubscribeToInput(input);
 }
Пример #15
0
        /// <summary>
        /// Generates the bounding box vertex array for a terrain using the map colors of the tile.
        /// </summary>
        /// <param name="chunk"></param>
        /// <param name="chunkIndex"></param>
        /// <param name="pointsTile"></param>
        /// <returns></returns>
        public VertexArray GenerateTerrainBoundingBoxArray(SurfaceContainer surface, Chunk chunk, int chunkIndex, float[] pointsTile)
        {
            VertexArray vertexArray = new VertexArray(PrimitiveType.Lines);

            for (int k = 0; k < Props.chunkSize; k++)
            {
                for (int l = 0; l < Props.chunkSize; l++)
                {
                    Tile tile = GetTerrainTile(chunk.GetTile(k, l));
                    if ((tile.collisionMask & Base.CollisionLayer.TerrainSolid) != 0)
                    {
                        Vector2 position = surface.WorldToTileVector(chunkIndex, k * Props.chunkSize + l);
                        for (int x = 0; x < pointsTile.Length; x += 2)
                        {
                            vertexArray.Append(new Vertex(new Vector2f(pointsTile[x] + position.x, pointsTile[x + 1] + position.y), tile.mapColor));
                            vertexArray.Append(new Vertex(new Vector2f(pointsTile[(x + 2) % 8] + position.x, pointsTile[(x + 3) % 8] + position.y), tile.mapColor));
                        }
                    }
                }
            }
            return(vertexArray);
        }
Пример #16
0
        /// <summary>
        /// Gets the tiles the entity could possibly occupy in tile indices
        /// </summary>
        /// <param name="self"></param>
        /// <param name="posSelf"></param>
        /// <returns></returns>
        public static int[][] GetTileBounds(BoundingBox self, Vector2 posSelf)
        {
            float xMin = posSelf.x - self.radiusApproximation - Props.tileCollisionFactor * Props.tileSize;
            float xMax = posSelf.x + self.radiusApproximation + Props.tileCollisionFactor * Props.tileSize;
            float yMin = posSelf.y - self.radiusApproximation - Props.tileCollisionFactor * Props.tileSize;
            float yMax = posSelf.y + self.radiusApproximation + Props.tileCollisionFactor * Props.tileSize;

            int[] top    = SurfaceContainer.WorldToTileCoords(xMin, yMin);
            int[] bot    = SurfaceContainer.WorldToTileCoords(xMax, yMax);
            int   yRange = (bot[1] - top[1]) + 1;
            int   xRange = (bot[0] - top[0]) + 1;

            int[][] ret = new int[xRange * yRange][];
            int     x   = 0;

            for (int i = top[0]; i <= bot[0]; i++)
            {
                for (int j = top[1]; j <= bot[1]; j++)
                {
                    int tileXmin = i == top[0] ? top[2] : 0;
                    int tileXmax = i == bot[0] ? bot[2] + 1 : Props.chunkSize;
                    int tileYmin = j == top[1] ? top[3] : 0;
                    int tileYmax = j == bot[1] ? bot[3] + 1 : Props.chunkSize;
                    ret[x] = new int[(tileXmax - tileXmin) * (tileYmax - tileYmin)];
                    int y = 0;
                    for (int k = tileXmin; k < tileXmax; k++)
                    {
                        for (int l = tileYmin; l < tileYmax; l++)
                        {
                            ret[x][y] = k * Props.chunkSize + l;
                            y++;
                        }
                    }
                    x++;
                }
            }
            return(ret);
        }
Пример #17
0
 public void GenerateEntities(int x, int y, SurfaceGenerator surfaceGenerator, SurfaceContainer surface)
 {
     surfaceGenerator.GenerateEntities(x, y, surface);
 }
Пример #18
0
        public static List <TypeToTest> CheckSelectionOfType <TypeToTest>(Vector2 position, BoundingBox collisionBox, SurfaceContainer surface) where TypeToTest : Entity
        {
            //lists to keep track of collided entities
            List <TypeToTest> list = new List <TypeToTest>();

            //list of chunks where collisions may have happened + tiles
            int[]   chunkList = BoundingBox.GetChunkBounds(collisionBox, position, surface);
            int[][] tileList  = BoundingBox.GetTileBounds(collisionBox, position);
            for (int i = 0; i < chunkList.Length; i++)
            {
                Chunk chunk = surface.GetChunk(chunkList[i], false);
                if (chunk == null)
                {
                    continue;
                }
                //entity collision checks
                List <Entity> collisionList = chunk.entityCollisionList;
                for (int j = 0; j < collisionList.Count; j++)
                {
                    TypeToTest checkEntity = collisionList[j] as TypeToTest;
                    if (checkEntity != null &&
                        BoundingBox.CheckCollision(collisionBox, checkEntity.selectionBox, position, collisionList[j].position))
                    {
                        list.Add(checkEntity);
                    }
                }
            }
            return(list);
        }
Пример #19
0
        public static bool CheckForPlacementCollision(BoundingBox collisionBox, Vector2 position, SurfaceContainer surface, Base.CollisionLayer collisionMask)
        {
            int[]   chunkList = BoundingBox.GetChunkBounds(collisionBox, position, surface);
            int[][] tileList  = BoundingBox.GetTileBounds(collisionBox, position);
            for (int i = 0; i < chunkList.Length; i++)
            {
                Chunk chunk = surface.GetChunk(chunkList[i], false);
                if (chunk == null)
                {
                    continue;
                }
                //entity collision checks
                List <Entity> collisionList = chunk.entityCollisionList;
                for (int j = 0; j < collisionList.Count; j++)
                {
                    if ((collisionList[j].collisionMask & collisionMask) != 0)
                    {
                        if (BoundingBox.CheckCollision(collisionBox, collisionList[j].collisionBox, position, collisionList[j].position))
                        {
                            return(true);
                        }
                    }
                }

                //tile collision checks
                //Perhaps switch to continually checking whether the player is colliding with a tile at his position until he isnt colliding with a tile?
                //Would fix the situation where getting stuck in water still allows movement within
                //TODO: try solution outline above
                for (int j = 0; j < tileList[i].Length; j++)
                {
                    Tile tile = surface.tileCollection.GetTerrainTile(chunk.GetTile(tileList[i][j]));
                    if ((collisionMask & tile.collisionMask) != 0)
                    {
                        Vector2 tilePos = surface.WorldToTileVector(chunkList[i], tileList[i][j]);
                        if (BoundingBox.CheckCollision(collisionBox, surface.tileBox, position, tilePos))
                        {
                            return(true);
                        }
                    }
                }
            }
            return(false);
        }
Пример #20
0
        /// <summary>
        /// Gets the chunks the entity is possibly present in chunk indices
        /// </summary>
        /// <param name="self"></param>
        /// <param name="selfPos"></param>
        /// <returns></returns>
        public static int[] GetChunkBounds(BoundingBox self, Vector2 posSelf, SurfaceContainer surface)
        {
            float xMin = posSelf.x - self.radiusApproximation - Props.tileCollisionFactor * Props.tileSize;
            float xMax = posSelf.x + self.radiusApproximation + Props.tileCollisionFactor * Props.tileSize;
            float yMin = posSelf.y - self.radiusApproximation - Props.tileCollisionFactor * Props.tileSize;
            float yMax = posSelf.y + self.radiusApproximation + Props.tileCollisionFactor * Props.tileSize;

            int[] top    = surface.WorldToChunkCoords(xMin, yMin);
            int[] bot    = surface.WorldToChunkCoords(xMax, yMax);
            int   yRange = (bot[1] - top[1]) + 1;
            int   xRange = (bot[0] - top[0]) + 1;

            int[] ret = new int[xRange * yRange];
            int   k   = 0;

            for (int i = top[0]; i <= bot[0]; i++)
            {
                for (int j = top[1]; j <= bot[1]; j++)
                {
                    ret[k] = i * surface.worldSize + j;
                    k++;
                }
            }
            return(ret);

            #region more complex chunk bound code

            /*if(self.rotation == 0)
             * {
             *  int[] top = SurfaceContainer.WorldToChunkCoords(selfPos.x + self.topLeftR.x, selfPos.y + self.topLeftR.y);
             *  int[] bot = SurfaceContainer.WorldToChunkCoords(selfPos.x + self.botLeftR.y, selfPos.y + self.botLeftR.y);
             *  int yRange = (bot[1] - top[1]);
             *  int xRange = (bot[0] - top[0]);
             *  int[] ret = new int[xRange * yRange];
             *  int k = 0;
             *  for(int i = top[0]; i <= bot[0]; i++)
             *  {
             *      for(int j = top[1]; j <= bot[1]; j++)
             *      {
             *          ret[k] = i * Props.worldSize + j;
             *          k++;
             *      }
             *  }
             *  return ret;
             * }
             * int[][] coords = new int[4][];
             * coords[0] = SurfaceContainer.WorldToChunkCoords(selfPos.VAdd(self.topLeftR));
             * coords[1] = SurfaceContainer.WorldToChunkCoords(selfPos.VAdd(self.topRightR));
             * coords[2] = SurfaceContainer.WorldToChunkCoords(selfPos.VAdd(self.botLeftR));
             * coords[3] = SurfaceContainer.WorldToChunkCoords(selfPos.VAdd(self.botRightR));
             * int[] min = new int[] { coords[0][0], coords[0][1] };
             * int[] max = new int[] { coords[3][0], coords[3][1] };
             * for (int i = 0; i < 4; i++)
             * {
             *  if(coords[i][0] <= min[0])
             *  {
             *      min[0] = coords[i][0];
             *  }
             *  if(coords[i][0] >= max[0])
             *  {
             *      max[0] = coords[i][0];
             *  }
             *  if(coords[i][1] <= min[1])
             *  {
             *      min[1] = coords[i][1];
             *  }
             *  if(coords[i][1] >= max[1])
             *  {
             *      max[1] = coords[i][1];
             *  }
             * }*/
            #endregion more complex chunk bound code
        }
Пример #21
0
        /// <summary>
        /// Culls vertex arrays that are too far away based on camera variables.
        /// </summary>
        public void CullVertexCache(Camera camera, SurfaceContainer surface)
        {
            int[]      cameraChunkCoords = surface.WorldToChunkCoords(camera.GetGameView().Center.X, camera.GetGameView().Center.Y);
            List <int> keysToRemove      = new List <int>();

            foreach (int key in terrainVertexArrays.Keys)
            {
                int[] chunkIndices = surface.ChunkIndexToChunkCoords(key);
                if (Math.Abs(chunkIndices[0] - cameraChunkCoords[0]) > Props.vertexArrayCullingDistance ||
                    Math.Abs(chunkIndices[1] - cameraChunkCoords[1]) > Props.vertexArrayCullingDistance)
                {
                    keysToRemove.Add(key);
                }
            }
            foreach (int key in keysToRemove)
            {
                VertexArray[] vA;
                if (terrainVertexArrays.TryGetValue(key, out vA))
                {
                    foreach (VertexArray v in vA)
                    {
                        v.Dispose();
                    }
                }
                terrainVertexArrays.Remove(key);
            }
            keysToRemove.Clear();

            foreach (int key in tileBoundingBoxVertexArray.Keys)
            {
                int[] chunkIndices = surface.ChunkIndexToChunkCoords(key);
                if (Math.Abs(chunkIndices[0] - cameraChunkCoords[0]) > Props.vertexArrayCullingDistance ||
                    Math.Abs(chunkIndices[1] - cameraChunkCoords[1]) > Props.vertexArrayCullingDistance)
                {
                    keysToRemove.Add(key);
                }
            }
            foreach (int key in keysToRemove)
            {
                VertexArray vA;
                if (tileBoundingBoxVertexArray.TryGetValue(key, out vA))
                {
                    vA.Dispose();
                }
                tileBoundingBoxVertexArray.Remove(key);
            }
            keysToRemove.Clear();

            if (cullMinimap)
            {
                foreach (int key in minimapVertexArrays.Keys)
                {
                    int[] chunkIndices = surface.ChunkIndexToChunkCoords(key);
                    if (Math.Abs(chunkIndices[0] - cameraChunkCoords[0]) > Props.vertexArrayCullingDistance ||
                        Math.Abs(chunkIndices[1] - cameraChunkCoords[1]) > Props.vertexArrayCullingDistance)
                    {
                        keysToRemove.Add(key);
                    }
                }
                foreach (int key in keysToRemove)
                {
                    VertexArray vA;
                    if (minimapVertexArrays.TryGetValue(key, out vA))
                    {
                        vA.Dispose();
                    }
                    minimapVertexArrays.Remove(key);
                }
            }
        }
Пример #22
0
        public void RenderWorld(RenderWindow window, Camera camera, SurfaceContainer surface)
        {
            window.SetView(camera.GetGameView()); //Set view
            Vector2f origin = window.MapPixelToCoords(new Vector2i(0, 0), camera.GetGameView());
            Vector2f extent = window.MapPixelToCoords(new Vector2i((int)window.Size.X, (int)window.Size.Y), camera.GetGameView());

            int[] begPos = surface.WorldToChunkCoords(origin.X, origin.Y);
            int[] endPos = surface.WorldToChunkCoords(extent.X, extent.Y);
            windowBox = new BoundingBox(0, 0, extent.X - origin.X, extent.Y - origin.Y);
            #region terrain drawing
            for (int i = begPos[0]; i <= endPos[0]; i++)
            {
                for (int j = begPos[1]; j <= endPos[1]; j++)
                {
                    int key = (i) * surface.worldSize + j;
                    if (terrainVertexArrays.TryGetValue(key, out _) == false)
                    {
                        terrainVertexArrays.Add(key, tileCollection.GenerateTerrainVertices(surface, new int[] { i, j }));
                    }
                    VertexArray[] vArr;
                    if (terrainVertexArrays.TryGetValue(key, out vArr))
                    {
                        for (int k = 0; k < vArr.Length; k++)
                        {
                            window.Draw(vArr[k], terrainRenderStates[k]);
                        }
                    }
                }
            }
            #endregion terrain drawing

            #region entity drawing
            renderedEntityCount = 0;
            renderedSpriteCount = 0;
            for (int i = begPos[0]; i <= endPos[0] + 1; i++)
            {
                for (int j = begPos[1]; j <= endPos[1] + 1; j++)
                {
                    Chunk chunk = surface.GetChunk(i, j);
                    if (chunk == null)
                    {
                        continue;
                    }
                    List <Entity> entityList = chunk.entityList;
                    for (int k = 0; k < entityList.Count; k++)
                    {
                        if (entityList[k].drawArray != null && BoundingBox.CheckCollision(windowBox, entityList[k].drawingBox, new Vector2(origin), entityList[k].position))
                        {
                            drawList.Add(entityList[k]);
                        }
                    }
                }
            }
            drawList.Sort(delegate(Entity a, Entity b)
            {
                int ydiff = a.position.y.CompareTo(b.position.y);
                if (ydiff != 0)
                {
                    return(ydiff);
                }
                else
                {
                    return(a.position.x.CompareTo(b.position.x));
                }
            });
            for (int i = 0; i < entityBatch.Length; i++)
            {
                entityBatch[i].Initialize(camera.GetGameView(), Color.Transparent);
            }
            foreach (Entity e in drawList)
            {
                renderedEntityCount++;
                for (int i = 0; i < e.drawArray.Length; i++)
                {
                    if (e.drawArray[i].drawLayer != Drawable.DrawLayer.None)
                    {
                        e.drawArray[i].Draw(entityBatch[(int)e.drawArray[i].drawLayer - 1], e.position.internalVector);
                        renderedSpriteCount++;
                    }
                }
            }
            window.SetView(camera.GetGUIView());
            for (int i = 0; i < entityBatch.Length; i++)
            {
                Sprite sprite = entityBatch[i].Finalize();
                window.Draw(sprite);
            }
            window.SetView(camera.GetGameView());
            drawList.Clear();
            #endregion entity drawing

            #region lighting drawing
            lightingBatch.Initialize(camera.GetGameView(), new Color(0, 0, 0, surface.GetDarkness()));
            for (int i = begPos[0]; i <= endPos[0]; i++)
            {
                for (int j = begPos[1]; j <= endPos[1]; j++)
                {
                    Chunk chunk = surface.GetChunk(i, j);
                    List <LightSource> lightSources = chunk.lightSources;
                    for (int k = 0; k < lightSources.Count; k++)
                    {
                        if (lightSources[k].on == true)
                        {
                            lightSources[k].Draw(lightingBatch);
                        }
                    }
                }
            }
            Sprite lightingSprite = lightingBatch.Finalize();
            window.SetView(camera.GetGUIView());
            window.Draw(lightingSprite);
            window.SetView(camera.GetGameView());
            #endregion

            #region bounding box drawing
            if (drawBoundingBoxes == true)
            {
                for (int i = begPos[0]; i <= endPos[0]; i++)
                {
                    for (int j = begPos[1]; j <= endPos[1]; j++)
                    {
                        Chunk chunk = surface.GetChunk(i, j);
                        #region Tile bounding box drawing

                        int         chunkIndex = i * surface.worldSize + j;
                        float[]     pointsTile = surface.tileBox.GetPoints();
                        VertexArray vA;
                        if (!tileBoundingBoxVertexArray.TryGetValue(chunkIndex, out vA))
                        {
                            vA = tileCollection.GenerateTerrainBoundingBoxArray(surface, chunk, chunkIndex, pointsTile);
                            tileBoundingBoxVertexArray.Add(chunkIndex, vA);
                        }
                        window.Draw(vA);
                        #endregion Tile bounding box drawing

                        #region Entity bounding box drawing
                        List <Entity> entityList = chunk.entityList;
                        for (int k = 0; k < entityList.Count; k++)
                        {
                            float[] pointsEntity        = entityList[k].collisionBox.GetPoints();
                            float[] drawingPointsEntity = entityList[k].drawingBox.GetPoints();
                            Vector2 position            = entityList[k].position;
                            for (int l = 0; l < pointsEntity.Length; l += 2)
                            {
                                entityBoundingBoxArray.Append(new Vertex(new Vector2f(pointsEntity[l] + position.x, pointsEntity[l + 1] + position.y), Color.Red));
                                entityBoundingBoxArray.Append(new Vertex(new Vector2f(pointsEntity[(l + 2) % 8] + position.x, pointsEntity[(l + 3) % 8] + position.y), Color.Red));
                            }
                            for (int l = 0; l < drawingPointsEntity.Length; l += 2)
                            {
                                drawingBoundingBoxArray.Append(new Vertex(new Vector2f(drawingPointsEntity[l] + position.x, drawingPointsEntity[l + 1] + position.y), Color.Blue));
                                drawingBoundingBoxArray.Append(new Vertex(new Vector2f(drawingPointsEntity[(l + 2) % 8] + position.x, drawingPointsEntity[(l + 3) % 8] + position.y), Color.Blue));
                            }
                        }
                        #endregion Entity bounding box drawing
                    }
                }
                window.Draw(entityBoundingBoxArray);
                window.Draw(drawingBoundingBoxArray);
                entityBoundingBoxArray.Clear();
                drawingBoundingBoxArray.Clear();
                VertexArray windowBoxArray = new VertexArray(PrimitiveType.Lines);
                float[]     pointsWindow   = windowBox.GetPoints();
                for (int l = 0; l < pointsWindow.Length; l += 2)
                {
                    windowBoxArray.Append(new Vertex(new Vector2f(pointsWindow[l] + origin.X, pointsWindow[l + 1] + origin.Y), Color.Magenta));
                    windowBoxArray.Append(new Vertex(new Vector2f(pointsWindow[(l + 2) % 8] + origin.X, pointsWindow[(l + 3) % 8] + origin.Y), Color.Magenta));
                }
                window.Draw(windowBoxArray);
                windowBoxArray.Clear();
            }
            #endregion bounding box drawing
        }
Пример #23
0
        public VertexArray[] GenerateTerrainVertices(SurfaceContainer surface, int[] pos)
        {
            VertexArray[] terrainVertexArray = new VertexArray[terrainTiles.Count];
            terrainVertexArray[0] = GenerateCliffVertices(surface, pos);
            for (int curType = 1; curType < terrainTiles.Count; curType++)
            {
                Tile tile = terrainTiles[curType];
                terrainVertexArray[curType] = new VertexArray(PrimitiveType.Triangles);
                int[] cXY = new int[] { pos[0] * Props.chunkSize, pos[1] * Props.chunkSize };
                for (int i = 0; i < Props.chunkSize; i++)
                {
                    for (int j = 0; j < Props.chunkSize; j++)
                    {
                        //the current tile in the loop
                        byte currentTile = surface.GetTileFromWorldInt(pos, i, j);
                        if (currentTile > curType)
                        {
                            continue;
                        }
                        //hash algo
                        int variantX = i * 266489917 + 374761393;
                        variantX  = (variantX << 17) | (variantX >> 15);
                        variantX += j * 266489917;
                        variantX *= 668265263;
                        variantX ^= variantX >> 15;
                        variantX *= 246822519;
                        variantX  = Math.Abs(variantX);
                        //origin that vertices will be defined relative to
                        int oX = (cXY[0] + i) * Props.tileSize;
                        int oY = (cXY[1] + j) * Props.tileSize;

                        #region Regular tile variant determination
                        if (currentTile == curType)
                        {
                            int variantRegular = variantX % 8;
                            //Append regular tile variation
                            AppendQuadVertices(terrainVertexArray[curType], oX, oY, 0, 0, variantRegular, tile.shade, tile.textureRect);
                            continue;
                        }
                        #endregion
                        int value   = 0;
                        int variant = variantX % 6; //variant is determine by whether the transition is into an impassable tile
                        if (currentTile != 0 && impassableTileTypes.Contains(currentTile))
                        {
                            variant += 6;
                        }

                        value += (surface.GetTileFromWorldInt(pos, i - 1, j - 1) == curType) ? 1 : 0;   //top left
                        value += (surface.GetTileFromWorldInt(pos, i, j - 1) == curType) ? 2 : 0;       //top center
                        value += (surface.GetTileFromWorldInt(pos, i + 1, j - 1) == curType) ? 4 : 0;   //top right
                        value += (surface.GetTileFromWorldInt(pos, i - 1, j) == curType) ? 8 : 0;       //left
                        value += (surface.GetTileFromWorldInt(pos, i + 1, j) == curType) ? 16 : 0;      //right
                        value += (surface.GetTileFromWorldInt(pos, i - 1, j + 1) == curType) ? 32 : 0;  //bottom left
                        value += (surface.GetTileFromWorldInt(pos, i, j + 1) == curType) ? 64 : 0;      //bottom center
                        value += (surface.GetTileFromWorldInt(pos, i + 1, j + 1) == curType) ? 128 : 0; //bottom right
                        if (value == 0)
                        {
                            continue; //no surrounding tiles of tiletype
                        }
                        if (((value & 24) + (value & 2)) == 2)
                        {
                            //top fade
                            AppendQuadVertices(terrainVertexArray[curType], oX, oY, 0, 2, variant, tile.shade, tile.textureRect);
                        }
                        if (((value & 24) + (value & 64)) == 64)
                        {
                            //bottom fade
                            AppendQuadVertices(terrainVertexArray[curType], oX, oY, 12, 2, variant, tile.shade, tile.textureRect);
                        }
                        if (((value & 66) + (value & 8)) == 8)
                        {
                            //left fade
                            AppendQuadVertices(terrainVertexArray[curType], oX, oY, 0, 3, variant, tile.shade, tile.textureRect);
                        }
                        if (((value & 66) + (value & 16)) == 16)
                        {
                            //right fade
                            AppendQuadVertices(terrainVertexArray[curType], oX, oY, 12, 3, variant, tile.shade, tile.textureRect);
                        }
                        if ((value & 10) == 10)
                        {
                            //inside corner topleft
                            AppendQuadVertices(terrainVertexArray[curType], oX, oY, 0, 4, variant, tile.shade, tile.textureRect);
                        }
                        else if (((value & 1) + (value & 10)) == 1)
                        {
                            //outside corner topleft
                            AppendQuadVertices(terrainVertexArray[curType], oX, oY, 0, 6, variant, tile.shade, tile.textureRect);
                        }
                        if ((value & 18) == 18)
                        {
                            //inside corner topright
                            AppendQuadVertices(terrainVertexArray[curType], oX, oY, 12, 4, variant, tile.shade, tile.textureRect);
                        }
                        else if (((value & 4) + (value & 18)) == 4)
                        {
                            //outside corner topright
                            AppendQuadVertices(terrainVertexArray[curType], oX, oY, 12, 6, variant, tile.shade, tile.textureRect);
                        }
                        if ((value & 72) == 72)
                        {
                            //inside corner bottomleft
                            AppendQuadVertices(terrainVertexArray[curType], oX, oY, 0, 5, variant, tile.shade, tile.textureRect);
                        }
                        else if (((value & 32) + (value & 72)) == 32)
                        {
                            //outside corner bottomleft
                            AppendQuadVertices(terrainVertexArray[curType], oX, oY, 0, 7, variant, tile.shade, tile.textureRect);
                        }
                        if ((value & 80) == 80)
                        {
                            //inside corner bottomright
                            AppendQuadVertices(terrainVertexArray[curType], oX, oY, 12, 5, variant, tile.shade, tile.textureRect);
                        }
                        else if (((value & 128) + (value & 80)) == 128)
                        {
                            //outside corner bottomright
                            AppendQuadVertices(terrainVertexArray[curType], oX, oY, 12, 7, variant, tile.shade, tile.textureRect);
                        }
                    }
                }
            }
            return(terrainVertexArray);
        }
Пример #24
0
        public PathNode GetPath(SurfaceContainer surface, Vector2 start, Vector2 target, int pathTimeout, Base.CollisionLayer unwalkableMask, Base.CollisionLayer collisionMask, float frictionFactor)
        {
            this.frictionFactor = frictionFactor;
            int frictionMask = (int)(collisionMask & Base.CollisionLayer.Terrain); //a nonzero value means the pathcost is higher for lower frictions

            frictionMask = frictionMask / (1 + frictionMask);                      //Normalize the frictionmask to 0 or 1 using +1 trick
            int[] startCoords = surface.WorldToAbsoluteTileCoords(start.x, start.y);
            int[] endCoords   = surface.WorldToAbsoluteTileCoords(target.x, target.y);
            float heuristic   = CalculateHeuristic(startCoords, endCoords);

            PathNode        startNode  = new PathNode(null, 0, 0, heuristic, startCoords);
            List <PathNode> openList   = new List <PathNode>();
            List <PathNode> closedList = new List <PathNode>();
            PathNode        endNode    = null;

            openList.Add(startNode);
            while (openList.Count > 0 && pathTimeout > 0)
            {
                pathTimeout--;
                PathNode curNode     = null;
                int      removeIndex = 0;
                for (int i = 0; i < openList.Count; i++)
                {
                    if (curNode == null || openList[i].cost < curNode.cost)
                    {
                        removeIndex = i;
                        curNode     = openList[i];
                    }
                }
                openList.RemoveAt(removeIndex);
                closedList.Add(curNode);
                if (pathTimeout == 0 || (curNode.coords[0] == endCoords[0] && curNode.coords[1] == endCoords[1]))
                {
                    endNode = curNode;
                    break;
                }
                for (int i = curNode.coords[0] - 1; i <= curNode.coords[0] + 1; i++)
                {
                    for (int j = curNode.coords[1] - 1; j <= curNode.coords[1] + 1; j++)
                    {
                        bool ignore = false;
                        if (i < 0 || j < 0) //Check if coords are outside worldSize
                        {
                            ignore = true;
                        }
                        if (ignore == false) //else check that coords are not already in closedList
                        {
                            for (int k = 0; k < closedList.Count; k++)
                            {
                                if (closedList[k].coords[0] == i && closedList[k].coords[1] == j)
                                {
                                    ignore = true;
                                    break;
                                }
                            }
                        }
                        if (ignore == false) //else check that coords are not already in openList
                        {
                            for (int k = 0; k < openList.Count; k++)
                            {
                                if (openList[k].coords[0] == i && openList[k].coords[1] == j)
                                {
                                    ignore = true;
                                    break;
                                }
                            }
                        }
                        if (!ignore) //if neither of the preceding conditiosn set ignore to false, add tile to open list on path search
                        {
                            Tile tile      = tileCollection.GetTerrainTile(surface.GetTileFromWorldInt(i, j));
                            int  solidMask = (int)((unwalkableMask & collisionMask) & tile.collisionMask); // a zero value when the tile is walkable
                            if (solidMask == 0)
                            {
                                int[]    coords  = new int[] { i, j };
                                PathNode newNode = new PathNode(curNode, frictionMask * (frictionFactor * (1 / tile.frictionModifier)), curNode.begin + 1, CalculateHeuristic(coords, endCoords), coords);
                                openList.Add(newNode);
                            }
                        }
                    }
                }
            }
            return(endNode);
        }
Пример #25
0
        private VertexArray GenerateCliffVertices(SurfaceContainer surface, int[] pos)
        {
            VertexArray vA = new VertexArray(PrimitiveType.Triangles);

            int[] cXY = new int[] { pos[0] * Props.chunkSize, pos[1] * Props.chunkSize };
            for (int i = 0; i < Props.chunkSize; i++)
            {
                for (int j = 0; j < Props.chunkSize; j++)
                {
                    //the current tile in the loop
                    byte currentTile = surface.GetTileFromWorldInt(pos, i, j);
                    #region Skip tile determination
                    if (currentTile != 0)
                    {
                        continue;
                    }
                    #endregion
                    //hash algo
                    int variantX = i * 266489917 + 374761393;
                    variantX  = (variantX << 17) | (variantX >> 15);
                    variantX += j * 266489917;
                    variantX *= 668265263;
                    variantX ^= variantX >> 15;
                    variantX *= 246822519;
                    variantX  = Math.Abs(variantX);
                    //origin that vertices will be defined relative to
                    int oX = (cXY[0] + i) * Props.tileSize;
                    int oY = (cXY[1] + j) * Props.tileSize;

                    int value   = 0;
                    int variant = variantX % 4;                                               //variant is determine by whether the transition is into an impassable tile

                    value += (surface.GetTileFromWorldInt(pos, i - 1, j - 1) != 0) ? 1 : 0;   //top left
                    value += (surface.GetTileFromWorldInt(pos, i, j - 1) != 0) ? 2 : 0;       //top center
                    value += (surface.GetTileFromWorldInt(pos, i + 1, j - 1) != 0) ? 4 : 0;   //top right
                    value += (surface.GetTileFromWorldInt(pos, i - 1, j) != 0) ? 8 : 0;       //left
                    value += (surface.GetTileFromWorldInt(pos, i + 1, j) != 0) ? 16 : 0;      //right
                    value += (surface.GetTileFromWorldInt(pos, i - 1, j + 1) != 0) ? 32 : 0;  //bottom left
                    value += (surface.GetTileFromWorldInt(pos, i, j + 1) != 0) ? 64 : 0;      //bottom center
                    value += (surface.GetTileFromWorldInt(pos, i + 1, j + 1) != 0) ? 128 : 0; //bottom right

                    //Virtual mapping of surrounding tiles
                    // 1 2 3
                    // 4 0 5
                    // 6 7 8
                    //bitflag values of surrounding tiles
                    // 1  2  4
                    // 8  0  16
                    // 32 64 128

                    //need specific checks for if left and right exist simultaneously
                    //if top and bottom exist simultaneously
                    //if two corners exist (u shape) in any config
                    //if four corners exist in any config

                    if (value == 0)
                    {
                        continue; //no surrounding tiles of tiletype
                    }
                    if (((value & 24) + (value & 2)) == 2)
                    {
                        //top fade
                        AppendQuadVerticesCliff(vA, oX, oY, 0, 0, variant, cliffShade, cliffBounds);
                    }
                    if (((value & 24) + (value & 64)) == 64)
                    {
                        //bottom fade
                        AppendQuadVerticesCliff(vA, oX, oY, 4, 0, variant, cliffShade, cliffBounds);
                    }
                    if (((value & 66) + (value & 8)) == 8)
                    {
                        //left fade
                        AppendQuadVerticesCliff(vA, oX, oY, 8, 0, variant, cliffShade, cliffBounds);
                    }
                    if (((value & 66) + (value & 16)) == 16)
                    {
                        //right fade
                        AppendQuadVerticesCliff(vA, oX, oY, 12, 0, variant, cliffShade, cliffBounds);
                    }
                    if ((value & 10) == 10)
                    {
                        //inside corner topleft
                        AppendQuadVerticesCliff(vA, oX, oY, 0, 1, variant, cliffShade, cliffBounds);
                    }
                    else if (((value & 1) + (value & 10)) == 1)
                    {
                        //outside corner topleft
                        AppendQuadVerticesCliff(vA, oX, oY, 0, 2, variant, cliffShade, cliffBounds);
                    }
                    if ((value & 18) == 18)
                    {
                        //inside corner topright
                        AppendQuadVerticesCliff(vA, oX, oY, 4, 1, variant, cliffShade, cliffBounds);
                    }
                    else if (((value & 4) + (value & 18)) == 4)
                    {
                        //outside corner topright
                        AppendQuadVerticesCliff(vA, oX, oY, 4, 2, variant, cliffShade, cliffBounds);
                    }
                    if ((value & 72) == 72)
                    {
                        //inside corner bottomleft
                        AppendQuadVerticesCliff(vA, oX, oY, 8, 1, variant, cliffShade, cliffBounds);
                    }
                    else if (((value & 32) + (value & 72)) == 32)
                    {
                        //outside corner bottomleft
                        AppendQuadVerticesCliff(vA, oX, oY, 8, 2, variant, cliffShade, cliffBounds);
                    }
                    if ((value & 80) == 80)
                    {
                        //inside corner bottomright
                        AppendQuadVerticesCliff(vA, oX, oY, 12, 1, variant, cliffShade, cliffBounds);
                    }
                    else if (((value & 128) + (value & 80)) == 128)
                    {
                        //outside corner bottomright
                        AppendQuadVerticesCliff(vA, oX, oY, 12, 2, variant, cliffShade, cliffBounds);
                    }
                }
            }
            return(vA);
        }
Пример #26
0
 virtual public void InitializeEntity(Vector2 position, SurfaceContainer surface)
 {
     this.surface  = surface;
     this.position = position;
     this.surface.InitiateEntityInChunks(this);
 }
Пример #27
0
 public override void InitializeEntity(Vector2 position, SurfaceContainer surface)
 {
     base.InitializeEntity(position, surface);
     lightSourceFlicker.on = false;
     lightSourceFlicker.Initialize(this);
 }