public WorldObject(Intersection intersection) { X = intersection.X; Y = intersection.Y; IntersectsWith = intersection.IntersectsWith; Distance = intersection.Distance; }
/// <summary> /// Checks if certain coordinates are outside of the level boundaries /// </summary> /// <param name="coordinates">coordinates on grid (not array indexes)</param> /// <param name="grid">the grid to search in</param> /// <returns></returns> private bool IsOutOfBounds(Intersection coordinates, int[][] grid) { Point gridCell = CoordsToGrid(coordinates); return gridCell.Y < 0 || gridCell.Y >= grid.Length || gridCell.X < 0 || gridCell.X >= grid[0].Length; }
/// <summary> /// Use raycasting to find the nearest intersection with an object on the grid at a specified angle /// </summary> /// <param name="angle"></param> /// <param name="grid"></param> /// <returns></returns> private Intersection FindIntersection(Angle angle, int[][] grid) { bool foundX = false; bool foundY = false; // Distance from current point to next intersection for X-axis and Y-axis double angleTan = Math.Tan(angle.ToRadians()); double deltaX = wallSize / angleTan; double deltaY = wallSize * angleTan; // Correct the deltaX/deltaY values if (angle.FacingSouth()) { deltaX = -deltaX; } if (angle.FacingEast()) { deltaY = -deltaY; } // Location of horizontal (X) and vertical (Y) intersections Intersection intersectionX = null; Intersection intersectionY = null; // Distance to next horizontal intersection if (angle.FacingNorth() || angle.FacingSouth()) { while (intersectionX == null || (!foundX && !IsOutOfBounds(intersectionX, grid))) { if (intersectionX == null) { intersectionX = new Intersection(); intersectionX.IntersectsWith = IntersectionAxe.Xaxe; intersectionX.Y = Math.Floor(player.Position.Y / wallSize) * wallSize; intersectionX.Y += angle.FacingNorth() ? -0.001 : wallSize; intersectionX.X = player.Position.X + (player.Position.Y - intersectionX.Y) / angleTan; } else { // Target the next horizontal intersection intersectionX.X = intersectionX.X + deltaX; intersectionX.Y += angle.FacingNorth() ? -wallSize : wallSize; } foundX = ContainsItem(intersectionX, grid); } } // Distance to next vertical intersection if (angle.FacingWest() || angle.FacingEast()) { while (intersectionY == null || (!foundY && !IsOutOfBounds(intersectionY, grid))) { if (intersectionY == null) { intersectionY = new Intersection(); intersectionY.IntersectsWith = IntersectionAxe.Yaxe; intersectionY.X = Math.Floor(player.Position.X / wallSize) * wallSize; intersectionY.X += angle.FacingWest() ? -0.001 : wallSize; intersectionY.Y = player.Position.Y + (player.Position.X - intersectionY.X) * angleTan; } else { // Target the next vertical intersection intersectionY.X += angle.FacingWest() ? -wallSize : wallSize; intersectionY.Y = intersectionY.Y + deltaY; } foundY = ContainsItem(intersectionY, grid); } } // Determine which wall is nearest to our starting point if (!(IsOutOfBounds(intersectionX, grid) && IsOutOfBounds(intersectionY, grid))) { Intersection intersection = ChooseNearest(angle, intersectionX, intersectionY); // Calculate distance from player to the intersection intersection.SetDistance(player.Position, angle); return intersection; } return null; }
/// <summary> /// Converts world coordinates to grid coordinates (eg. 10,10 = 0,0) /// </summary> /// <param name="coordinates">world coordinates</param> /// <returns>grid coordinates</returns> private Point CoordsToGrid(Intersection coordinates) { return new Point((int)(coordinates.X / wallSize), (int)(coordinates.Y / wallSize)); }
/// <summary> /// Checks if certain coordinates on the specified grid contain an item /// </summary> /// <param name="coordinates">coordinates on map (not array indexes)</param> /// <param name="grid">the grid to search in</param> /// <returns></returns> private bool ContainsItem(Intersection coordinates, int[][] grid) { Point gridCell = CoordsToGrid(coordinates); return (gridCell.Y >= 0 && gridCell.Y < grid.Length) && (gridCell.X >= 0 && gridCell.X < grid[0].Length) && grid[gridCell.Y][gridCell.X] != 0; }
/// <summary> /// Returns the intersection that is nearest to the player /// </summary> /// <param name="angle"></param> /// <param name="intersectionX">Horizontal intersection point</param> /// <param name="intersectionY">Vertical intersection point</param> /// <returns></returns> private Intersection ChooseNearest(Angle angle, Intersection intersectionX, Intersection intersectionY) { // If either horizontal or vertical intersection was left empty we can simply return the other one if (intersectionX == null) { return intersectionY; } else if (intersectionY == null) { return intersectionX; } else { // Determine which intersection is nearest double distanceX = Math.Abs(Math.Abs(player.Position.X - intersectionX.X) / Math.Cos(angle.ToRadians())); double distanceY = Math.Abs(Math.Abs(player.Position.X - intersectionY.X) / Math.Cos(angle.ToRadians())); if (distanceX < distanceY) { return intersectionX; } else { return intersectionY; } } }