//TODO: Checker, Remover, Replacer(, Connector) multithreaded private static void Checker() { List <GridNode> pathList = path.ToList(); // Gridnoden för de delar som har tagits bort var gridnodeStartingPoints = new HashSet <GridNode>(); //SAME: Ifall det finns en node på samma x- eller y-axel två steg bort bool Same(int i, int additional) { if (i - 2 - additional < 0 || i + 2 + additional > pathList.Count - 1) { return(false); } bool firstSameX = pathList[i - 2 - additional].Location.X == pathList[i].Location.X && pathList[i - 2 - additional].Location.Y != pathList[i].Location.Y; bool firstSameY = pathList[i - 2 - additional].Location.Y == pathList[i].Location.Y && pathList[i - 2 - additional].Location.X != pathList[i].Location.X; bool secondSameX = pathList[i + 2 + additional].Location.X == pathList[i].Location.X && pathList[i + 2 + additional].Location.Y != pathList[i].Location.Y; bool secondSameY = pathList[i + 2 + additional].Location.Y == pathList[i].Location.Y && pathList[i + 2 + additional].Location.X != pathList[i].Location.X; return((firstSameX || secondSameX) && (firstSameY || secondSameY)); } void AddListRange(int index, int range) { for (int i = index - range; i <= index + range; i++) { invalidNodes.AddLast(pathList[i]); } } for (int i = 2; i < pathList.Count; i++) { int skip = 2; if (Same(i, 0)) { //SAME fast [i +/- 2 +/- j], ska kolla ifall det finns några nodes innan/efter som ligger på samma x- eller y-axel for (int j = 1; Same(i, j); j++, skip++) { } AddListRange(i, skip); gridnodeStartingPoints.Add(i == skip ? path.First() : path.ElementAt(i - skip - 1)); Obstacle temp = new Obstacle(new Rectangle(pathList[i].Location, new Point(WorldGeneration.NodeSize))); if (!WorldGeneration.Obstacles.Contains(temp)) { WorldGeneration.AddTempStacle(temp); } i += skip; } } if (gridnodeStartingPoints.Count > 0) { //Ta bort path //Gör ny path genom att köra AStar mellan Start, startingNodes, goal Replacer(gridnodeStartingPoints, WorldGeneration.TemporaryObstacles); } }
protected override void Initialize() { WorldGeneration.Screen = new Rectangle(0, 0, 800, 800); WorldGeneration.NodeSize = 80; WorldGeneration.WorldGenerationType = WorldGenType.Random; WorldGeneration.Generate(); //GridNode.Weight = 5; PathFindAStar(); keyDelay = 0f; base.Initialize(); }
/// <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.CornflowerBlue); spriteBatch.Begin(); string times = ""; if (showPathInfo) { times = $"PathTime: {pathTime}s\nOpenLLGN: {openLLGN.Count}\nClosedLLGN: {closedLLGN.Count}\nReachedGoal: {Pathfinder.ReachedGoal}\n" + $"NodeSize: {WorldGeneration.NodeSize}\nObstacleCount: {WorldGeneration.NumberOfObstacles}\n\nStart: {WorldGeneration.Start.ScalePoint()}\n" + $"Goal: {WorldGeneration.Goal.ScalePoint()}"; } void DrawNodeInfo(GridNode node) => spriteBatch.DrawString( nodeSF, $"X:{node.LocationNodeScaled.X}\nY:{node.LocationNodeScaled.Y}", node.Location.ToVector2(), Color.Red); void DrawListConditional(LinkedList <GridNode> list, Color listNodeColor, Action <GridNode> drawData, bool drawDataIf) { foreach (var node in list) { spriteBatch.Draw(WorldGeneration.TileTexture, new Rectangle(node.Location, new Point(WorldGeneration.NodeSize, WorldGeneration.NodeSize)), listNodeColor); if (drawDataIf) { drawData(node); } } } DrawListConditional(openLLGN, Color.Gray, DrawNodeInfo, showNodeInfo); DrawListConditional(closedLLGN, Color.LightGray, DrawNodeInfo, showNodeInfo); DrawListConditional(pfPath, Color.White, node => { }, false); WorldGeneration.DrawWorld(spriteBatch); if (showInvalidPath) { DrawListConditional(Pathfinder.InvalidNodes, Color.DarkRed, node => { }, false); DrawListConditional(Pathfinder.ChildStartGoals, Color.Magenta, node => { }, false); } if (!string.IsNullOrEmpty(times)) { spriteBatch.DrawString(sf, times, new Vector2(6, 6), Color.Red); } spriteBatch.End(); base.Draw(gameTime); }
/// <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(); } KeyboardState state = Keyboard.GetState(); if (IsActive) { if (keyDelay == 0f) { if (state.IsKeyDown(Keys.R)) { WorldGeneration.Generate(); PathFindAStar(); } else if (state.IsKeyDown(Keys.F11)) { showPathInfo = !showPathInfo; } else if (state.IsKeyDown(Keys.F10)) { showNodeInfo = !showNodeInfo; } else if (state.IsKeyDown(Keys.F9)) { showInvalidPath = !showInvalidPath; } keyDelay = 100f; } if (state.IsKeyDown(Keys.LeftControl)) { if (state.IsKeyDown(Keys.L)) { pfLoader = new PreFab.PreFabLoader(); pfLoader.Show(); } else if (state.IsKeyDown(Keys.S)) { pfSaver = new PreFab.PreFabSaver(); pfSaver.Show(); } } } keyDelay -= gameTime.ElapsedGameTime.Milliseconds > keyDelay ? keyDelay : gameTime.ElapsedGameTime.Milliseconds; base.Update(gameTime); }
private static void LogException(Action a) { try { a(); } catch (Exception e) { int crashNumber = System.IO.Directory.GetFiles(System.IO.Directory.GetCurrentDirectory(), "*.dat").Select(file => file.StartsWith("Crash_")).Count() + 1; PreFab.PreFabUser.Write($"Crash_{crashNumber}.dat"); System.IO.File.WriteAllText($"CrashReport_{crashNumber}.txt", e.Source + "\n\n" + e.Message); } finally { WorldGeneration.Generate(); //Program.GameT.PathFindAStar(); } }