Пример #1
0
        List<Weapon> weapons; // a list to hold all of the weapons for the level

        #endregion Fields

        #region Constructors

        // constructor
        public Level(string mapFile)
        {
            // initializes things
            this.mapFile = mapFile;
            basicEnemies = new List<Enemy>();
            walls = new List<Wall>();
            weapons = new List<Weapon>();
            coins = new List<Coin>();
            doors = new List<Door>();
            keys = new List<Key>();
            disguises = new List<Disguise>();
            floorSwitchers = new List<FloorSwitcher>();
            font = ScreenManager.SharedManager.Content.Load<SpriteFont>("Arial");

            graphics = ScreenManager.SharedManager.gDevice;
            spriteBatch = ScreenManager.SharedManager.sBatch;

            levelMap = new Map(mapFile, new int[11] { 1, 1, 1, 1, 1, int.MaxValue, int.MaxValue, int.MaxValue, int.MaxValue, 0, 0 });

            roomGraph = new RoomGraph();
            foreach (var groupname in levelMap.ObjectGroups.Keys) // goes through each layer in the map file
            {
                int currentFloor = int.Parse(groupname[5].ToString()) - 1; // gets the floor number of the map layer.

                if (groupname.Substring(6, 8) == "Entities") // the layer contains GameObjects
                {
                    foreach (var entity in levelMap.ObjectGroups[groupname]) // goes through each entity and creates a GameObject if possible.
                    {
                        if (entity.Type == "Enemy") // adds an enemy to the basicEnemies list.
                        {
                            string sDir = entity.Properties.Find(x => x.Item1 == "startDirection").Item2;
                            int dir =  (sDir != null) ? int.Parse(sDir) : 3;
                            basicEnemies.Add(EntityGenerator.GenerateEnemy(new Vector3(entity.X, entity.Y, currentFloor), entity.Properties, dir));
                        }
                        else if (entity.Type == "Player") // creates the player.
                        {
                            player = EntityGenerator.GeneratePlayer(new Vector3(entity.X, entity.Y, currentFloor), 5, 400);
                        }
                        else if (entity.Type == "Wall") // adds a wall to the walls list.
                        {
                            walls.Add(EntityGenerator.GenerateWall(new Vector3(entity.X, entity.Y, currentFloor), entity.Width, entity.Height));
                        }
                        else if (entity.Type == "LockedDoor") // adds a door to the doors list.
                        {
                            doors.Add(EntityGenerator.GenerateDoor(new Vector3(entity.X, entity.Y, currentFloor), doors.Count));
                        }
                        else if (entity.Type == "Key") // adds a key to the keys list.
                        {
                            keys.Add(EntityGenerator.GenerateKey(new Vector3(entity.X, entity.Y, currentFloor), keys.Count));
                        }
                        else if (entity.Type == "Weapon") // adds a weapon to the weapons list.
                        {
                            weapons.Add(EntityGenerator.GenerateWeapon(new Vector3(entity.X, entity.Y, currentFloor), int.Parse(entity.Properties.Find(x => x.Item1 == "durability").Item2), entity.Properties.Find(x => x.Item1 == "type").Item2));
                        }
                        else if (entity.Type == "Coin") // adds a coin to the coins list.
                        {
                            coins.Add(EntityGenerator.GenerateCoin(new Vector3(entity.X, entity.Y, currentFloor), int.Parse(entity.Properties.Find(x => x.Item1 == "value").Item2)));
                        }
                        else if (entity.Type == "Disguise") //adds a disguise to the disguises list.
                        {
                            disguises.Add(EntityGenerator.GenerateDisguise(new Vector3(entity.X, entity.Y, currentFloor), entity.Properties.Find(x => x.Item1 == "disguiseType").Item2));
                        }
                        else if (entity.Type == "FloorSwitcher") // adds a floor switcher to the floorSwitchers list.
                        {
                            floorSwitchers.Add(new FloorSwitcher(new Rectangle(entity.X, entity.Y, entity.Width, entity.Height), currentFloor, currentFloor + 1, bool.Parse(entity.Properties.Find(x => x.Item1 == "Horizontal").Item2)));
                        }
                    }
                }

                if (groupname.Contains("Room")) // layer contains rooms
                {
                    foreach (var entity in levelMap.ObjectGroups[groupname]) // goes through each room object in the layer.
                    {
                        // creates a new RoomGraphNode and sets up it's connections.
                        RoomGraphNode node = new RoomGraphNode(new Rectangle(entity.X, entity.Y, entity.Width, entity.Height), currentFloor, entity.Name);
                        List<string> connections = new List<string>();
                        foreach (var t in entity.Properties)
                        {
                            if (t.Item1 != null)
                                connections.Add(t.Item1);
                            if (t.Item2 != null)
                                node.validDisguises.Add(t.Item2);
                        }
                        roomGraph.AddNode(node, connections);
                    }
                }

                // how much money the player needs to complete the level is 70% of the total money in the level.
                player.moneyNeeded = (basicEnemies.Count + coins.Count) * 70;
            }

            foreach (Door lockedDoor in doors) // if there aren't enough keys, the extra locked doors are unlocked.
            {
                if (keys[lockedDoor.keyAssociation] == null)
                    lockedDoor.locked = false;
            }

            // sets up what part of the level to show on screen.
            windowSpace = new Rectangle((int)(player.location.X + (player.rectangle.Width / 2)) - (graphics.Viewport.Width / 2), (int)(player.location.Y + (player.rectangle.Height / 2)) - (graphics.Viewport.Height / 2), graphics.Viewport.Width, graphics.Viewport.Height);
        }
Пример #2
0
        /// <summary>
        /// Gets an adjacent space for a model to move to in order to reach a given target.
        /// </summary>
        /// <param name="model">The model for which the next space should be found.</param>
        /// <param name="target">The model's intended destination.</param>
        /// <param name="ignoreLayers">Layers that the object ignores when pathfinding.</param>
        /// <returns>An adjacent space if the model has a path to its target, or the model's
        /// original space if there is no such path.</returns>
        public Vector2 Pathfind(WorldObjectModel model, WorldObjectModel destination)
        {
            if (!graphValid)
            {
                RebuildPathfindingGraph();
            }
            Vector2 current = model.Position.RoundComponents();
            Vector2 target  = destination.Position.RoundComponents();

            if (current == target)
            {
                // what are we doing
                return(target);
            }
            // temp var
            List <RoomGraphNode> nodesToAdd = new List <RoomGraphNode>(4);

            Dictionary <RoomGraphNode, RoomGraphNode> prevPointers = new Dictionary <RoomGraphNode, RoomGraphNode>();
            Queue <RoomGraphNode> queue = new Queue <RoomGraphNode>();

            // initial population
            prevPointers[emptySpaceGraph[current]] = null;
            queue.Enqueue(emptySpaceGraph[current]);
            while (queue.Count > 0)
            {
                RoomGraphNode currentNode = queue.Dequeue();
                // Check if we are at the target
                if (currentNode.Position == target)
                {
                    // we found it
                    while (prevPointers[currentNode].Position != current)
                    {
                        currentNode = prevPointers[currentNode];
                    }
                    return(currentNode.Position);
                }
                // TODO: Pathfinding currently ignores size completely. (Is this OK?)
                // Get current node's neighbors
                nodesToAdd.Clear();
                foreach (var adjacentNode in currentNode.AdjacencyList.GetElementsInRandomOrder())
                {
                    if (!prevPointers.ContainsKey(adjacentNode) &&
                        (adjacentNode.ModelAtNode == null ||
                         currentNode.ModelAtNode == adjacentNode.ModelAtNode ||
                         adjacentNode.ModelAtNode == destination))
                    {
                        nodesToAdd.Add(adjacentNode);
                    }
                }
                // If current node is original, we want to favor the direction that the object's currently facing
                if (currentNode.Position == current)
                {
                    for (int i = 0; i < nodesToAdd.Count; i++)
                    {
                        if (nodesToAdd[i].Position - current == model.Direction)
                        {
                            nodesToAdd.Swap(0, i);
                            break;
                        }
                    }
                }
                // Add valid neighbors to queue
                foreach (var nextNode in nodesToAdd)
                {
                    prevPointers[nextNode] = currentNode;
                    queue.Enqueue(nextNode);
                }
            }
            // couldn't find it
            Debug.Log("Couldn't find a path from " + current + " to " + target);
            return(current);
        }