Exemple #1
0
    public void Lower(int pos)
    {
        if (this._Values.Count == 0)
        {
            return;
        }
        int num  = pos;
        int num2 = pos * 2 + 1;
        int num3 = pos * 2 + 2;

        while (true)
        {
            int num4 = num;
            num2 = num * 2 + 1;
            num3 = num * 2 + 2;
            if (num2 < this._Values.Count && HValue.Compare(this._Values[num2], this._Values[num4]))
            {
                num4 = num2;
            }
            if (num3 < this._Values.Count && HValue.Compare(this._Values[num3], this._Values[num4]))
            {
                num4 = num3;
            }
            if (num4 == num)
            {
                break;
            }
            HValue value = this._Values[num];
            this._Values[num]  = this._Values[num4];
            this._Values[num4] = value;
            num = num4;
        }
    }
Exemple #2
0
    /// <summary>
    /// 什么算法,我很懵逼啊?????????????
    /// </summary>
    /// <param name="p"></param>
    /// <param name="c"></param>
    /// <returns></returns>
    private int GetDirection(HValue p, HValue c)
    {
        int num  = (int)(c.X - p.X);
        int num2 = (int)(c.Y - p.Y);

        return((num + 1) * 3 + num2);
    }
Exemple #3
0
    public void Push(HValue value)
    {
        this._Values.Add(value);
        int pos = this._Values.Count - 1;

        this.Upper(pos);
        this.PushCount++;
    }
Exemple #4
0
 /// <summary>
 /// 比较评估
 /// </summary>
 /// <param name="left"></param>
 /// <param name="right"></param>
 /// <returns></returns>
 public static bool Compare(HValue left, HValue right)
 {
     if (Math.Abs(right.Key - left.Key) < 0.1f)          //key值相等   ,比较cost
     {
         return(Math.Abs(right.Cost - left.Cost) >= 0.1f && left.Cost > right.Cost);
     }
     return(left.Key < right.Key);
 }
Exemple #5
0
 public HValue Pop()
 {
     if (this._Values.Count >= 1)
     {
         HValue result = this._Values[0];
         this._Values[0] = this._Values[this._Values.Count - 1];
         this._Values.RemoveAt(this._Values.Count - 1);
         this.Lower(0);
         return(result);
     }
     return(new HValue());
 }
Exemple #6
0
 public int Find(HValue instance)
 {
     if (this._Values != null)
     {
         for (int i = 0; i < this._Values.Count; i++)
         {
             if (instance.X == this._Values[i].X && instance.Y == this._Values[i].Y)
             {
                 return(i);
             }
         }
     }
     return(-1);
 }
Exemple #7
0
    public void Upper(int pos)
    {
        int num  = pos;
        int num2 = (pos - 1) / 2;

        while (true)
        {
            num2 = (num - 1) / 2;
            if (num == 0 || !HValue.Compare(this._Values[num], this._Values[num2]))
            {
                break;
            }
            HValue value = this._Values[num];
            this._Values[num]  = this._Values[num2];
            this._Values[num2] = value;
            num = num2;
        }
    }
Exemple #8
0
 /// <summary>
 /// 获取分配给指定网格坐标的缓存索引
 /// </summary>
 /// <param name="x"></param>
 /// <param name="y"></param>
 /// <returns></returns>
 private HValue getHValue(int x, int y)
 {
     if (this.path[x, y] == -1)
     {
         if (this.cacheIndex == this.cacheCount)             //缓存索引达到最大缓存数量,最大缓存数加1000
         {
             for (int i = 0; i < 1000; i++)
             {
                 HValue hValue = new HValue();
                 hValue.Reset();
                 this.HValueCache.Add(hValue);
             }
             this.cacheCount += 1000;
         }
         this.path[x, y] = this.cacheIndex;
         this.cacheIndex++;
     }
     return(this.HValueCache[this.path[x, y]]);
 }
Exemple #9
0
    public bool Validate()
    {
        bool flag = true;

        for (int i = 0; i < this._Values.Count; i++)
        {
            if (i * 2 + 1 < this._Values.Count && HValue.Compare(this._Values[2 * i + 1], this._Values[i]))
            {
                flag = false;
            }
            if (i * 2 + 2 < this._Values.Count && HValue.Compare(this._Values[2 * i + 2], this._Values[i]))
            {
                flag = false;
            }
            if (!flag || i * 2 >= this._Values.Count)
            {
                break;
            }
        }
        return(flag);
    }
Exemple #10
0
 private void RequestPathsImmed(Vector3 startPoint, Vector3 endPoint, int collisionSize, int maxComputeCount = 8000)
 {
     while (!this.heap[0].IsEmpty || !this.heap[1].IsEmpty)
     {
         int num;
         if (this.heap[0].Count < this.heap[1].Count)
         {
             num = 0;
         }
         else
         {
             num = 1;
         }
         if (this.heap[0].Count == 0)
         {
             num = 1;
         }
         if (this.heap[1].Count == 0)
         {
             num = 0;
         }
         HValue hValue = this.heap[num].Pop();
         hValue.Mark = (short)(num * this.markBase + 2);
         for (int i = 0; i < 8; i++)
         {
             float num2 = (float)(this.dx[i] * this.dx[i] + this.dy[i] * this.dy[i]);
             num2 = (float)Math.Sqrt((double)num2);
             int  num3 = (int)hValue.X + this.dx[i];
             int  num4 = (int)hValue.Y + this.dy[i];
             bool flag = this.IsValidForWalk((int)hValue.X, (int)hValue.Y, collisionSize);
             if (Math.Abs(num2 - 1f) < 0.01f)
             {
                 flag = this.IsValidForWalk(num3, num4, collisionSize);
             }
             else
             {
                 for (int j = 0; j <= 1; j++)
                 {
                     for (int k = 0; k <= 1; k++)
                     {
                         flag = (flag && this.IsValidForWalk((int)hValue.X + j * this.dx[i], (int)hValue.Y + k * this.dy[i], collisionSize));
                     }
                 }
             }
             if (flag)
             {
                 this.curPathValue = this.getHValue(num3, num4);
                 if (this.curPathValue.Mark == -1)
                 {
                     float num5 = hValue.Cost + num2;
                     float num6 = this.HeapHFunction(num3, num4, this.heapX[1 - num], this.heapY[1 - num]);
                     this.curPathValue.Set((short)num3, (short)num4, num5, num5 + num6);
                     this.curPathValue.PreX = hValue.X;
                     this.curPathValue.PreY = hValue.Y;
                     this.curPathValue.Mark = (short)(num * this.markBase + 1);
                     this.heap[num].Push(this.curPathValue);
                 }
                 if ((int)this.curPathValue.Mark == num * this.markBase + 1)
                 {
                     float num7 = hValue.Cost + num2;
                     if (num7 + 0.1f < this.curPathValue.Cost)
                     {
                         float num8 = this.Distance((int)hValue.X, (int)hValue.Y, num3, num4);
                         int   pos  = this.heap[num].Find(this.curPathValue);
                         this.curPathValue.Set((short)num3, (short)num4, num7, num7 + num8);
                         this.curPathValue.PreX = hValue.X;
                         this.curPathValue.PreY = hValue.Y;
                         this.heap[num].Upper(pos);
                     }
                 }
                 this.computeTick++;
                 if (this.computeTick > maxComputeCount && i == 7)
                 {
                     this.computeTick = 0;
                     return;
                 }
                 if (num == 0)
                 {
                     float num9  = this.Distance((int)this.nearestTarget.X, (int)this.nearestTarget.Y, this.heapX[1], this.heapY[1]);
                     float num10 = this.Distance(num3, num4, this.heapX[1], this.heapY[1]);
                     if (num10 < num9)
                     {
                         this.nearestTarget = this.curPathValue;
                     }
                     float num11 = this.nearestTarget.Cost + 8f * num9;
                     float num12 = hValue.Cost + num10;
                     if (num12 > num11 && this.heap[0].PushCount > 4096 && this.heap[1].IsEmpty)
                     {
                         hValue = this.nearestTarget;
                         this.pathHValues.Add(hValue);
                         while (hValue.PreX != -1 && hValue.PreY != -1)
                         {
                             this.pathHValues.Add(this.getHValue((int)hValue.PreX, (int)hValue.PreY));
                             hValue = this.getHValue((int)hValue.PreX, (int)hValue.PreY);
                         }
                         for (int l = 0; l < this.pathHValues.Count / 2; l++)
                         {
                             HValue value = this.pathHValues[l];
                             this.pathHValues[l] = this.pathHValues[this.pathHValues.Count - l - 1];
                             this.pathHValues[this.pathHValues.Count - l - 1] = value;
                         }
                         Vector3 end = new Vector3((float)((int)this.nearestTarget.X - this.halfWidth) * this.gridSize, 0f, (float)((int)this.nearestTarget.Y - this.halfHeight) * this.gridSize);
                         this.paths       = this.BuildPath(this.pathHValues, startPoint, end, collisionSize);
                         this.pathFindEnd = true;
                         if (this.pathFindEndBack != null)
                         {
                             this.pathFindEndBack(this.paths);
                         }
                         return;
                     }
                 }
                 if (this.curPathValue.Mark >= 0 && (int)(this.curPathValue.Mark / 10) != num)
                 {
                     HValue[] array = new HValue[2];
                     array[num]     = hValue;
                     array[1 - num] = this.curPathValue;
                     this.paths.Clear();
                     hValue = array[0];
                     this.pathHValues.Add(hValue);
                     while (hValue.PreX != -1 && hValue.PreY != -1)
                     {
                         this.pathHValues.Add(this.getHValue((int)hValue.PreX, (int)hValue.PreY));
                         hValue = this.getHValue((int)hValue.PreX, (int)hValue.PreY);
                     }
                     for (int l = 0; l < this.pathHValues.Count / 2; l++)
                     {
                         HValue value2 = this.pathHValues[l];
                         this.pathHValues[l] = this.pathHValues[this.pathHValues.Count - l - 1];
                         this.pathHValues[this.pathHValues.Count - l - 1] = value2;
                     }
                     hValue = array[1];
                     this.pathHValues.Add(hValue);
                     while (hValue.PreX != -1 && hValue.PreY != -1)
                     {
                         this.pathHValues.Add(this.getHValue((int)hValue.PreX, (int)hValue.PreY));
                         hValue = this.getHValue((int)hValue.PreX, (int)hValue.PreY);
                     }
                     this.paths       = this.BuildPath(this.pathHValues, startPoint, endPoint, collisionSize);
                     this.pathFindEnd = true;
                     if (this.pathFindEndBack != null)
                     {
                         this.pathFindEndBack(this.paths);
                     }
                     return;
                 }
             }
         }
     }
 }
Exemple #11
0
 /// <summary>
 /// 请求获取指定条件的路径
 /// </summary>
 /// <param name="startPoint">起点</param>
 /// <param name="endPoint">终点</param>
 /// <param name="collisionSize">(移动体)碰撞尺寸</param>
 /// <param name="pathFindEndBack">路径搜索结束事件回调</param>
 /// <param name="maxComputeCount">最大的搜索计算次数计数上限</param>
 public void RequestPaths(Vector3 startPoint, Vector3 endPoint, int collisionSize, MapPath.PathFindEndBack pathFindEndBack = null, int maxComputeCount = 8000)
 {
     try
     {
         this.pfStartPoint    = startPoint;
         this.pfEndPoint      = endPoint;
         this.pfCollisionSize = collisionSize;
         this.pathFindEnd     = false;
         this.pathFindResult  = true;
         this.pathFindEndBack = pathFindEndBack;
         this.paths.Clear();
         this.computeTick = 0;
         this.heapX       = new int[2];
         this.heapY       = new int[2];
         //起点网格坐标
         this.heapX[0] = Mathf.FloorToInt(startPoint.x / this.gridSize) + this.halfWidth;
         this.heapY[0] = Mathf.FloorToInt(startPoint.z / this.gridSize) + this.halfHeight;
         //终点网格坐标
         this.heapX[1] = Mathf.FloorToInt(endPoint.x / this.gridSize) + this.halfWidth;
         this.heapY[1] = Mathf.FloorToInt(endPoint.z / this.gridSize) + this.halfHeight;
         if (this.heapX[0] == this.heapX[1] && this.heapY[0] == this.heapY[1])               //原地,直接完成
         {
             this.paths.Add(endPoint);
             this.pathFindEnd = true;
             if (pathFindEndBack != null)
             {
                 pathFindEndBack(this.paths);
             }
         }
         else
         {
             //初始化heap列表
             for (int i = 0; i < 2; i++)
             {
                 if (this.heap[i] == null)
                 {
                     this.heap[i] = new Heap();
                 }
                 this.heap[i].Clear();
             }
             //重置HValeCache
             for (int i = 0; i < this.HValueCache.Count; i++)
             {
                 this.HValueCache[i].Reset();
             }
             //path列表重置
             for (int i = 0; i < this.width; i++)
             {
                 for (int j = 0; j < this.height; j++)
                 {
                     this.path[i, j] = -1;
                 }
             }
             this.cacheIndex = 0;
             for (int k = 0; k < 2; k++)
             {
                 int num  = this.heapX[k];
                 int num2 = this.heapY[k];
                 for (int i = -1; i <= 1; i++)                        //将起点和终点的9宫格信息加入heap表
                 {
                     for (int j = -1; j <= 1; j++)
                     {
                         int     num3    = num + i;
                         int     num4    = num2 + j;
                         Vector3 vector  = new Vector3((float)(this.heapX[0] - this.halfWidth) * this.gridSize, 0f, (float)(this.heapY[0] - this.halfHeight) * this.gridSize);
                         Vector3 vector2 = new Vector3((float)(this.heapX[1] - this.halfWidth) * this.gridSize, 0f, (float)(this.heapY[1] - this.halfHeight) * this.gridSize);
                         Vector3 vector3 = (k != 0) ? vector2 : vector;
                         Vector3 vector4 = new Vector3((float)(num3 - this.halfWidth) * this.gridSize, 0f, (float)(num4 - this.halfHeight) * this.gridSize);
                         vector3.y = (vector4.y = 0f);
                         float num5 = Vector3.Distance(vector3, vector4);
                         float num6 = this.TryWalkDistance(vector3, vector4, collisionSize);
                         if (Math.Abs(num6 - num5) < 0.01f)
                         {
                             HValue hValue = this.getHValue(num3, num4);
                             hValue.Set((short)num3, (short)num4, num5, 0f);
                             hValue.Mark = (short)(1 + k * this.markBase);
                             hValue.PreX = -1;
                             hValue.PreY = -1;
                             this.heap[k].Push(hValue);
                         }
                     }
                 }
             }
             this.nearestTarget = this.heap[0].Peek();
             int num7 = 8;
             this.dx = new int[num7];
             this.dy = new int[num7];
             for (int i = 0; i < num7; i++)
             {
                 float num8 = (float)i * 2f * 3.14159274f / (float)num7;
                 this.dx[i] = this.Sign(Math.Cos((double)num8));
                 this.dy[i] = this.Sign(Math.Sin((double)num8));
             }
             this.pathHValues.Clear();
             this.RequestPathsImmed(this.pfStartPoint, this.pfEndPoint, this.pfCollisionSize, maxComputeCount);
         }
     }
     catch (Exception ex)          //路径搜索失败
     {
         this.paths = new List <Vector3>();
         if (GameScene.isEditor)
         {
             LogSystem.Log(new object[]
             {
                 string.Concat(new object[]
                 {
                     "寻路失败: 起始点 ",
                     startPoint,
                     " 目标点 : ",
                     endPoint,
                     " 错误消息 : ",
                     ex.Message
                 })
             });
         }
     }
 }