0
点赞
收藏
分享

微信扫一扫

网格遍历算法

yundejia 2022-04-14 阅读 75

前言

这算是平面游戏里非常常见的一种需求了。
对某个物品或者角色,判定其周围环境的一些属性、交互。
我在开发修仙模拟器的mod时接触过这个算法。
由于这个需求过于常见,单独拎出来。

需求定义&解法

以自身坐标为0. 遍历所有网格。
在这里插入图片描述
见上图,定义两个控制量。

从0出发,初始方向为下,步长为1。

每经历两次“进—转”,需要更新步长。现将步长设为2。

又经历两次“进—转”,更新步长为3。

其中转向的规律是相同的,一共只有上下左右四个方向。
想逆时针,下转左,左转上,上转右,右转下。

一个list获得所有的offset(x,y)。

class MY : Object
{
    public void GetGridXY(ref int X, ref int Y, g_emGridDir dir)
    {
        if (dir == g_emGridDir.Left || dir == g_emGridDir.LeftUp || dir == g_emGridDir.LeftDown)
        {
            X--;
        }
        if (dir == g_emGridDir.Right || dir == g_emGridDir.RightDown || dir == g_emGridDir.RightUp)
        {
            X++;
        }
        if (dir == g_emGridDir.Up || dir == g_emGridDir.LeftUp || dir == g_emGridDir.RightUp)
        {
            Y++;
        }
        if (dir == g_emGridDir.Down || dir == g_emGridDir.RightDown || dir == g_emGridDir.LeftDown)
        {
            Y--;
        }
    }


    private void AroundGrids()
    {


        int radius = 3;
        int numTotalGrids = (radius * 2 + 1) * (radius * 2 + 1);

        int stride = 1; //步长
        int counter = 2; //变长计数器,总是2

        g_emGridDir g_emGridDir = g_emGridDir.Down;
        int offsetX = 0;
        int offsetY = 0;

        List<int[]> listOffsets = new List<int[]>();
        listOffsets.Add(new int[]
        {
            offsetX,
            offsetY
        });

        int j = 1;
        while (j < numTotalGrids)
        {
            while (counter > 0)
            {
                for (int k = 0; k < stride; k++)
                {
                    GetGridXY(ref offsetX, ref offsetY, g_emGridDir);
                    listOffsets.Add(new int[]
                    {
                        offsetX,
                        offsetY
                    });

                    j++;
                    if (j >= numTotalGrids)
                    {
                        return; //出口
                    }
                }
                //改变方向
                if (g_emGridDir == g_emGridDir.Right)
                {
                    g_emGridDir = g_emGridDir.Down;
                }
                else if (g_emGridDir == g_emGridDir.Down)
                {
                    g_emGridDir = g_emGridDir.Left;
                }
                else if (g_emGridDir == g_emGridDir.Left)
                {
                    g_emGridDir = g_emGridDir.Up;
                }
                else if (g_emGridDir == g_emGridDir.Up)
                {
                    g_emGridDir = g_emGridDir.Right;
                }
                counter--; //改变了方向,更新变长计数器
            }
            //每两次变长计数,步长+1
            counter = 2;
            stride++;
        }
        return listOffsets;
    }
}

这种写法存的是 offset(x,y)
想直接存全局坐标,只需要改中间的部分就行了。

举报

相关推荐

0 条评论