protected override void Initialize() { Window.AllowUserResizing = true; IsMouseVisible = true; base.Initialize(); Input.SetWindow(Window); _offset = new Vector2(-DrawDistance * Chunk.Size * 8) / 2f; _chunkUpdates = new float[DrawDistance, DrawDistance]; _world = new World(World_ChunkRequest); _world.OnBuildOrder += (w, c, order) => { _chunkUpdates[c.Position.X, c.Position.Y] = ChunkUpdateDuration; }; _client = new NetGameClient(); _client.Open(); System.Threading.Tasks.Task.Run(() => { _client.Connect(IPAddress.Loopback, AppConstants.NetDefaultPort); Thread.Sleep(500); var grid = new byte[DrawDistance * Chunk.Size, DrawDistance * Chunk.Size]; while (true) { for (int i = 0; i < grid.GetLength(0); i++) { for (int j = 0; j < grid.GetLength(1); j++) { var tp = new TilePosition(i, j); if (_world.TryGetChunk(ChunkPosition.FromTile(tp), out var chunk)) { grid[i, j] = (byte)Math.Min((ushort)1, chunk.GetTile(tp.LocalX, tp.LocalY).ID); } } } var finder = new PathFinder(grid); _path = finder.FindPath(new TilePosition(80, 80), new TilePosition(100, 100)); Thread.Sleep(250); } }); }
protected override void Update(GameTime time) { Input.Update(time); if (Input.IsKeyDown(Keys.Escape)) { Exit(); } _client.ReadMessages(); ProcessReceivedMessages(); _world.Update(time); if (Input.IsKeyDown(Keys.D1)) { _brushTile = new Tile(0); } else if (Input.IsKeyDown(Keys.D2)) { _brushTile = new Tile(1); } else if (Input.IsKeyDown(Keys.D3)) { _brushTile = new Tile(2); } else if (Input.IsKeyDown(Keys.D4)) { _brushTile = new Tile(3); } var view = GraphicsDevice.Viewport; _transform = Matrix.CreateTranslation(_offset.ToVector3()) * Matrix.CreateScale(_zoom) * Matrix.CreateTranslation(view.Width / 2f, view.Height / 2f, 0); var invertedWorld = Matrix.Invert(_transform); _mouseInWorld = Vector2.Transform(Input.MousePosition.ToVector2(), invertedWorld); var tmp = _mouseInWorld / 8f; _selectedTile = new Point((int)tmp.X, (int)tmp.Y); _zoom = MathHelper.Clamp(_zoom + Input.MouseScroll / 1000, 0.5f, 4f); if (Input.IsMouseDown(MouseButton.Right)) { _offset += Input.MouseVelocity.ToVector2() / _zoom; } if (Input.IsMouseDown(MouseButton.Left) && _client.IsConnected) { const int brushSize = 3; for (int y = 0; y < brushSize * 2; y++) { for (int x = 0; x < brushSize * 2; x++) { var brushCenter = _selectedTile + new Point(x - brushSize, y - brushSize); var chunkPos = ChunkPosition.FromTile((TilePosition)brushCenter); if (chunkPos.X >= 0 && chunkPos.X < DrawDistance && chunkPos.Y >= 0 && chunkPos.Y < DrawDistance) { if (_world.TryGetChunk(chunkPos, out var chunk)) { var tilePos = new Point(brushCenter.X % 16, brushCenter.Y % 16); chunk.TrySetTile(tilePos.X, tilePos.Y, _brushTile); } } } } } for (int y = 0; y < _chunkUpdates.GetLength(1); y++) { for (int x = 0; x < _chunkUpdates.GetLength(0); x++) { if (_chunkUpdates[x, y] > 0) { _chunkUpdates[x, y] -= time.Delta; } else { _chunkUpdates[x, y] = 0; } } } base.Update(time); }
public static void BreadthFirstSearch(World world, TilePosition start, TilePosition end) { var comparer = new DistanceToEndComparer(end); var frontier = new List <Node>(); var visited = new HashSet <TilePosition>(); // drawing/debugging junk _frontier = frontier; _visited = visited; Begin: lock (frontier) { frontier.Add(new Node(start, 0)); frontier.Sort(comparer); } void Sleep() { Thread.Sleep(500); lock (frontier) frontier.Clear(); lock (visited) visited.Clear(); } while (frontier.Count > 0) { Node current = frontier[frontier.Count - 1]; lock (frontier) frontier.RemoveAt(frontier.Count - 1); if (world.TryGetChunk(ChunkPosition.FromTile(start), out Chunk startChunk)) { if (!startChunk.TryGetTile(end.LocalX, end.LocalY, out Tile tile) || tile.ID == 0) { Sleep(); goto Begin; } } if (world.TryGetChunk(ChunkPosition.FromTile(end), out Chunk endChunk)) { if (!endChunk.TryGetTile(end.LocalX, end.LocalY, out Tile tile) || tile.ID == 0) { Sleep(); goto Begin; } } var adjacents = new TilePosition[8] { new TilePosition(-1, 1), new TilePosition(0, 1), new TilePosition(1, 1), new TilePosition(-1, 0), new TilePosition(1, 0), new TilePosition(-1, -1), new TilePosition(0, -1), new TilePosition(1, -1), }; foreach (var a in adjacents) { var tilePos = new TilePosition(current.Position.X + a.X, current.Position.Y + a.Y); var chunkPos = ChunkPosition.FromTile(tilePos); if (chunkPos.X < 0 || chunkPos.X >= 12 || chunkPos.Y < 0 || chunkPos.Y >= 12) { continue; } if (world.TryGetChunk(chunkPos, out Chunk chunk)) { if (!visited.Contains(tilePos) && chunk.GetTile(tilePos.LocalX, tilePos.LocalY).ID != 0) { lock (frontier) { frontier.Add(new Node(tilePos, current.Cost + 1)); frontier.Sort(comparer); } lock (visited) visited.Add(tilePos); if (tilePos == end) { if (Continue) { Sleep(); goto Begin; } } if (a.X == 0) { Thread.Sleep(1); } } } } } Sleep(); goto Begin; }