コード例 #1
0
    public void NewDest(int x, int y)
    {
        operating  = true;
        lastTarget = new Vector2Int(x, y);

        computestarttime            = Time.realtimeSinceStartup;
        pathData[x + y * flowWidth] = new pathInfo((uint)activePath, 0, 0, 0);
        if (AtoB)
        {
            pathBufferA.SetData(pathData);
        }
        else
        {
            pathBufferB.SetData(pathData);
        }

        fulfilled           = false;
        pathreturn          = false;
        waitingForRetrieval = false;

        runsBeforeCheck = 256; //make this actually something according to x and y

        currentRuns = 0;

        PathCompute();
    }
コード例 #2
0
    private void SetupPath()
    {
        pathData = new pathInfo[flowSize];
        for (int i = 0; i < flowSize; i++)
        {
            pathData[i] = new pathInfo(0, 0, 0, 0);
        }

        pathDataRaw = new byte[flowSize * size_of(typeof(pathInfo))];

        pathBufferA = new ComputeBuffer(flowSize, size_of(typeof(pathInfo)));
        pathBufferB = new ComputeBuffer(flowSize, size_of(typeof(pathInfo)));
        //pathBuffer.SetData(pathData);
    }
コード例 #3
0
ファイル: Pathfinder.cs プロジェクト: vaverkaj/NET-Game
        /// <summary>
        /// Initializes the dictionary for storing informations about Fields
        /// that are required for A*
        /// </summary>
        /// <returns></returns>
        private Dictionary <Field, pathInfo> initFiledInfo()
        {
            Dictionary <Field, pathInfo> fieldInfo = new Dictionary <Field, pathInfo>();

            foreach (List <Field> radka in mapa.allFields)
            {
                foreach (Field pole in radka)
                {
                    pathInfo p = new pathInfo();
                    p.pathParent           = null;
                    p.distanceToPathTarget = Double.MaxValue;
                    p.costFromPathSource   = 0;
                    fieldInfo.Add(pole, p);
                }
            }

            return(fieldInfo);
        }
コード例 #4
0
ファイル: Pathfinder.cs プロジェクト: vaverkaj/NET-Game
        /// <summary>
        /// Simplified A* that returns all aviable move options for unit
        /// It is similar to findPath function.
        /// This solution is not perfect because i repeated myslef, but creating function that is appliable on both
        /// findPath and findAviableMoveOptionsForUnit was unnecessary
        /// </summary>
        /// <param name="u">Unit that is located on map and has its movement parameter set</param>
        /// <returns>List of all fields that are accesible by that Unit in one turn</returns>
        public List <Field> findAviableMoveOptionsForUnit(Unit u)
        {
            Stack <Field> path       = new Stack <Field>();
            List <Field>  openList   = new List <Field>();
            List <Field>  closedList = new List <Field>();

            Dictionary <Field, pathInfo> fieldInfo = initFiledInfo();

            Field current = u.at;

            openList.Add(u.at);

            while (openList.Count != 0)
            {
                current = openList[0];
                openList.Remove(current);
                closedList.Add(current);
                foreach (Field n in current.neighbours)
                {
                    if (!closedList.Contains(n))
                    {
                        if ((u.flying && n.flyOverAble) || (!u.flying && n.passable && !n.isOccupied()))
                        {
                            if (!openList.Contains(n))
                            {
                                pathInfo p = fieldInfo[n];
                                p.pathParent         = current;
                                p.costFromPathSource = n.cost + fieldInfo[p.pathParent].costFromPathSource;
                                fieldInfo[n]         = p;
                                if (p.costFromPathSource <= u.movement)
                                {
                                    openList.Add(n);
                                    openList = openList.OrderBy(field => fieldInfo[field].costFromPathSource).ToList <Field>();
                                }
                            }
                        }
                    }
                }
            }
            return(closedList);
        }
コード例 #5
0
    // Update is called once per frame
    void Update()
    {
        if (operating)
        {
            if (!fulfilled)
            {
                PathCompute();
            }
            else if (!pathreturn)
            {
                if (!waitingForRetrieval)
                {
                    if (AtoB)
                    {
                        AsyncTextureReader.RequestBufferData(pathBufferB);
                    }
                    else
                    {
                        AsyncTextureReader.RequestBufferData(pathBufferA);
                    }
                    waitingForRetrieval = true;
                }
                else
                {
                    AsyncTextureReader.Status status;

                    if (AtoB)
                    {
                        status = AsyncTextureReader.RetrieveBufferData(pathBufferB, pathDataRaw);
                    }
                    else
                    {
                        status = AsyncTextureReader.RetrieveBufferData(pathBufferA, pathDataRaw);
                    }

                    if (status == AsyncTextureReader.Status.Succeeded)
                    {
                        Debug.Log(Time.realtimeSinceStartup - computestarttime);
                        waitingForRetrieval = false;
                        pathreturn          = true;

                        for (int i = 0; i < pathData.Length; i++)
                        {
                            pathData[i] = new pathInfo(System.BitConverter.ToUInt32(pathDataRaw, i * 16), System.BitConverter.ToInt32(pathDataRaw, i * 16 + 4), System.BitConverter.ToInt32(pathDataRaw, i * 16 + 8), System.BitConverter.ToUInt32(pathDataRaw, i * 16 + 12));
                            //debugArray[i].transform.localScale = new Vector3(1.0f, 1.0f, pathData[i].cost / 10.0f);
                        }

                        if (activePath == 1)
                        {
                            activePath = 0;
                        }
                        else
                        {
                            activePath = 1;
                        }

                        shader.SetInt("activePath", activePath);

                        operating = false;
                        //Debug.Log("hey now");
                    }
                }
            }
        }
        else
        {
            //edit
            if (edits.Count > 0)
            {
                while (edits.Count > 0)
                {
                    for (int i = 0; i < edits[0].blocks.Count; i++)
                    {
                        if (edits[0].blocks[i].x > 0 && edits[0].blocks[i].x < flowWidth && edits[0].blocks[i].y > 0 && edits[0].blocks[i].y < flowHeight)
                        {
                            difficultyData[edits[0].blocks[i].x + edits[0].blocks[i].y * flowWidth] = edits[0].newVal;
                            obstacles[edits[0].blocks[i].x, edits[0].blocks[i].y].SetActive(edits[0].newVal == 0u);
                        }
                    }
                    edits.RemoveAt(0);
                }

                difficultyBuffer.SetData(difficultyData);

                NewDest(lastTarget.x, lastTarget.y);
            }
        }
    }
コード例 #6
0
    public Vector2Int GetFlow(float x, float y)
    {
        pathInfo pi = pathData[(int)x + (int)y * flowWidth];

        return(new Vector2Int(pi.xDir, pi.yDir));
    }
コード例 #7
0
ファイル: Pathfinder.cs プロジェクト: vaverkaj/NET-Game
        /// <summary>
        /// This funciton applies A* alghorithm on our map. It has low maintainablity, but thats because the alghorithm itself is quite complex.
        /// I tried to devide it into more functions but it only made the code less readable.
        /// </summary>
        /// <param name="start">Field form which you want to start</param>
        /// <param name="end">Field where you want to get</param>
        /// <param name="u">Unit that is traveling. Unit can either fly or walk.
        /// I didnt wanted to use object type, because i want to be able to cast spells on units, that makes them fly or get pinned to the ground</param>
        /// <returns>Returns a stack with the Fields ordered by distance from goal, or null if the Field is inaccessible</returns>
        public Stack <Field> findPath(Field start, Field end, Unit u)
        {
            Stack <Field> path       = new Stack <Field>();
            List <Field>  openList   = new List <Field>();
            List <Field>  closedList = new List <Field>();

            Dictionary <Field, pathInfo> fieldInfo = initFiledInfo();

            Field current = start;

            openList.Add(start);

            while (openList.Count != 0 && !closedList.Exists((x) => (x.xPos == end.xPos && x.yPos == end.yPos)))
            {
                current = openList[0];
                openList.Remove(current);
                closedList.Add(current);
                foreach (Field n in current.neighbours)
                {
                    if (!closedList.Contains(n))
                    {
                        if ((u.flying && n.flyOverAble) || (!u.flying && n.passable && !n.isOccupied()))
                        {
                            if (!openList.Contains(n))
                            {
                                pathInfo p = fieldInfo[n];
                                p.pathParent           = current;
                                p.distanceToPathTarget = Math.Abs(n.xPos - end.xPos) + Math.Abs(n.yPos - end.yPos);
                                p.costFromPathSource   = n.cost + fieldInfo[p.pathParent].costFromPathSource;
                                fieldInfo[n]           = p;
                                openList.Add(n);
                                openList = openList.OrderBy((field) =>
                                {
                                    if (fieldInfo[field].distanceToPathTarget != -1 && fieldInfo[field].costFromPathSource != -1)
                                    {
                                        return(fieldInfo[field].distanceToPathTarget + fieldInfo[field].costFromPathSource);
                                    }
                                    else
                                    {
                                        return(-1);
                                    }
                                }
                                                            ).ToList <Field>();
                            }
                        }
                    }
                }
            }
            if (!closedList.Exists(x => (x.xPos == end.xPos && x.yPos == end.yPos)))
            {
                return(null);
            }

            Field temp = closedList[closedList.IndexOf(current)];

            while (temp != start && temp != null)
            {
                path.Push(temp);
                temp = fieldInfo[temp].pathParent;
            }
            return(path);
        }