Beispiel #1
0
 /// <summary>
 /// 向网格添加单位
 /// </summary>
 /// <param name="unit">Unit.</param>
 /// <param name="location">Location.</param>
 /// <param name="orientation">Orientation.</param>
 public void AddUnit(HexagonUnit unit, HexagonCell location, float orientation)
 {
     this.units.Add(unit);
     unit.transform.SetParent(this.transform, false);
     unit.Location    = location;
     unit.Orientation = orientation;
 }
 /// <summary>
 /// 目的地单元格是否可以进入
 /// </summary>
 /// <returns><c>true</c> if this instance is valid destination the specified cell; otherwise, <c>false</c>.</returns>
 /// <param name="cell">Cell.</param>
 public bool IsValidDestination(HexagonCell cell)
 {
     // 目标单元格不在水底
     // return !cell.IsUnderwater;
     // 目标单元格内没有其他单位
     return(!cell.Unit);
 }
 public void AddCell(int index, HexagonCell cell)
 {
     this.cells[index] = cell;
     cell.chunk        = this;
     cell.transform.SetParent(transform, false);
     cell.uiRect.SetParent(gridCanvas.transform, false);
 }
        /// <summary>
        /// 三角形化网格
        /// </summary>
        /// <param name="cell"></param>
        private void Triangulate(HexagonCell cell)
        {
            Vector3 center = cell.transform.localPosition;

            for (int i = 0; i < 6; i++)
            {
                this.terrain.AddTriangle(center, cell.Corners[i], cell.Corners[i + 1]);
                this.terrain.AddTriangleColor(cell.Color);
            }
        }
Beispiel #5
0
        /// <summary>
        /// 单元格添加到指定的块
        /// </summary>
        /// <param name="widthIndex"></param>
        /// <param name="heightIndex"></param>
        /// <param name="cell"></param>
        private void AddCellToChunk(int widthIndex, int heightIndex, HexagonCell cell)
        {
            int chunkX             = widthIndex / HexagonGrid.chunkSizeWidth;
            int chunkZ             = heightIndex / HexagonGrid.chunkSizeHeight;
            HexagonGridChunk chunk = this.chunks [chunkX + chunkZ * this.chunkCountWidth];

            int localX = widthIndex - chunkX * HexagonGrid.chunkSizeWidth;
            int localZ = heightIndex - chunkZ * HexagonGrid.chunkSizeHeight;

            chunk.AddCell(localX + localZ * HexagonGrid.chunkSizeWidth, cell);
        }
Beispiel #6
0
 /// <summary>
 /// 查找两个单元格之间的路径
 /// </summary>
 /// <param name="fromCell"></param>
 /// <param name="toCell"></param>
 public void FindPath(HexagonCell fromCell, HexagonCell toCell, int speed)
 {
     // 测试寻路的时间花费
     //System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
     //sw.Start();
     this.ClearPath();              // 清除上次的检索结果
     this.currentPathFrom   = fromCell;
     this.currentPathTo     = toCell;
     this.currentPathExists = this.Search(fromCell, toCell, speed);
     this.ShowPath(speed);              // 高亮检索到的路径
     //sw.Stop();
     //Debug.Log(sw.ElapsedMilliseconds);
 }
 public HexagonCell Dequeue()
 {
     this.count -= 1;
     for (; this.minimum < list.Count; minimum++)
     {
         HexagonCell cell = this.list[minimum];
         if (cell != null)
         {
             this.list[minimum] = cell.NextWithSamePriority;
             return(cell);
         }
     }
     return(null);
 }
Beispiel #8
0
 /// <summary>
 /// 清除路径
 /// </summary>
 public void ClearPath()
 {
     if (currentPathExists)
     {
         HexagonCell current = currentPathTo;
         while (current != currentPathFrom)
         {
             current.SetLabel(null);
             current.DisableHighlight();
             current = current.PathFrom;
         }
         current.DisableHighlight();
         currentPathExists = false;
     }
     currentPathFrom = currentPathTo = null;
 }
Beispiel #9
0
 /// <summary>
 /// 高亮路径
 /// </summary>
 /// <param name="speed"></param>
 private void ShowPath(int speed)
 {
     if (currentPathExists)
     {
         HexagonCell current = this.currentPathTo;
         while (current != currentPathFrom)
         {
             int turn = (current.Distance - 1) / speed;
             current.SetLabel(turn.ToString());
             current.EnableHighlight(Color.white);
             current = current.PathFrom;
         }
     }
     currentPathFrom.EnableHighlight(Color.blue);
     currentPathTo.EnableHighlight(Color.red);
 }
        public void Enqueue(HexagonCell cell)
        {
            this.count += 1;
            int priority = cell.SearchPriority;

            if (priority < this.minimum)
            {
                this.minimum = priority;
            }
            while (priority >= this.list.Count)
            {
                this.list.Add(null);
            }
            cell.NextWithSamePriority = list[priority];
            this.list[priority]       = cell;
        }
Beispiel #11
0
        /// <summary>
        /// 获取路径经过的单元格
        /// </summary>
        /// <returns>The path.</returns>
        public List <HexagonCell> GetPath()
        {
            if (!this.currentPathExists)
            {
                return(null);
            }
            List <HexagonCell> path = ListPool <HexagonCell> .Get();

            for (HexagonCell c = this.currentPathTo; c != this.currentPathFrom; c = c.PathFrom)
            {
                path.Add(c);
            }
            // 从终点到起点
            path.Add(this.currentPathFrom);
            // 反转
            path.Reverse();
            return(path);
        }
Beispiel #12
0
 private void Refresh()
 {
     if (this.chunk)
     {
         this.chunk.Refresh();
         for (int i = 0; i < neighbors.Length; i++)
         {
             HexagonCell neighbor = neighbors [i];
             if (neighbor != null && neighbor.chunk != chunk)
             {
                 neighbor.chunk.Refresh();
             }
         }
         if (this.Unit)
         {
             this.Unit.ValidateLocation();
         }
     }
 }
        public void Change(HexagonCell cell, int oldPriority)
        {
            HexagonCell current = list[oldPriority];
            HexagonCell next    = current.NextWithSamePriority;

            if (current == cell)
            {
                this.list[oldPriority] = next;
            }
            else
            {
                while (next != cell)
                {
                    current = next;
                    next    = current.NextWithSamePriority;
                }
                current.NextWithSamePriority = cell.NextWithSamePriority;
            }
            // 单元格删除后,必须重新添加单元格,以便最终在列表中显示新的优先级。
            this.Enqueue(cell);
            // Enqueue方法增加了计数,但是实际上并没有添加新的单元格。所以我们不得不减少这个计数来进行补偿。
            this.count -= 1;
        }
Beispiel #14
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="direction"></param>
 /// <param name="cell"></param>
 public void SetNeighbor(HexagonDirection direction, HexagonCell cell)
 {
     this.neighbors [(int)direction]            = cell;
     cell.neighbors [(int)direction.Opposite()] = this;
 }
Beispiel #15
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="cell"></param>
        /// <returns></returns>
        private bool Search(HexagonCell fromCell, HexagonCell toCell, int speed)
        {
            this.searchFrontierPhase += 2;

            if (this.searchFrontier == null)
            {
                this.searchFrontier = new HexagonCellPriorityQueue();
            }
            else
            {
                this.searchFrontier.Clear();
            }

            // toCell.EnableHighlight(Color.red);
            fromCell.SearchPhase = searchFrontierPhase;
            fromCell.Distance    = 0;
            this.searchFrontier.Enqueue(fromCell);
            while (this.searchFrontier.Count > 0)
            {
                // yield return delay;
                HexagonCell current = searchFrontier.Dequeue();
                current.SearchPhase += 1;

                // 找到目标单元格时结束循环
                if (current == toCell)
                {
                    return(true);
                }

                // 计算移动到目的需要的回合数

                int currentTurn = (current.Distance - 1) / speed;
                for (HexagonDirection d = HexagonDirection.NE; d <= HexagonDirection.NW; d++)
                {
                    HexagonCell neighbor = current.GetNeighbor(d);
                    if (neighbor == null || neighbor.SearchPhase > searchFrontierPhase)
                    {
                        continue;
                    }
                    if (neighbor.Unit)
                    {
                        //  单元格中有单位的时候跳过这个单元格
                        continue;
                    }
                    // 避开有水的地方
                    //if (neighbor.IsUnderwater)
                    //{
                    //    continue;
                    //}
                    // 避开悬崖
                    //if (current.GetEdgeType(neighbor) == HexEdgeType.Cliff)
                    //{
                    //    continue;
                    //}
                    // 沿着道路移动更快
                    // int distance = current.Distance;
                    // 根据移动成本计算
                    int moveCost = 1;
                    //if (current.HasRoadThroughEdge(d))
                    //{
                    //    moveCost = 1;
                    //}
                    //else if (current.Walled != neighbor.Walled)
                    //{
                    //    continue;
                    //}
                    //else
                    //{
                    //    moveCost = edgeType == HexEdgeType.Flat ? 5 : 10;
                    //    moveCost += neighbor.UrbanLevel + neighbor.FarmLevel +
                    //    neighbor.PlantLevel;
                    //}
                    int distance = current.Distance + moveCost;
                    // distance += 1;

                    // 计算移动到目的需要的回合数
                    int turn = (distance - 1) / speed;
                    if (turn > currentTurn)
                    {
                        distance = turn * speed + moveCost;
                    }


                    //if (neighbor.Distance == int.MaxValue)
                    if (neighbor.SearchPhase < this.searchFrontierPhase)
                    {
                        neighbor.SearchPhase = this.searchFrontierPhase;
                        neighbor.Distance    = distance;
                        // neighbor.SetLabel(turn.ToString());
                        neighbor.PathFrom        = current;
                        neighbor.SearchHeuristic = neighbor.Coordinates.DistanceTo(toCell.Coordinates);
                        this.searchFrontier.Enqueue(neighbor);
                    }
                    else if (distance < neighbor.Distance)
                    {
                        neighbor.Distance = distance;
                        // neighbor.SetLabel(turn.ToString());
                        neighbor.PathFrom = current;
                    }
                }
            }

            return(false);
        }