/// <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); } }
/// <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); }
/// <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); }
/// <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; }
/// <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; }
/// <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); }
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; }
/// <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; }
/// <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); }