6-15 河流的起点与终点

  在上一章中,我们完成了当河流笔直穿过地图单元时,河道的三角构建。在这一章中我们先来分析如何构建河流的起点与终点。这一章中我们来完成河流起点与终点的构建。
  河流的起点和终点的构建,与之前构建地图单元的方式有很大的区别。所以我们需要创建一个专门构建地图单元内河流起点与终点的方法,如果在一个地图单元内存在河流的起点或终点,那就调用这个方法进行构建。代码如下:

HexMesh.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
private void Triangulate(HexDirection direction, HexCell cell)
{


if (cell.HasRiver)
{


//检测是否为河流的起点或者终点
//如果是起点或终点,那就使用特殊的方法构建
if (cell.HasRiverBeginOrEnd)
{
TriangulateWithRiverBeginOrEnd(direction, cell, center, e);
}
else
{
TriangulateWithRiver(direction, cell, center, e);
}



}

  我们希望河流在地图单元的中心开始或终止,这里还是使用中位线的方式将其分为两个部分,我们先构建中位线到地图单元边缘的部分。这里要注意,由于起点或终点是要向地图单元的中心点聚拢的,所以我们这里依然使用各个顶点均分中位线的方式,来计算每个顶点的位置。代码如下:

HexMesh.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public class HexMesh : MonoBehaviour
{


/// <summary>
/// 构建河流起点或终点的cell
/// </summary>
/// <param name="direction">河流进入或者流出的方向</param>
/// <param name="cell">cell自身实例</param>
/// <param name="center"></param>
/// <param name="e"></param>
private void TriangulateWithRiverBeginOrEnd(HexDirection direction, HexCell cell, Vector3 center, EdgeVertices e)
{
//计算中位线上的5个顶点位置
//这里注意,由于是河流的终点或起点,所以河流整体是向内聚拢的,5个顶点对中位线进行等分
EdgeVertices m = new EdgeVertices(
Vector3.Lerp(center, e.v1, 0.5f),
Vector3.Lerp(center, e.v5, 0.5f)
);

//依然保持河道高度
m.v3.y = e.v3.y;

//构建中位线到cell边缘的梯形,这里是由4个矩形组成的,跟连接区域类似,所以使用了构建连接区域的方法
TriangulateEdgeStrip(m, cell.Color, e, cell.Color);
}
}

  接下来,可以构建中位线到地图单元中心的部分,这里已经获得了中位线上的5个顶点位置了,所以直接使用对应的方法进行构建即可。代码如下:

HexCell.cs
1
2
3
4
5
6
7
private void TriangulateWithRiverBeginOrEnd(HexDirection direction, HexCell cell, Vector3 center, EdgeVertices e)
{


//构建顶点到中位线的区域
TriangulateEdgeFan(center, m, cell.Color);
}

  至此,我们就完成了有河流起点或重点的地图单元内河道的构建。接下来的章节中,我们来分析如何构建地图单元内有拐弯的河流。

[Github代码](