예제 #1
0
        private void SetStart(Graph2D graph, int start, HashSet <int> walkables)
        {
            int startPointPlaceX = ( int )this.startPointPlace.x;
            int startPointPlaceY = ( int )this.startPointPlace.y;

            int[] coord = graph.IndexToCoord(start);
            if (coord[0] + startPointPlaceX > this.col - 1)
            {
                coord[0] = this.col - 1 - startPointPlaceX;
            }
            if (coord[1] + startPointPlaceY > this.row - 1)
            {
                coord[1] = this.row - 1 - startPointPlaceY;
            }
            for (int i = 0; i < startPointPlaceX; i++)
            {
                int x = coord[0] + i;
                for (int j = 0; j < startPointPlaceY; j++)
                {
                    int y = coord[1] + j;
                    this.SetTileWalkable(graph.CoordToIndex(x, y), walkables);
                }
            }

            //计算起始范围的中点坐标(世界坐标)
            float i0 = (coord[0] + startPointPlaceX - coord[0]) * 0.5f + coord[0];
            float i1 = -(coord[1] + startPointPlaceY - coord[1]) * 0.5f - coord[1];

            this.centerOfStartRange = this._localToWorld.TransformPoint(new FVec3(i0, 0, i1));
        }
예제 #2
0
        public Maze(FPseudoRandom random,
                    FVec3 scale, FVec3 offset, int row, int col,
                    int startIndex, int endIndex, FVec2 startPointPlace)
        {
            this.startPointPlace = startPointPlace;
            if (this.row < ( int )this.startPointPlace.y + 3 ||
                this.col < ( int )this.startPointPlace.x + 3)
            {
                throw new Exception("The row or col invaild");
            }

            this.scale  = scale;
            this.offset = offset;
            this.row    = row;
            this.col    = col;

            this._localToWorld = FMat4.FromTRS(this.offset, FQuat.identity, this.scale);
            this._worldToLocal = FMat4.NonhomogeneousInverse(this._localToWorld);

            //创建二维图
            Graph2D graph2 = this.CreateFullDigraph(random);

            //创建格子
            this.CreateTiles(graph2);

            //是否随机起点和终点
            this.startIndex = startIndex < 0 ? this.RandomIndexWithinBorder(random) : startIndex;
            if (endIndex < 0)
            {
                int[] candidate = new int[5];
                for (int i = 0; i < 5; i++)
                {
                    candidate[i] = this.RandomIndexWithinBorder(random);
                }
                endIndex = this.GetFarthestToStartIndex(this.startIndex, candidate);
            }
            this.endIndex = endIndex;

            //初始化起点范围
            HashSet <int> walkablesHs = new HashSet <int>();

            this.SetStart(graph2, this.startIndex, walkablesHs);

            //创建起点和终点
            int[]            coord       = graph2.IndexToCoord(this.startIndex);
            Delaunay.DVertex startVertex = new Delaunay.DVertex(coord[0], coord[1]);
            coord = graph2.IndexToCoord(this.endIndex);
            Delaunay.DVertex endVertex = new Delaunay.DVertex(coord[0], coord[1]);
            //创建外圆周附近的顶点
            List <Delaunay.DVertex> vertices1 = this.GenVertices(24, 1f, 0.8f, 24, random);
            //创建内圆周附近的顶点
            List <Delaunay.DVertex> vertices2 = this.GenVertices(12, 0.2f, 0.6f, 12, random);
            //合并所有顶点
            List <Delaunay.DVertex> vertices = new List <Delaunay.DVertex> {
                startVertex, endVertex
            };

            vertices.AddRange(vertices1);
            vertices.AddRange(vertices2);

            //点集合的三角化
            List <Delaunay.DTriangle> triangles = Delaunay.Triangulate(vertices);

            //从三角形集合创建图
            GraphBase graph = Tools.TrianglesToGraph(triangles, random.NextFloat);
            //Prim算法创建最小生成树
            List <GraphEdge> edges = GraphSearcher.PrimSearch(graph, triangles[0].v0);

            //每条边用A*算法生成路径
            int count = edges.Count;

            for (int i = 0; i < count; i++)
            {
                GraphEdge        edge = edges[i];
                Delaunay.DVertex v0   = vertices[edge.from];
                Delaunay.DVertex v1   = vertices[edge.to];
                int[]            path = GraphSearcher.AStarSearch(graph2, graph2.CoordToIndex(( int )v0.x, ( int )v0.y),
                                                                  graph2.CoordToIndex(( int )v1.x, ( int )v1.y));
                this.SetPathWalkable(path, walkablesHs);

                //把顶点扩展成房间
                if (i == 0)
                {
                    this.SetIndexToWalkable(graph2, ( int )v0.x, ( int )v0.y, random.Next(1, 3), random.Next(1, 3), walkablesHs);
                }
                this.SetIndexToWalkable(graph2, ( int )v1.x, ( int )v1.y, random.Next(1, 3), random.Next(1, 3), walkablesHs);
            }

            this.walkables = walkablesHs.ToArray();
        }