Ejemplo n.º 1
0
        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);
        }
Ejemplo n.º 2
0
        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);
        }