public static void LoadAnimation(int AnimationNum)
        {
            string filename;

            filename = Path.Combine(Application.StartupPath, "data", "animations", string.Format("animation{0}.dat", AnimationNum));
            ByteStream reader = new ByteStream();

            BinaryFile.Load(filename, ref reader);

            Types.Animation[AnimationNum].Name  = reader.ReadString();
            Types.Animation[AnimationNum].Sound = reader.ReadString();
            var loopTo = Information.UBound(Types.Animation[AnimationNum].Sprite);

            for (var x = 0; x <= loopTo; x++)
            {
                Types.Animation[AnimationNum].Sprite[x] = reader.ReadInt32();
            }
            var loopTo1 = Information.UBound(Types.Animation[AnimationNum].Frames);

            for (int x = 0; x <= loopTo1; x++)
            {
                Types.Animation[AnimationNum].Frames[x] = reader.ReadInt32();
            }
            var loopTo2 = Information.UBound(Types.Animation[AnimationNum].LoopCount);

            for (int x = 0; x <= loopTo2; x++)
            {
                Types.Animation[AnimationNum].LoopCount[x] = reader.ReadInt32();
            }
            var loopTo3 = Information.UBound(Types.Animation[AnimationNum].LoopTime);

            for (int x = 0; x <= loopTo3; x++)
            {
                Types.Animation[AnimationNum].LoopTime[x] = reader.ReadInt32();
            }

            if (Types.Animation[AnimationNum].Name == null)
            {
                Types.Animation[AnimationNum].Name = "";
            }
        }
        public static void SaveAnimation(int AnimationNum)
        {
            string filename;
            int    x;

            filename = Path.Combine(Application.StartupPath, "data", "animations", string.Format("animation{0}.dat", AnimationNum));

            ByteStream writer = new ByteStream(100);

            writer.WriteString(Types.Animation[AnimationNum].Name);
            writer.WriteString(Types.Animation[AnimationNum].Sound);
            var loopTo = Information.UBound(Types.Animation[AnimationNum].Sprite);

            for (x = 0; x <= loopTo; x++)
            {
                writer.WriteInt32(Types.Animation[AnimationNum].Sprite[x]);
            }
            var loopTo1 = Information.UBound(Types.Animation[AnimationNum].Frames);

            for (x = 0; x <= loopTo1; x++)
            {
                writer.WriteInt32(Types.Animation[AnimationNum].Frames[x]);
            }
            var loopTo2 = Information.UBound(Types.Animation[AnimationNum].LoopCount);

            for (x = 0; x <= loopTo2; x++)
            {
                writer.WriteInt32(Types.Animation[AnimationNum].LoopCount[x]);
            }
            var loopTo3 = Information.UBound(Types.Animation[AnimationNum].LoopTime);

            for (x = 0; x <= loopTo3; x++)
            {
                writer.WriteInt32(Types.Animation[AnimationNum].LoopTime[x]);
            }

            BinaryFile.Save(filename, ref writer);
        }
Beispiel #3
0
        public static bool APlus(int MapNum, int SX, int SY, int TX, int TY, eCell FreeCell, ref tPoint[] Path)
        {
            bool APlus = false;
            // A+ Pathfinding Algorithm:
            // Implementation by Herbert Glarner ([email protected])
            // Unlimited use for whatever purpose allowed provided that above credits are given.
            // Suggestions and bug reports welcome.
            int   lMaxList = 0;
            int   lActList;
            float sCheapCost; int lCheapIndex;
            float sTotalCost;
            int   lCheapX, lCheapY;
            int   lOffX, lOffY;
            int   lTestX, lTestY;
            int   lMaxX, lMaxY;
            float sAdditCost;
            int   lPathPtr;

            // The test program wants to access this grid. For this reason it is defined
            // and initialized globally. Usually one would define and initialize it only
            // in this procedure.
            // The two fields of tGrid can also be merged into the source matrix.
            // Dim abGridCopy() As tGrid

            const float cSqr2 = 1.4142135623731f;

            // Define the upper boundaries of the grid.
            lMaxX = Information.UBound(mapMatrix[MapNum].gaeGrid, 1); lMaxY = Information.UBound(mapMatrix[MapNum].gaeGrid, 2);

            // For each cell of the grid a bit is defined to hold it's "closed" status
            // and the index to the Open-List.
            // The test program wants to access this grid. For this reason it is defined
            // and initialized globally. Usually one would define and initialize it only
            // in this procedure. (Don't omit here: we need an empty matrix.)
            tGrid[,] abGridCopy = new tGrid[lMaxX + 1, lMaxY + 1];

            // The starting point is added to the working list. It has no parent (-1).
            // The cost to get here is 0 (we start here). The direct distance enters
            // the Heuristic.
            tCell[] grList = new tCell[0 + 1];

            grList[0].x         = SX; grList[0].y = SY; grList[0].Parent = -1; grList[0].Cost = 0;
            grList[0].Heuristic = (float)(Math.Sqrt((TX - SX) * (TX - SX) + (TY - SY) * (TY - SY)));


            // Start the algorithm
            for (;;)
            {
                // Get the cell with the lowest Cost+Heuristic. Initialize the cheapest cost
                // with an impossible high value (change as needed). The best found index
                // is set to -1 to indicate "none found".
                sCheapCost  = 10000000;
                lCheapIndex = -1;
                // Check all cells of the list. Initially, there is only the start point,
                // but more will be added soon.
                for (lActList = 0; lActList <= lMaxList; lActList++)
                {
                    // Only check if not closed already.
                    if (!grList[lActList].Closed)
                    {
                        // If this cells total cost (Cost+Heuristic) is lower than the so
                        // far lowest cost, then store this total cost and the cell's index
                        // as the so far best found.
                        sTotalCost = grList[lActList].Cost + grList[lActList].Heuristic;
                        if (sTotalCost < sCheapCost)
                        {
                            // New cheapest cost found.
                            sCheapCost = sTotalCost; lCheapIndex = lActList;
                        }
                    }
                }                 // lActList

                // lCheapIndex contains the cell with the lowest total cost now.
                // If no such cell could be found, all cells were already closed and there
                // is no path at all to the target.
                if (lCheapIndex == -1)
                {
                    // There is no path.
                    APlus = false; return(APlus);
                }

                // Get the cheapest cell's coordinates
                lCheapX = grList[lCheapIndex].x;
                lCheapY = grList[lCheapIndex].y;

                // If the best field is the target field, we have found our path.
                if (lCheapX == TX & lCheapY == TY)
                {
                    // Path found.
                    break;
                }

                // Check all immediate neighbors
                for (lOffY = -1; lOffY <= 1; lOffY++)
                {
                    for (lOffX = -1; lOffX <= 1; lOffX++)
                    {
                        // Ignore the actual field, process all others (8 neighbors).
                        if (lOffX != 0 | lOffY != 0)
                        {
                            if (!modTypes.Options.allowEightDirectionalMovement && !(lOffX != 0 & lOffY != 0))
                            {
                                continue;
                            }
                            // Get the neighbor's coordinates.
                            lTestX = lCheapX + lOffX; lTestY = lCheapY + lOffY;
                            // Don't test beyond the grid's boundaries.
                            if (lTestX >= 0 & lTestX <= lMaxX & lTestY >= 0 & lTestY <= lMaxY)
                            {
                                // The cell is within the grid's boundaries.
                                // Make sure the field is accessible. To be accessible,
                                // the cell must have the value as per the function
                                // argument FreeCell (change as needed). Of course, the
                                // target is allowed as well.
                                if (mapMatrix[MapNum].gaeGrid[lTestX, lTestY] == FreeCell || mapMatrix[MapNum].gaeGrid[lTestX, lTestY] == eCell.target)
                                {
                                    // The cell is accessible.
                                    // For this we created the "bitmatrix" abGridCopy().
                                    if (abGridCopy[lTestX, lTestY].ListStat == eListStat.Unprocessed)
                                    {
                                        // Register the new cell in the list.
                                        lMaxList += 1;
                                        Array.Resize(ref grList, lMaxList + 1);

                                        // The parent is where we come from (the cheapest field);
                                        // it's index is registered.
                                        grList[lMaxList].x = lTestX; grList[lMaxList].y = lTestY; grList[lMaxList].Parent = lCheapIndex;
                                        // Additional cost is 1 for othogonal movement, cSqr2 for
                                        // diagonal movement (change if diagonal steps should have
                                        // a different cost).
                                        if (Math.Abs(lOffX) + Math.Abs(lOffY) == 1)
                                        {
                                            sAdditCost = (float)(1.0);
                                        }
                                        else
                                        {
                                            sAdditCost = cSqr2;
                                        }
                                        // Store cost to get there by summing the actual cell's cost
                                        // and the additional cost.
                                        grList[lMaxList].Cost = grList[lCheapIndex].Cost + sAdditCost;
                                        // Calculate distance to target as the heuristical part
                                        grList[lMaxList].Heuristic = (float)(Math.Sqrt((TX - lTestX) * (TX - lTestX) + (TY - lTestY) * (TY - lTestY)));

                                        // Register in the Grid copy as open.
                                        abGridCopy[lTestX, lTestY].ListStat = eListStat.IsOpen;
                                        // Also register the index to quickly find the element in the
                                        // "closed" list.
                                        abGridCopy[lTestX, lTestY].Index = lMaxList;
                                    }
                                    else if (abGridCopy[lTestX, lTestY].ListStat == eListStat.IsOpen)
                                    {
                                        // Is the cost to get to this already open field cheaper when using
                                        // this path via lTestX/lTestY ?
                                        lActList   = abGridCopy[lTestX, lTestY].Index;
                                        sAdditCost = (float)((Math.Abs(lOffX) + Math.Abs(lOffY) == 1 ? 1.0 : cSqr2));
                                        if (grList[lCheapIndex].Cost + sAdditCost < grList[lActList].Cost)
                                        {
                                            // The cost to reach the already open field is lower via the
                                            // actual field.

                                            // Store new cost
                                            grList[lActList].Cost = grList[lCheapIndex].Cost + sAdditCost;
                                            // Store new parent
                                            grList[lActList].Parent = lCheapIndex;
                                        }
                                        // ElseIf abGridCopy(lTestX, lTestY) = IsClosed Then
                                        // This cell can be ignored
                                    }
                                }
                            }
                        }
                    }             // lOffX
                }                 // lOffY
                // Close the just checked cheapest cell.
                grList[lCheapIndex].Closed            = true;
                abGridCopy[lCheapX, lCheapY].ListStat = eListStat.IsClosed;
            }

            // The path can be found by backtracing from the field TX/TY until SX/SY.
            // The path is traversed in backwards order and stored reversely (!) in
            // the "argument" Path().
            Path     = new tPoint[0 + 1];
            lPathPtr = -1;
            // lCheapIndex (lCheapX/Y) initially contains the target TX/TY
            do
            {
                // Store the coordinates of the current cell
                lPathPtr += 1;
                Array.Resize(ref Path, lPathPtr + 1);
                Path[lPathPtr].x = grList[lCheapIndex].x;
                Path[lPathPtr].y = grList[lCheapIndex].y;
                // Follow the parent
                lCheapIndex = grList[lCheapIndex].Parent;
            } while (lCheapIndex != -1);

            Console.WriteLine("Path found");

            APlus = true;
            return(APlus);
        }