相信大家玩过类似用接水管的游戏:

水流顺着水管的一头流向另一头,但是直管通过,遇到弯管改变方向,那么究竟是如何改变方向的呢?
仔细观察一下,不难发现,弯管只是将水流的方向旋转了90度,有了规律就好办了!

1.让我们先定义一个方向的枚举,表示当前水流的方向:

1
2
3
4
5
6
7
8
enum ETileDirection
{
ED_UP,
ED_RIGHT,
ED_DOWN,
ED_LEFT,
ED_TICK_COUNT,
};

这个枚举定义可以是顺时针,也可以是逆时针,但一定要是连续的!

2.当地图编辑好后,我们会获得一个二维数组,通过一个x,y参数就能取得某个坐标上的图块,根据图块的功能,我们可以讲图块分为:入口, 出口, 直管, 弯管, 于是我们可以再定义一个枚举:

1
2
3
4
5
6
7
enum ETileType
{
ET_ENTRANCE,
ET_EXIT,
ET_STRAIGHT,
ET_ELBOW,
};

3.仔细想想,除了直管每一种类型的图块都会有,都会有四个方向,对于入口,会有向左的,向右的,向下的,向上的,终点,弯管也是如此!这样的话,我们一个图块的属性都会有两个,类型方向,我们用一个结构体来表示:

1
2
3
4
5
struct STile
{
ETileType eType;
ETileDirection eDirection;
};

4.如下面这个砖块:

当水流从右侧进入时水流的方向也是ED_LEFT,出去的水流方向是什么呢?是ED_LEFT+1,因为方向的可能只有4个,所以我们需要和方向的总数量取余,即(eDir+1)%ED_TICK_COUNTED_UP.

当水流是从上方进入时方向为ED_DOWN,出去时的方向为ED_DOWN-1,但是减完有可能会出现负数,所以我们先扩大一个周期在减然后取余,即((eDir+ED_TICK_COUNT)-1)%ED_TICK_COUNTED_RIGHT.

那么如何区分是顺时针还是逆时针呢?我们之前Tile的eDirection属性就派上用场了,我们将这个图块的方向属性设置为ED_LEFT,细思之后会发现当图块的方向和水流方向一致时+1,不一致时-1.

好吧,说了这么久,让我们来看看具体的逻辑如何写吧?

1
2
3
4
5
6
7
8
9
10
11
ETileDirection changeDirection(ETileDirection eDir,const STile* pProfile )
{
ASSERT(pProfile->eType==ET_ELBOW);

if (pProfile->eDirection==eDir)
{
return (ETileDirection)(((eDir+ED_TICK_COUNT)-1)%ED_TICK_COUNT);
}

return (ETileDirection)((eDir+1)%ED_TICK_COUNT);
}

如果有什么不明白的,留言告诉我!

全文完