Example #1
0
        /// <summary>
        /// Calculate the cost to traverse this edge based on the slope between the two tile centers
        /// </summary>
        /// <param name="n1"></param>
        /// <param name="n2"></param>
        /// <returns></returns>
        private static float CalculateCost(MapTile n1, MapTile n2) {
            var dx = Math.Abs(n1.WorldPos.X - n2.WorldPos.X);
            var dz = Math.Abs(n1.WorldPos.Z - n2.WorldPos.Z);
            var dy = Math.Abs(n1.WorldPos.Y - n2.WorldPos.Y);

            var dxz = MathF.Sqrt(dx * dx + dz * dz);
            var slope = dy / dxz;

            return 1 +slope;
        }
Example #2
0
        public Unit(BasicModelInstance model, MapTile mp, Terrain terrain) {
            _modelInstance = model;
            MapTile = mp;
            _terrain = terrain;
            _position = mp.WorldPos;
            _position.Y += HeightOffset;
            Time = 0.0f;
            _activeWP = 0;
            Moving = false;
            MovePrc = 0;

            Speed = 1.0f;
        }
        public List <MapTile> GetPath(Point start, Point goal)
        {
            var startTile = GetTile(start);
            var goalTile  = GetTile(goal);

            // check that the start and goal positions are valid, and are not the same
            if (!Within(start) || !Within(goal) || start == goal || startTile == null || goalTile == null)
            {
                return(new List <MapTile>());
            }
            // Check that start and goal are walkable and that a path can exist between them
            if (startTile.Set != goalTile.Set)
            {
                return(new List <MapTile>());
            }


            // reset costs
            foreach (var t in _tiles)
            {
                t.F = t.G = float.MaxValue;
            }
            var open   = new PriorityQueue <MapTile>(_tiles.Length);
            var closed = new HashSet <MapTile>();

            startTile.G = 0;
            startTile.F = h(start, goal);

            open.Enqueue(startTile, startTile.F);

            MapTile current = null;

            while (open.Any() && current != goalTile)
            {
                current = open.Dequeue();
                closed.Add(current);
                for (var i = 0; i < 8; i++)
                {
                    var edge = current.Edges[i];

                    if (edge == null)
                    {
                        continue;
                    }
                    var neighbor = edge.Node2;
                    var cost     = current.G + edge.Cost;



                    if (open.Contains(neighbor) && cost < neighbor.G)
                    {
                        open.Remove(neighbor);
                    }
                    if (closed.Contains(neighbor) && cost < neighbor.G)
                    {
                        closed.Remove(neighbor);
                    }
                    if (!open.Contains(neighbor) && !closed.Contains(neighbor))
                    {
                        neighbor.G = cost;
                        var f = cost + h(neighbor.MapPosition, goal);
                        open.Enqueue(neighbor, f);
                        neighbor.Parent = current;
                    }
                }
            }
            System.Diagnostics.Debug.Assert(current == goalTile);
            var path = new List <MapTile>();


            while (current != startTile)
            {
                path.Add(current);
                current = current.Parent;
            }
            path.Reverse();
            return(path);
        }
Example #4
0
        protected override void OnMouseDown(object sender, MouseEventArgs e) {
            switch (e.Button) {
                case MouseButtons.Left:
                    _minimap.OnClick(e);
                    _lastMousePos = e.Location;
                    Window.Capture = true;
                    break;
                case MouseButtons.Right:
                    // move the unit around using the right clicks
                    var ray = _camera.GetPickingRay(new Vector2(e.X, e.Y), new Vector2(Viewport.Width, Viewport.Height));

                    var tile = new MapTile();
                    var worldPos = new Vector3();

                    // do intersection test
                    if (!_terrain.Intersect(ray, ref worldPos, ref tile)) {
                        return;
                    }
                    Console.WriteLine("Clicked at " + worldPos.ToString());
                    if (tile == null) {
                        return;
                    }
                    // move the unit towards the new goal
                    Console.WriteLine("Hit tile " + tile.MapPosition);
                    Console.WriteLine("Moving unit to " + tile.MapPosition);
                    _unit.Goto(tile);
                    break;
            }
        }
Example #5
0
 public bool Intersect(Ray ray, ref Vector3 worldPos, ref MapTile mapPos) {
     Vector3 ret;
     QuadTreeNode ret2;
     if (!QuadTree.Intersects(ray, out ret, out ret2)) {
         return false;
     }
     ret.Y = Height(ret.X, ret.Z);
     worldPos = ret;
     mapPos = ret2.MapTile;
     return true;
 }
Example #6
0
 private void ResetTileMap() {
     _widthInTiles = Info.HeightMapWidth / TileSize;
     _heightInTiles = Info.HeightMapHeight / TileSize;
     _tiles = new MapTile[_widthInTiles * _heightInTiles];
     for (var i = 0; i < _tiles.Length; i++) {
         _tiles[i] = new MapTile();
     }
 }
Example #7
0
 /// <summary>
 /// Factory method to create an edge between two terrain tiles
 /// If the slope between two tiles is too great, return null, indicating that there is no connection between tiles
 /// </summary>
 /// <param name="tile"></param>
 /// <param name="neighbor"></param>
 /// <returns></returns>
 public static MapEdge Create(MapTile tile, MapTile neighbor) {
     var cost = CalculateCost(tile, neighbor);
     if (cost < 1+MapTile.MaxSlope) {
         return new MapEdge(tile, neighbor, cost);
     }
     return null;
 }
Example #8
0
 private MapEdge(MapTile n1, MapTile n2, float cost) {
     Node1 = n1;
     Node2 = n2;
     Cost = cost;
 }
Example #9
0
 private void MoveUnit(MapTile to) {
     // set the unit's last position to its current position
     _lastWP = MapTile.WorldPos;
     _lastWP.Y = _terrain.Height(_lastWP.X, _lastWP.Z) + HeightOffset;
     // set the unit's position to the next leg in the path
     MapTile = to;
     MovePrc = 0.0f;
     // set the next position to the next leg's position
     _nextWP = MapTile.WorldPos;
     _nextWP.Y = _terrain.Height(_nextWP.X, _nextWP.Z) + HeightOffset;
 }
Example #10
0
        public void Goto(MapTile mp) {
            if (_terrain == null) return;

            _path.Clear();
            _activeWP = 0;

            if (Moving) {
                _path.Add(MapTile);
                var tmpPath = _terrain.GetPath(MapTile.MapPosition, mp.MapPosition);
                _path.AddRange(tmpPath);
            } else {
                _path = _terrain.GetPath(MapTile.MapPosition, mp.MapPosition);
                if (_path.Count <= 0) {
                    // unit is already at goal position
                    return;
                }
                Moving = true;
                MoveUnit(_path[_activeWP]);
            }
        }
Example #11
0
 private MapEdge(MapTile n1, MapTile n2, float cost)
 {
     Node1 = n1;
     Node2 = n2;
     Cost  = cost;
 }
Example #12
0
        protected override void OnMouseDown(object sender, MouseEventArgs e) {
            if (e.Button == MouseButtons.Left) {
                _lastMousePos = e.Location;
                Window.Capture = true;
            } else if (e.Button == MouseButtons.Right) {
                var ray = _camera.GetPickingRay(new Vector2(e.X, e.Y), new Vector2(Viewport.Width, Viewport.Height));

                var tile = new MapTile();
                var worldPos = new Vector3();

                _showSphere = _terrain.Intersect(ray, ref worldPos, ref tile);

                _spherePos = worldPos;

                Console.WriteLine("Clicked at " + _spherePos.ToString());
                if (tile != null) {
                    Console.WriteLine("Hit tile " + tile.MapPosition);
                }
            }
        }