Exemple #1
0
        private int RandomIndexWithinBorder(FPseudoRandom random)
        {
            int x = random.Next(1, this.col - 1);
            int y = random.Next(1, this.row - 1);

            return(y * this.col + x);
        }
Exemple #2
0
        public FVec3 GetRandomPointInWalkables(FPseudoRandom random)
        {
            int   index = this.GetRandomIndexInWalkables(random);
            FVec3 coord = this.IndexToCoord(index);

            coord.x *= this.scale.x;
            coord.z *= this.scale.z;
            return(new FVec3(random.NextFix64(coord.x, coord.x + this.scale.x), coord.y,
                             random.NextFix64(coord.z - this.scale.z, coord.z)));
        }
Exemple #3
0
 public Battle(BattleParams param)
 {
     this._data           = ModelFactory.GetMapData(Utils.GetIDFromRID(param.id));
     this._random         = new FPseudoRandom(param.rndSeed);
     this._buffManager    = new BuffManager(this);
     this._entityManager  = new EntityManager(this);
     this._context        = new UpdateContext();
     this._startCountDown = new StartCountDown(this, this._data.startCountDown);
     this._maze           = new Maze(this._random, this._data.scale, this._data.offset, this._data.row, this._data.col, this._data.startIndex,
                                     this._data.endIndex, this._data.startPointPlace);
     SyncEvent.GenMaze(this._maze.walkables, this._maze.startIndex, this._maze.endIndex);
     this.CreateRails();
     this.CreateTerminus();
     this.CreatePlayers(param.players);
     this._entityManager.SupplyItems();
 }
Exemple #4
0
        private Graph2D CreateFullDigraph(FPseudoRandom random)
        {
            Graph2D graph = new Graph2D(this.row, this.col);

            for (int i = 1; i < this.row - 1; i++)
            {
                for (int j = 1; j < this.col - 1; j++)
                {
                    int       cur  = i * this.col + j;
                    GraphNode node = graph[cur];
                    if (j < this.col - 2)
                    {
                        node.AddEdge(cur, cur + 1, random.NextFloat());
                    }
                    if (j > 1)
                    {
                        node.AddEdge(cur, cur - 1, random.NextFloat());
                    }
                }
            }
            for (int i = 1; i < this.col - 1; i++)
            {
                for (int j = 1; j < this.row - 1; j++)
                {
                    int       cur  = j * this.col + i;
                    GraphNode node = graph[cur];
                    if (j < this.row - 2)
                    {
                        node.AddEdge(cur, cur + this.col, random.NextFloat());
                    }
                    if (j > 1)
                    {
                        node.AddEdge(cur, cur - this.col, random.NextFloat());
                    }
                }
            }
            return(graph);
        }
Exemple #5
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();
        }
Exemple #6
0
 public int GetRandomIndexInWalkables(FPseudoRandom random)
 {
     return(this.walkables[random.Next(0, this.walkables.Length)]);
 }
Exemple #7
0
        private List <Delaunay.DVertex> GenVertices(int vertexCount, float innerRadius, float outterRadius, int slpiceSegment, FPseudoRandom rnd)
        {
            float cx = .5f * this.col;
            float cy = .5f * this.row;
            float hw = .5f * (this.col - 1);
            float hh = .5f * (this.row - 1);
            List <Delaunay.DVertex> vertices = new List <Delaunay.DVertex>();

            for (int i = 0; i < vertexCount; i++)
            {
                //横轴半径
                int r1 = ( int )(hw * (rnd.NextFloat() * (outterRadius - innerRadius) + innerRadius));
                //纵轴半径
                int r2 = ( int )(hh * (rnd.NextFloat() * (outterRadius - innerRadius) + innerRadius));
                //随机角度
                float sita = rnd.NextFloat() * MathUtils.PI * 2f;
                //椭圆极坐标参数方程
                int x = ( int )(cx + r1 * MathUtils.Cos(sita));
                int y = ( int )(cy + r2 * MathUtils.Sin(sita));

                vertices.Add(new Delaunay.DVertex(x, y));
            }
            //取半径的平均单位比例
            float avgRadius = (outterRadius + innerRadius) * 0.5f;
            //椭圆周长近似公式
            float p = MathUtils.Sqrt(0.5f * avgRadius * avgRadius * (hw * hw + hh * hh));
            //按给定的分段数计算阈值
            float threshold = 2f * MathUtils.PI * p / slpiceSegment;

            //去掉距离较近的顶点
            TripVertex(vertices, threshold);
            return(vertices);
        }