Exemple #1
0
        private Vector2 CalculateExit(Vector2 direction, Vector2 center, Collision.Side s, Vector2 middleOfSide)
        {
            Vector2 exitPoint = middleOfSide - center;

            switch (s)
            {
            case Collision.Side.Top:
            case Collision.Side.Bottom:
                exitPoint.X = direction.X * (exitPoint.Y / direction.Y);
                break;

            case Collision.Side.Left:
            case Collision.Side.Right:
                exitPoint.Y = direction.Y * (exitPoint.X / direction.X);
                break;
            }

            return(exitPoint);
        }
    public static Collision.Side Opposite(this Collision.Side side)
    {
        switch (side)
        {
        case Collision.Side.Bottom:
            return(Collision.Side.Top);

        case Collision.Side.Top:
            return(Collision.Side.Bottom);

        case Collision.Side.Left:
            return(Collision.Side.Right);

        case Collision.Side.Right:
            return(Collision.Side.Left);

        default:
            return(default(Collision.Side));
        }
    }
Exemple #3
0
        /// <summary>
        /// </summary>
        /// <param name="rect"></param>
        /// <param name="side"></param>
        /// <returns>The middle of the side of the rectangle specified.</returns>
        public static Vector2 GetMiddleOfSide(this Rectangle rect, Collision.Side side)
        {
            switch (side)
            {
            case Collision.Side.Top:
                return(new Vector2(rect.Center.X, rect.Top));

            case Collision.Side.Bottom:
                return(new Vector2(rect.Center.X, rect.Bottom - 1));

            case Collision.Side.Left:
                return(new Vector2(rect.Left, rect.Center.Y));

            case Collision.Side.Right:
                return(new Vector2(rect.Right - 1, rect.Center.Y));

            default:
                return(Vector2.Zero);
            }
        }
Exemple #4
0
        private Collision.Side CalculateExitSide(Room r, Vector2 relVector)
        {
            Vector2 center = r.BoundingBox.Center.ToVector2();

            //Calculate angles of vector.
            double relAngle = Math.Atan2(relVector.Y, relVector.X);

            //Calculate the angles of the line
            Vector2[] cornerVectors = new Vector2[4];
            cornerVectors[0] = new Vector2(r.BoundingBox.Left, r.BoundingBox.Top) - center;
            cornerVectors[1] = new Vector2(r.BoundingBox.Right, r.BoundingBox.Top) - center;
            cornerVectors[2] = new Vector2(r.BoundingBox.Right, r.BoundingBox.Bottom) - center;
            cornerVectors[3] = new Vector2(r.BoundingBox.Left, r.BoundingBox.Bottom) - center;
            //Use Math.Atan2 to convert vectors to angles.
            double[] cornerAngles = new double[4];
            cornerAngles[0] = Math.Atan2(cornerVectors[0].Y, cornerVectors[0].X);
            cornerAngles[1] = Math.Atan2(cornerVectors[1].Y, cornerVectors[1].X);
            cornerAngles[2] = Math.Atan2(cornerVectors[2].Y, cornerVectors[2].X);
            cornerAngles[3] = Math.Atan2(cornerVectors[3].Y, cornerVectors[3].X);

            //Calculate Sides based on angle
            Collision.Side s = default(Collision.Side);
            if (relAngle >= cornerAngles[0] && relAngle < cornerAngles[1])
            {
                s = Collision.Side.Top;
            }
            else if (relAngle >= cornerAngles[1] && relAngle < cornerAngles[2])
            {
                s = Collision.Side.Right;
            }
            else if (relAngle >= cornerAngles[2] && relAngle < cornerAngles[3])
            {
                s = Collision.Side.Bottom;
            }
            else if (relAngle >= cornerAngles[3] || relAngle < cornerAngles[0])
            {
                s = Collision.Side.Left;
            }

            return(s);
        }
Exemple #5
0
        private TileField GenerateTiles(List <Room> rooms, List <Tuple <Room, Room> > hallwayPairs)
        {
            //Get the highest coordinates so we know the size of the TileField.
            int highestX = int.MinValue;
            int highestY = int.MinValue;

            foreach (Room r in rooms)
            {
                if (r.BoundingBox.Right > highestX)
                {
                    highestX = r.BoundingBox.Right;
                }
                if (r.BoundingBox.Bottom > highestY)
                {
                    highestY = r.BoundingBox.Bottom;
                }
            }

            //Make the tilefield and fill with default Tiles.
            TileField tf = new TileField(highestY + 1, highestX + 1, 0, "TileField");

            Add(tf);
            for (int x = 0; x < tf.Columns; x++)
            {
                for (int y = 0; y < tf.Rows; y++)
                {
                    tf.Add(new Tile(), x, y);
                }
            }

            List <Tuple <XNAPoint, XNAPoint> > hallways = new List <Tuple <XNAPoint, XNAPoint> >();

            //Find good points for the hallways connect to.
            foreach (Tuple <Room, Room> pair in hallwayPairs)
            {
                Vector2 center1 = pair.Item1.BoundingBox.Center.ToVector2();
                Vector2 center2 = pair.Item2.BoundingBox.Center.ToVector2();

                //Vector from center of room1 to center of room2 and vice versa
                Vector2 v1 = center2 - center1;
                Vector2 v2 = center1 - center2;

                Collision.Side s1 = CalculateExitSide(pair.Item1, v1);
                Collision.Side s2 = CalculateExitSide(pair.Item2, v2);

                v1.Normalize();
                v2.Normalize();

                XNAPoint cRelExit1 = CalculateExit(v1, center1, s1, pair.Item1.BoundingBox.GetMiddleOfSide(s1)).ToPoint();
                XNAPoint cRelExit2 = CalculateExit(v2, center2, s2, pair.Item2.BoundingBox.GetMiddleOfSide(s2)).ToPoint();
                XNAPoint absExit1  = cRelExit1 + pair.Item1.BoundingBox.Center;
                XNAPoint absExit2  = cRelExit2 + pair.Item2.BoundingBox.Center;

                hallways.Add(new Tuple <XNAPoint, XNAPoint>(absExit1, absExit2));
            }

            //for each room, add floor tiles to the tilefield.
            for (int i = 0; i < rooms.Count; i++)
            {
                Room r      = rooms[i];
                int  width  = r.BoundingBox.Width;
                int  height = r.BoundingBox.Height;

                XNAPoint relCenter = r.BoundingBox.Center - r.BoundingBox.Location;

                for (int x = 0; x < width; x++)
                {
                    for (int y = 0; y < height; y++)
                    {
                        Tile tile = LoadFloorTile();
                        if (x == relCenter.X && y == relCenter.Y)
                        {
                            tile.AddDebugTag("Room", "" + i);
                        }
                        tf.Add(tile, x + r.BoundingBox.X, y + r.BoundingBox.Y);
                    }
                }
            }

            //Generate hallways
            foreach (Tuple <XNAPoint, XNAPoint> pair in hallways)
            {
                //Use the pathfinder to get a path from exitpoint to exitpoint.
                PathFinder pf = new PathFinder(tf);
                pf.EnableStraightLines();
                List <Tile> path = pf.ShortestPath(tf[pair.Item1.X, pair.Item1.Y] as Tile, tf[pair.Item2.X, pair.Item2.Y] as Tile, tile => true);

                Tile t = tf[pair.Item1.X, pair.Item1.Y] as Tile;
                t.AddDebugTag("ExitConnectionPoint", pair.Item2.X + "," + pair.Item2.Y);
                path.Add(t);

                //Add a floor tile for every tile in the path.
                foreach (Tile tile in path)
                {
                    Tile newTile = LoadFloorTile();
                    newTile.AddDebugTags(tile.DebugTags);
                    tf.Add(newTile, tile.TilePosition.X, tile.TilePosition.Y);
                }
            }

            //Exchange all remaining background tiles for Wall tiles.
            for (int x = 0; x < tf.Columns; x++)
            {
                for (int y = 0; y < tf.Rows; y++)
                {
                    Tile currentTile = tf[x, y] as Tile;
                    Tile aboveTile   = tf[x, y - 1] as Tile;
                    if (currentTile != null && aboveTile != null && currentTile.TileType == TileType.Background)
                    {
                        Tile newTile = LoadWallTile(x, y);
                        newTile.AddDebugTags(currentTile.DebugTags);
                        tf.Add(newTile, x, y);
                    }
                }
            }

            //Add starttiles
            for (int p = 0; p < 4; p++)
            {
                tf.Add(LoadStartTile(p + 1), rooms[0].Location.ToRoundedPoint().X + 1 + p % 2, rooms[0].Location.ToRoundedPoint().Y + 1 + p / 2);
            }

            //Generate EndTile
            List <Room> forEnd    = new List <Room>();
            List <Room> usedRooms = new List <Room>();

            for (int a = 0; a < hallwayPairs.Count; a++)
            {
                if (!forEnd.Contains(hallwayPairs[a].Item1))
                {
                    forEnd.Add(hallwayPairs[a].Item1);
                    usedRooms.Add(hallwayPairs[a].Item1);
                }
                if (!forEnd.Contains(hallwayPairs[a].Item2))
                {
                    forEnd.Add(hallwayPairs[a].Item2);
                    usedRooms.Add(hallwayPairs[a].Item2);
                }
            }

            for (int a = 0; a < hallwayPairs.Count; a++)
            {
                if (hallwayPairs[a].Item1 == rooms[0] || hallwayPairs[a].Item2 == rooms[0])
                {
                    if (forEnd.Contains(hallwayPairs[a].Item1))
                    {
                        forEnd.Remove(hallwayPairs[a].Item1);
                    }
                    if (forEnd.Contains(hallwayPairs[a].Item2))
                    {
                        forEnd.Remove(hallwayPairs[a].Item2);
                    }
                }
            }
            tf.Add(LoadEndTile(), forEnd[0].Location.ToRoundedPoint().X + 1, forEnd[0].Location.ToRoundedPoint().Y + 1);
            tf.Add(LoadChestTile(levelIndex), forEnd[0].Location.ToRoundedPoint().X + forEnd[0].Size.X - 2, forEnd[0].Location.ToRoundedPoint().Y + 1);

            //Door spawn
            for (int i = 0; i < usedRooms.Count; i++)
            {
                for (int x = rooms[i].Location.ToRoundedPoint().X; x < rooms[i].Location.ToRoundedPoint().X + rooms[i].Size.X; x++)
                {
                    if (!tf.IsWall(x, rooms[i].Location.ToRoundedPoint().Y - 1))
                    {
                        if (tf.IsWall(x + 1, rooms[i].Location.ToRoundedPoint().Y - 1) && tf.IsWall(x - 1, rooms[i].Location.ToRoundedPoint().Y - 1))
                        {
                            tf.Add(LoadDoorTile(), x, rooms[i].Location.ToRoundedPoint().Y - 1);
                        }
                    }
                    if (!tf.IsWall(x, rooms[i].Location.ToRoundedPoint().Y + rooms[i].Size.Y))
                    {
                        if (tf.IsWall(x + 1, rooms[i].Location.ToRoundedPoint().Y + rooms[i].Size.Y) && tf.IsWall(x - 1, rooms[i].Location.ToRoundedPoint().Y + rooms[i].Size.Y))
                        {
                            tf.Add(LoadDoorTile(), x, rooms[i].Location.ToRoundedPoint().Y + rooms[i].Size.Y);
                        }
                    }
                }
            }

            //Test chest spawn
            int chestAmount = Random.Next(1, 2);

            usedRooms.Remove(rooms[0]);
            for (int i = 0; i < chestAmount; i++)
            {
                int chestRoom = Random.Next(usedRooms.Count);
                usedRooms.Remove(rooms[chestRoom]);
                int xChest = rooms[chestRoom].Location.ToRoundedPoint().X + rooms[chestRoom].Size.X / 2;
                int yChest = rooms[chestRoom].Location.ToRoundedPoint().Y + rooms[chestRoom].Size.Y / 2;
                tf.Add(LoadChestTile(levelIndex), xChest, yChest);
            }
            //End test

            //Test enemy spawn
            int numberOfEnemys = 8;

            for (int n = 0; n < numberOfEnemys; n++)
            {
                Enemy             enemy          = new Enemy(0, Index, EnemyType.random, "Enemy");
                List <GameObject> spawnLocations = tf.FindAll(obj => obj is Tile && (obj as Tile).Passable && !(obj as Tile).Blocked);
                Tile spawnLocation = spawnLocations[GameEnvironment.Random.Next(spawnLocations.Count)] as Tile;
                spawnLocation.PutOnTile(enemy);
            }
            //End test

            //Must be last statement, executed after the Tilefield is done.
            tf.InitSpriteSheetIndexation();
            return(tf);
        }