Пример #1
0
        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);
                }
            });
        }
Пример #2
0
        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);
        }
Пример #3
0
        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;
        }