2-11 优化双色混合区域

  在上一章中,我们分析了应该如何进对颜色混合区域进行面数的优化,现在我们来实现这一功能。
  首先我们来优化矩形颜色混合区域,也就是两个相邻地图单元的双色混合区域。目前的混合区域是使用两个矩形进行颜色混合,也就是4个三角面片。在这里我们把一侧的的颜色混合区域宽度增加一倍。也就是在HexMetrics.GetBridge方法中,不再需要乘以0.5。

HexMetrics.cs
1
2
3
4
5
6
7
8
9
public static Vector3 GetBridge(HexDirection direction)
{
//这里对颜色混合区域进行优化
//之前的 * 0.5f 的作用是:设两个cell的颜色混合区域宽度为1
//那每个cell的颜色混合区域宽度都是 自身颜色到两者颜色相加的一半
//也就是两个相邻的cell各自混合了一半,所以该区域宽度要 *0.5f
//在这里要将两个0.5宽度的颜色混合区域合并为一个整体,所以不在需要*0.5f了
return (corners[(int)direction] + corners[(int)direction + 1]) * blendFactor;
}

  经过修改代码,现在一个矩形双色混合区域连接了两个地图单元。虽然通过·观察生成的Mesh兵没有发现什么问题,但其实在两个相邻的地图单元之间,仍然有两个矩形连接区域,只不过重叠了起来。而我们的需求是只有一个矩形双色混合区域来连接两个相邻的地图单元,所以这里要删除其中一个矩形双色混合区域。我们回到HexMesh.Triangulate(HexDirection direction, HexCell cell)方法中。先注释掉所有与构建颜色混合区域和为颜色混合区域顶点赋值的方法。创建一个新的方法,用来专门负责颜色混合区域的构建,这样避免了重复计算,使整个代码结构更加清晰。

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
28
29
30
31
32
33
private void Triangulate(HexDirection direction, HexCell cell)
{
Vector3 center = cell.transform.localPosition;
Vector3 v1 = center + HexMetrics.GetFirstSolidCorner(direction);
Vector3 v2 = center + HexMetrics.GetSecondSolidCorner(direction);

AddTriangle(center, v1, v2);
AddTriangleColor(cell.color);

TriangulateConnection(direction, cell, v1, v2);
}

/// <summary>
/// 构建cell其中一个三角面片的颜色混合区域
/// </summary>
/// <param name="direction">颜色混合区域的方位</param>
/// <param name="cell">cell自身实例,用于取得cell位置和颜色 也是三角面片的第一个顶点</param>
/// <param name="v1">自身颜色三角面片 的第二个顶点</param>
/// <param name="v2">自身颜色三角面片 的第三个顶点</param>
private void TriangulateConnection(HexDirection direction, HexCell cell, Vector3 v1, Vector3 v2)
{
HexCell neighbor = cell.GetNeighbor(direction) ?? cell;

//参考图 http://magi-melchiorl.gitee.io/pages/Pics/Hexmap/2-8-1.png
//先计算出颜色混合区域的高度,在通过v1 v2计算出v3 v4,这样就知道了矩形颜色混合区域的四个顶点了
Vector3 bridge = HexMetrics.GetBridge(direction);
Vector3 v3 = v1 + bridge;
Vector3 v4 = v2 + bridge;

//进行矩形颜色混合区域的三角面片构建和赋值顶点颜色
AddQuad(v1, v2, v3, v4);
AddQuadColor(cell.color, neighbor.color);
}

  经过修改,我们就可以很容易的控制在单个地图单元的哪个方向生成颜色混合区域了。现在我们可以尝试只在每个地图单元的NE方向生成颜色混合区域。

HexMesh.cs
1
2
3
4
5
6
7
8
9
private void Triangulate(HexDirection direction, HexCell cell)
{


if (direction == HexDirection.NE)
{
TriangulateConnection(direction, cell, v1, v2);
}
}

  根据运行结果来看,每个地图单元都生成了正确方位的双色混合区域。按照这个思路,其实每个地图单元都只需要生成NE、E和SE方向的双色混合区域就可以了,并且不会有双色混合区域的重合。

HexMesh.cs
1
2
3
4
5
6
7
8
9
private void Triangulate(HexDirection direction, HexCell cell)
{


if (direction <= HexDirection.SE)
{
TriangulateConnection(direction, cell, v1, v2);
}
}

  这样,每个地图单元之间都建立了双色混合区域连接。但是通过运行效果我们发现,在地图边缘处,有些地图单元会生成一些无用的双色混合区域连接。这里可以通过修改TriangulateConnection方法中的代码去掉这些无用的双色混合区域连接。

HexMesh.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
private void TriangulateConnection(HexDirection direction, HexCell cell, Vector3 v1, Vector3 v2)
{
//HexCell neighbor = cell.GetNeighbor(direction) ?? cell;

HexCell neighbor = cell.GetNeighbor(direction);

//当一个方位没有相邻的cell时,不生成双色混合区域
if (neighbor == null)
{
return;
}


}

  最后,我们完成了双色混合区域连接的优化,现在相邻地图单元之间只有两个三角面片组成了双色混合区域,相比之前所用的三角面片减少了一半。在下一章中,我们来优化三色混合区域。

Github代码