Пример #1
0
    public static TSVector2 Move(this SDFMap map, List <DynamicCircle> circles, FP radius, TSVector2 start, TSVector2 dir, FP len, int layerMask = -1)
    {
        start = map.SDF.WorldToLocal(start);
        TSVector2 end        = start + dir * len;
        RectInt   rect       = map.SDF.ToRect(start, end);
        int       externSize = (int)TSMath.Ceiling(radius / map.SDF.Grain);

        rect.max += new Vector2Int(externSize, externSize);
        moveFilterCache.Clear();
        map.FilterToList(moveFilterCache, rect, layerMask);

        FP        maxStepLen = radius * FP.Half;
        int       moveStep   = (int)TSMath.Ceiling(len / maxStepLen);
        TSVector2 result     = start;

        for (int i = 1; i <= moveStep; ++i)
        {
            FP moveLen = maxStepLen;
            if (i == moveStep)
            {
                moveLen = len - (moveStep - 1) * maxStepLen;
            }

            TSVector2 newPos = result + dir * moveLen;
            FP        sd     = map.Sample(newPos, moveFilterCache, circles);
            if (sd < radius)
            {
                TSVector2 gradient  = map.Gradient(moveFilterCache, circles, newPos);
                TSVector2 asjustDir = dir - gradient * TSVector2.Dot(gradient, dir);
                newPos = result + asjustDir.normalized * moveLen;
                //多次迭代
                for (int j = 0; j < 3; ++j)
                {
                    sd = map.Sample(newPos, moveFilterCache, circles);
                    if (sd >= radius)
                    {
                        break;
                    }
                    newPos += map.Gradient(moveFilterCache, circles, newPos) * (radius - sd);
                }
                //避免往返
                if (TSVector2.Dot(newPos - start, dir) < FP.Zero)
                {
                    return(result + map.SDF.Origin);
                }
                else
                {
                    result = newPos;
                }
                break;
            }
            else
            {
                result = newPos;
            }
        }
        return(result + map.SDF.Origin);
    }
Пример #2
0
    //直线移动,用于AI的移动
    public static TSVector2 StraightMove(this SDFMap map, List <DynamicCircle> circles, FP radius, TSVector2 start, TSVector2 dir, FP len, int layerMask = -1)
    {
        start = map.SDF.WorldToLocal(start);
        TSVector2 end        = start + dir * len;
        RectInt   rect       = map.SDF.ToRect(start, end);
        int       externSize = (int)TSMath.Ceiling(radius / map.SDF.Grain);

        rect.max += new Vector2Int(externSize, externSize);
        moveFilterCache.Clear();
        map.FilterToList(moveFilterCache, rect, layerMask);

        FP        maxStepLen = radius * FP.Half;
        int       moveStep   = (int)TSMath.Ceiling(len / maxStepLen);
        TSVector2 result     = start;

        for (int i = 1; i <= moveStep; ++i)
        {
            FP moveLen = maxStepLen;
            if (i == moveStep)
            {
                moveLen = len - (moveStep - 1) * maxStepLen;
            }
            TSVector2 newPos = result + dir * moveLen;
            FP        sd     = map.Sample(newPos, moveFilterCache, circles);
            if (sd < radius)
            {
                newPos = result + dir * sd;
                sd     = map.Sample(newPos, moveFilterCache, circles);
                if (sd >= radius)
                {
                    result = newPos;
                }
                break;
            }
            result = newPos;
        }
        return(result + map.SDF.Origin);
    }