public static CollisionInfo?GetVerticalCollision(this int[,] map, Vector2 position, float directionInDegrees, float maxDistance) { if (directionInDegrees == 90 || directionInDegrees == 270) { return(null); } int firstXCoordinateToCheck = 0; int lastXCoordinateToCheck = 0; var directionInRadian = MathHelper.ToRadians(directionInDegrees); Vector2 directionAsVector = directionInRadian.AngleAsVector(); float angleOfCollisionInDegrees = angleOfCollisionInDegrees = Math.Abs(((directionInDegrees + 360) % 180) - 90); if (directionAsVector.X < 0) { firstXCoordinateToCheck = (int)Math.Floor(position.X); lastXCoordinateToCheck = 0; } else { firstXCoordinateToCheck = (int)Math.Ceiling(position.X); lastXCoordinateToCheck = map.GetLength(0) - 1; } int deltaX = Math.Sign(lastXCoordinateToCheck - firstXCoordinateToCheck); var line = LineFormula.FromCoordinateAndDirection(position, directionInRadian); bool done = false; for (int x = firstXCoordinateToCheck; !done; x += deltaX) { float?y = 0; if (directionInDegrees == 0 || directionInDegrees == 180) { y = position.Y; } else { y = line.GetInterSectWithVerticalLine(x); } var realX = x - (deltaX < 0 ? 1 : 0); if (!y.HasValue || !map.Contains(realX, (int)y.Value)) { return(null); } if (map[realX, (int)y.Value] != 0) { var fraction = y.Value - (int)y.Value; if (deltaX < 0) { fraction = 1 - fraction; } var collisionPoint = new Vector2(x, y.Value); return(new CollisionInfo() { CollisionPoint = collisionPoint, PositionOnWall = fraction, TileHit = new Point(realX, (int)y.Value), TileHitValue = map[realX, (int)y.Value], DistanceToCollision = Vector2.Distance(position, collisionPoint), ViewAngleOnWall = angleOfCollisionInDegrees }); } if (x == lastXCoordinateToCheck) { done = true; } } return(null); }
public static CollisionInfo?GetHorizontalCollision(this int[,] map, Vector2 position, float directionInDegrees, float maxDistance) { int firstYCoordinateToCheck = 0; int lastYCoordinateToCheck = 0; if (directionInDegrees == 0 || directionInDegrees == 180) { return(null); } float directionInRadian = (float)MathHelper.ToRadians(directionInDegrees); Vector2 directionAsVector = new Vector2((float)Math.Cos(directionInRadian), (float)Math.Sin(directionInRadian)); float angleOfCollisionInDegrees = angleOfCollisionInDegrees = (directionInDegrees + 360) % 180; if (directionAsVector.Y < 0) { firstYCoordinateToCheck = (int)Math.Floor(position.Y); lastYCoordinateToCheck = 0; } else { firstYCoordinateToCheck = (int)Math.Ceiling(position.Y); lastYCoordinateToCheck = map.GetLength(1) - 1; } int deltaY = Math.Sign(lastYCoordinateToCheck - firstYCoordinateToCheck); var line = LineFormula.FromCoordinateAndDirection(position, directionInRadian); bool done = false; for (int y = firstYCoordinateToCheck; !done; y += deltaY) { float?x = 0; if (directionInDegrees == 90 || directionInDegrees == 270) { x = position.X; } else { x = line.GetInterSectWithHorizontalLine(y); } var realY = y - (deltaY < 0 ? 1 : 0); if (!x.HasValue || !map.Contains((int)x.Value, realY)) { return(null); } if (map[(int)x.Value, realY] != 0) { var fraction = x.Value - (int)x.Value; if (deltaY > 0) { fraction = 1 - fraction; } var collisionPoint = new Vector2(x.Value, y); return(new CollisionInfo() { CollisionPoint = collisionPoint, PositionOnWall = fraction, TileHit = new Point((int)x.Value, realY), TileHitValue = map[(int)x.Value, realY], DistanceToCollision = Vector2.Distance(position, collisionPoint), ViewAngleOnWall = angleOfCollisionInDegrees }); } if (y == lastYCoordinateToCheck) { done = true; } } return(null); }