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); }
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))); }
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(); }
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); }
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(); }
public int GetRandomIndexInWalkables(FPseudoRandom random) { return(this.walkables[random.Next(0, this.walkables.Length)]); }
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); }