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