Beispiel #1
0
        /// <summary>
        /// This is called when the game should draw itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.White);

            spriteBatch.Begin(samplerState: SamplerState.PointClamp);

            //render out the path
            PathCell current = finderCell;

            while (current != null)
            {
                spriteBatch.Draw(pixel, new Rectangle(current.x * 2, current.y * 2, 2, 2), Color.Red);
                current = current.parent;
            }

            //render obstacles
            //if a path intersects an obstacle, it will be easier to tell
            for (int i = 0; i < 100; i++)
            {
                for (int j = 0; j < 100; j++)
                {
                    if (!Pathfinder.pathMap[i, j])
                    {
                        spriteBatch.Draw(pixel, new Rectangle(i * 2, j * 2, 2, 2), Color.Black);
                    }
                }
            }

            spriteBatch.End();

            base.Draw(gameTime);
        }
Beispiel #2
0
        /// <summary>
        /// Get all walkable cells adjacent to a specified cell.
        /// </summary>
        /// <param name="focus">The cell to search around.</param>
        /// <param name="open">The list of currently-open cells.</param>
        /// <returns>A list of valid adjacent cells.</returns>
        static List <PathCell> GetAdjacentCells(PathCell focus, List <PathCell> open)
        {
            List <PathCell> adjacent = new List <PathCell>();

            for (int i = -1; i <= 1; i++)
            {
                for (int j = -1; j <= 1; j++)
                {
                    //make sure coord is safe
                    if (focus.x + i > 0 &&
                        focus.x + i < pathMap.GetLength(0) &&
                        focus.y + j > 0 &&
                        focus.y + j < pathMap.GetLength(1))
                    {
                        //make sure its walkable
                        if (pathMap[focus.x + i, focus.y + j])
                        {
                            //find node, create it if necessary, and add to returned list
                            PathCell node = open.Find(c => c.x == focus.x + i && c.y == focus.y + j);
                            if (node == null)
                            {
                                adjacent.Add(new PathCell(focus.x + i, focus.y + j));
                            }
                            else
                            {
                                adjacent.Add(node);
                            }
                        }
                    }
                }
            }

            return(adjacent);
        }
Beispiel #3
0
        /// <summary>
        /// Allows the game to perform any initialization it needs to before starting to run.
        /// This is where it can query for any required services and load any non-graphic
        /// related content.  Calling base.Initialize will enumerate through any components
        /// and initialize them as well.
        /// </summary>
        protected override void Initialize()
        {
            // TODO: Add your initialization logic here

            Pathfinder.BuildMap();
            finderCell = Pathfinder.FindPath();

            base.Initialize();
        }
Beispiel #4
0
        /// <summary>
        /// Allows the game to run logic such as updating the world,
        /// checking for collisions, gathering input, and playing audio.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Update(GameTime gameTime)
        {
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape))
            {
                Exit();
            }

            //generate a new path
            if (Keyboard.GetState().IsKeyDown(Keys.Space))
            {
                finderCell = Pathfinder.FindPath();
            }

            base.Update(gameTime);
        }
Beispiel #5
0
        /// <summary>
        /// Find a path between the origin and a randomly-generated goal.
        /// </summary>
        /// <returns>The endpoint of the path.</returns>
        public static PathCell FindPath()
        {
            //define start & goal
            PathCell start = new PathCell(0, 0);

            //generate a goal
            int goalX = rng.Next(0, 99);
            int goalY = rng.Next(0, 99);

            pathMap[goalX, goalY] = true; //make sure its attainable
            PathCell goal = new PathCell(goalX, goalY);

            //prep algorithm
            PathCell current = null;

            List <PathCell> open   = new List <PathCell>();
            List <PathCell> closed = new List <PathCell>();

            int g = 0;

            open.Add(start);

            while (open.Count > 0)
            {
                //get square with lowest f
                var lowestF = open.Min(c => c.f);
                current = open.First(c => c.f == lowestF);

                //move current to closed
                closed.Add(current);
                open.Remove(current);

                //if goal is in closed list, we're done
                if (closed.FirstOrDefault(c => c.x == goal.x && c.y == goal.y) != null)
                {
                    break;
                }

                //find adjacent tiles
                List <PathCell> adjacent = GetAdjacentCells(current, open);
                g = current.g + 1;

                //loop through adjacent
                foreach (PathCell a in adjacent)
                {
                    //make sure it isn't already closed
                    if (closed.FirstOrDefault(c => c.x == a.x && c.y == a.y) != null)
                    {
                        continue;
                    }

                    //create and add to open if not open either
                    if (open.FirstOrDefault(c => c.x == a.x && c.y == a.y) == null)
                    {
                        //set metrics
                        a.g      = g;
                        a.h      = CalculateH(a, goal);
                        a.f      = a.g = a.h;
                        a.parent = current;

                        //add to top of open list
                        open.Insert(0, a);
                    }
                    else //is already open
                    {
                        //update g if this path is more efficient
                        if (g + a.h < a.f)
                        {
                            a.g      = g;
                            a.f      = a.g + a.h;
                            a.parent = current;
                        }
                    }
                }
            }

            return(current);
        }
Beispiel #6
0
 /// <summary>
 /// Calcualte the h score of a cell.
 /// </summary>
 /// <param name="cell">The cell to calculate for.</param>
 /// <param name="goal">The goal cell.</param>
 /// <returns>The h value.</returns>
 static int CalculateH(PathCell cell, PathCell goal)
 {
     return(Math.Abs(goal.x - cell.x) + Math.Abs(goal.y - cell.y));
 }