void Generate() { int seed = int.Parse(generate.seed.ToString() + (groundData.pos.x).ToString() + (groundData.pos.z).ToString()); MapTools.SetRandomSeed(seed, out rand); if (spaceData.type == SpaceType.City) { if (!generate.map_data.GetHouseData(out wall_datas, out house_datas, area_id)) { // 创建城市 GenerateCity(spaceData); generate.map_data.SetHouseData(wall_datas, house_datas, area_id); } debug_test += "\n增加操作 " + GenerateState.Wall + " " + area_id + " " + new System.Diagnostics.StackTrace(); debug_test += "\n增加操作 " + GenerateState.House + " " + area_id + " " + new System.Diagnostics.StackTrace(); BuildOperate wall_operate = new BuildOperate() { area_id = area_id, state = GenerateState.Wall }; generate.EnqueueOperate(wall_operate); // 增加创建围墙的操作 BuildOperate house_operate = new BuildOperate() { area_id = area_id, state = GenerateState.House }; generate.EnqueueOperate(house_operate); // 增加创建房子的操作 } if (!generate.map_data.GetDecorateData(out tree_datas, out decorate_datas, area_id)) { // 创建地表 GenerateOther(); generate.map_data.SetDecorateData(tree_datas, decorate_datas, area_id); } city_rects = null; if (tree_datas.Length > 0) { debug_test += "\n增加操作 " + GenerateState.Tree + " " + area_id + " " + new System.Diagnostics.StackTrace(); BuildOperate tree_operate = new BuildOperate() { area_id = area_id, state = GenerateState.Tree }; generate.EnqueueOperate(tree_operate); // 增加创建树的操作 } debug_test += "\n增加操作 " + GenerateState.Decorate + " " + area_id + " " + new System.Diagnostics.StackTrace(); BuildOperate decorate_operate = new BuildOperate() { area_id = area_id, state = GenerateState.Decorate }; generate.EnqueueOperate(decorate_operate); // 增加创建植物的操作 }
private void CreateGround(SpaceData space, SpaceData[] areas, int idx, SpaceData[] triggers) { float width = space.scale.x + MapTools.RandomRange(ground_min, ground_max, rand); float length = space.scale.z + MapTools.RandomRange(ground_min, ground_max, rand); SpaceData trigger = new SpaceData(new Vector3(space.pos.x, see_dir, space.pos.z), new Vector3(width + see_dir, see_dir * 2, length + see_dir), SpaceType.AreaTrriger); triggers[idx] = trigger; idx = idx * 2 + 1; SpaceData data = new SpaceData(new Vector3(space.pos.x, ground_height, space.pos.z), new Vector3(width, 1, length), SpaceType.Ground, useMeshScale: true); areas[idx] = data; idx++; SpaceData water = new SpaceData(new Vector3(space.pos.x, water_height, space.pos.z), new Vector3(width + space_edge, 1, length + space_edge), SpaceType.Water, useMeshScale: true); areas[idx] = water; }
/// <summary> /// 生成房子 /// </summary> /// <param name="pos">位置</param> /// <param name="dir">方向</param> private SpaceData GenerateHouse(Vector3 pos, Direction dir, SpaceType typ) { StaticObjsData[] objs; switch (typ) { case SpaceType.House: objs = generate.houseObjs; break; case SpaceType.Shop: objs = generate.shopObjs; break; default: objs = null; break; } int id = objs == null ? 0 : MapTools.RandomRange(0, objs.Length, rand); int idx = objs == null ? 0 : MapTools.RandomRange(0, objs[id].objs.Length, rand); var size = MapTools.RandomRange(0.9f, 1.1f, rand); float angle = MapTools.RandomRange(-5f, 5f, rand); switch (dir) { case Direction.East: angle += 90; break; case Direction.West: angle += 270; break; case Direction.South: angle += 180; break; } return(new SpaceData(pos, new Vector3(size, size, size), typ, angle: angle, id: (short)id, idx: (short)idx)); }
int GetHypotenuse(int x, int y) { return(MapTools.IntegerSqrt(x * x + y * y)); }
void GenerateCity(SpaceData city) { List <SpaceData> walls = new List <SpaceData>(); List <SpaceData> doors = new List <SpaceData>(); List <SpaceData> ways = new List <SpaceData>(); List <SpaceData> shops = new List <SpaceData>(); List <SpaceData> houses = new List <SpaceData>(); int half_wall_width = (int)(wall_width * 0.5f); Vector3 pos = city.pos; float width = city.scale.x; float length = city.scale.z; float min_x = city.min_x; float max_x = city.max_x; float min_y = city.min_z; float max_y = city.max_z; // 城门统一坐北朝南 // 随机道路 // 先随机一个点,然后随机一个方向建立道路,再向两边建立道路 int way_node_min_x = (int)(min_x + space_size + space_edge); int way_node_min_y = (int)(min_y + space_size + space_edge); int way_node_max_x = (int)(max_x - space_size - space_edge); int way_node_max_y = (int)(max_y - space_size - space_edge); // 创建城市中心点 Vector3 city_center; if (width > ((space_size + space_edge) * 0.5f) && length > ((space_size + space_edge) * 0.5f)) { city_center = new Vector3(MapTools.RandomRange(way_node_min_x, way_node_max_x, rand), 0, MapTools.RandomRange(way_node_min_y, way_node_max_y, rand)); } else { city_center = new Vector3(min_x + (min_y - min_x) * 0.5f, 0, max_x + (max_y - max_x) * 0.5f); } // 东墙 Vector3 east_wall_pos = new Vector3(max_x - half_wall_width, city_height, pos.z); float east_wall_width = wall_width; float east_wall_length = length; SpaceData east_wall = new SpaceData(east_wall_pos, new Vector3(east_wall_width, 3, east_wall_length), SpaceType.Wall, useMeshScale: true); // 西墙 Vector3 west_wall_pos = new Vector3(min_x + half_wall_width, city_height, pos.z); float west_wall_width = wall_width; float west_wall_length = length; SpaceData west_wall = new SpaceData(west_wall_pos, new Vector3(west_wall_width, 3, west_wall_length), SpaceType.Wall, useMeshScale: true); //北墙 Vector3 north_wall_pos = new Vector3(pos.x, city_height, max_y - half_wall_width); float north_wall_width = width; float north_wall_length = wall_width; SpaceData north_wall = new SpaceData(north_wall_pos, new Vector3(north_wall_width, 3, north_wall_length), SpaceType.Wall, useMeshScale: true); // 南墙1 float south1_wall_width = (int)(max_x - city_center.x - door_width); float south1_wall_length = wall_width; Vector3 south1_wall_pos = new Vector3(max_x - south1_wall_width * 0.5f, city_height, min_y + half_wall_width); SpaceData south1_wall = new SpaceData(south1_wall_pos, new Vector3(south1_wall_width, 3, south1_wall_length), SpaceType.Wall, useMeshScale: true); // 南墙2 float south2_wall_width = (int)(city_center.x - min_x - door_width); float south2_wall_length = wall_width; Vector3 south2_wall_pos = new Vector3(min_x + south2_wall_width * 0.5f, city_height, min_y + half_wall_width); SpaceData south2_wall = new SpaceData(south2_wall_pos, new Vector3(south2_wall_width, 3, south2_wall_length), SpaceType.Wall, useMeshScale: true); walls.Add(east_wall); walls.Add(west_wall); walls.Add(north_wall); walls.Add(south1_wall); walls.Add(south2_wall); // 围墙柱子 walls.Add(new SpaceData(new Vector3(min_x + half_wall_width, city_height, min_y + half_wall_width), new Vector3(wallnode_size, 5, wallnode_size), SpaceType.WallNode, useMeshScale: true)); walls.Add(new SpaceData(new Vector3(min_x + half_wall_width, city_height, max_y - half_wall_width), new Vector3(wallnode_size, 5, wallnode_size), SpaceType.WallNode, useMeshScale: true)); walls.Add(new SpaceData(new Vector3(max_x - half_wall_width, city_height, min_y + half_wall_width), new Vector3(wallnode_size, 5, wallnode_size), SpaceType.WallNode, useMeshScale: true)); walls.Add(new SpaceData(new Vector3(max_x - half_wall_width, city_height, max_y - half_wall_width), new Vector3(wallnode_size, 5, wallnode_size), SpaceType.WallNode, useMeshScale: true)); walls.Add(new SpaceData(new Vector3(min_x + south2_wall_width - half_wall_width, city_height, min_y + half_wall_width), new Vector3(wallnode_size * 2, 5, wallnode_size * 2), SpaceType.WallNode, useMeshScale: true)); walls.Add(new SpaceData(new Vector3(max_x - south1_wall_width + half_wall_width, city_height, min_y + half_wall_width), new Vector3(wallnode_size * 2, 5, wallnode_size * 2), SpaceType.WallNode, useMeshScale: true)); var door = new SpaceData(new Vector3(city_center.x, city_height, min_y), new Vector3(door_width, 1, 1), SpaceType.Door); // 门 doors.Add(door); //主干道 int main_way_vertical_width = door_width; int main_way_vertical_length = (int)(max_y - min_y - space_edge); int main_way_horizontal_width = (int)(max_x - min_x - space_edge * 2); int main_way_horizontal_length = door_width; Vector3 main_vertical_way_pos = new Vector3(city_center.x, city_height, min_y + main_way_vertical_length * 0.5f); Vector3 main_horizontal_way_pos = new Vector3(min_x + main_way_horizontal_width * 0.5f + space_edge, city_height, city_center.z); SpaceData main_vertical_way = new SpaceData(main_vertical_way_pos, new Vector3(main_way_vertical_width, 0.08f, main_way_vertical_length), SpaceType.Way, useMeshScale: true); SpaceData main_horizontal_way = new SpaceData(main_horizontal_way_pos, new Vector3(main_way_horizontal_width, 0.08f, main_way_horizontal_length), SpaceType.Way, useMeshScale: true); ways.Add(main_vertical_way); ways.Add(main_horizontal_way); // 中心点向主干道两边创建商店 int shop_idx = house_size; float house_offset = house_size * 0.5f + way_width; float main_way_right_x = city_center.x + house_offset; float main_way_left_x = city_center.x - house_offset; float main_way_up_y = city_center.z + house_offset; float main_way_down_y = city_center.z - house_offset; float max_count = Mathf.Max(main_way_vertical_width, main_way_vertical_length) * 1f; while (true) { int up_y = (int)(city_center.z + shop_idx); int down_y = (int)(city_center.z - shop_idx); int right_x = (int)(city_center.x + shop_idx); int left_x = (int)(city_center.x - shop_idx); if (up_y > (main_vertical_way.max_z) && down_y < (main_vertical_way.min_z) && right_x > (main_horizontal_way.max_x) && left_x < (main_horizontal_way.min_x)) { break; } //上面的 if (up_y < (main_vertical_way.max_z) && Vector3.Distance(door.pos, new Vector3(main_way_right_x, 1, up_y)) > space_edge) { shops.Add(GenerateHouse(new Vector3(main_way_right_x, city_height, up_y), Direction.West, SpaceType.Shop)); shops.Add(GenerateHouse(new Vector3(main_way_left_x, city_height, up_y), Direction.East, SpaceType.Shop)); } //下面的 if (down_y > (main_vertical_way.min_z) && Vector3.Distance(door.pos, new Vector3(main_way_right_x, 1, down_y)) > space_edge) { shops.Add(GenerateHouse(new Vector3(main_way_right_x, city_height, down_y), Direction.West, SpaceType.Shop)); shops.Add(GenerateHouse(new Vector3(main_way_left_x, city_height, down_y), Direction.East, SpaceType.Shop)); } right_x += house_size; left_x -= house_size; // 右边的 if (right_x < (main_horizontal_way.max_x) && Vector3.Distance(door.pos, new Vector3(right_x, 1, main_way_up_y)) > space_edge) { shops.Add(GenerateHouse(new Vector3(right_x, city_height, main_way_up_y), Direction.South, SpaceType.Shop)); shops.Add(GenerateHouse(new Vector3(right_x, city_height, main_way_down_y), Direction.North, SpaceType.Shop)); } // 左边的 if (left_x > (main_horizontal_way.min_x) && Vector3.Distance(door.pos, new Vector3(left_x, 1, main_way_up_y)) > space_edge) { shops.Add(GenerateHouse(new Vector3(left_x, city_height, main_way_up_y), Direction.South, SpaceType.Shop)); shops.Add(GenerateHouse(new Vector3(left_x, city_height, main_way_down_y), Direction.North, SpaceType.Shop)); } shop_idx += house_size; } // 创建民房 float try_count = city.scale.x * city.scale.z / 50; for (int i = 0; i < try_count; i++) { int x = (int)MapTools.RandomRange(city.min_x + space_edge, city.max_x - space_edge, rand); int y = (int)MapTools.RandomRange(city.min_z + space_edge, city.max_z - space_edge, rand); bool can_build = true; SpaceData h = GenerateHouse(new Vector3(x, city_height, y), x < city_center.x ? Direction.East : Direction.West, SpaceType.House); foreach (SpaceData shop in shops) { if (shop.IsOverlap(h, 8)) { can_build = false; } } if (can_build) { foreach (SpaceData house in houses) { if (house.IsOverlap(h, 7)) { can_build = false; } } } if (can_build && Vector3.Distance(door.pos, h.pos) > space_edge * 2 && Vector3.Distance(city_center, h.pos) > space_edge * 2) { houses.Add(h); } } ; // 数据归档 List <SpaceData> wall_datas = new List <SpaceData>(walls.Count + ways.Count); wall_datas.AddRange(walls); wall_datas.AddRange(ways); List <SpaceData> house_datas = new List <SpaceData>(shops.Count + houses.Count); house_datas.AddRange(shops); house_datas.AddRange(houses); this.wall_datas = wall_datas.ToArray(); this.house_datas = house_datas.ToArray(); }
void GenerateOther() { float min_x = groundData.min_x + 2; float max_x = groundData.max_x - 2; float min_z = groundData.min_z + 2; float max_z = groundData.max_z - 2; List <SpaceData> tmp_trees = new List <SpaceData>(); List <SpaceData> tmp_decorates = new List <SpaceData>(); int min_map_pos = generate.map_edge - generate.ground_max; float max_map_pos = generate.map_size + generate.map_edge + generate.ground_max; for (float i = min_x; i <= max_x; i++) { for (float j = min_z; j <= max_z; j++) { float x = i + MapTools.RandomRange(-0.38f, 0.38f, rand); float z = j + MapTools.RandomRange(-0.38f, 0.38f, rand); CreateType create = CreateType.Decorate; Vector3 pos = new Vector3(x, ground_height, z); // 检查不在任何一座城市内 bool onCity = false; bool onDoor = false; lock (city_rects) { for (int k = 0; k < city_rects.Length; k++) { float[] r = city_rects[k]; if (pos.x > r[0] && pos.x < r[2] && pos.z < r[3]) { if (pos.z > r[1]) { onCity = true; break; } else if (!onDoor && pos.z > (r[1] - 50)) { // 城门方向50米不创建树 onDoor = true; } } } } if (!onCity) { if (spaceData.IsTherein(pos)) { create = CreateType.Tree; } int ran_create_id = MapTools.RandomRange(0, 100, rand); if (create != CreateType.City) { if (!onDoor && ran_create_id < generate.tree_density && create == CreateType.Tree) { float max_dis = Mathf.Max(spaceData.scale.x, spaceData.scale.z) / 2.5f; Vector3 center = spaceData.pos; float center_dis = Vector3.Distance(pos, center); bool can_create = center_dis < max_dis; if (can_create) { float tree_size = MapTools.RandomRange(0.75f, 1.25f, rand); if (center_dis < max_dis * 0.5f) { tree_size *= MapTools.RandomRange(1f, 1.25f, rand); } else if (center_dis < max_dis * 0.25f) { tree_size *= MapTools.RandomRange(1.25f, 1.5f, rand); } else if (center_dis < max_dis * 0.1f) { tree_size *= MapTools.RandomRange(1.5f, 2f, rand); } int ran = MapTools.RandomRange(0, generate.treeObjs[0].objs.Length, rand); SpaceData tree = new SpaceData(pos, new Vector3(tree_size, tree_size, tree_size), SpaceType.Tree, angle: MapTools.RandomRange(0f, 360f, rand), id: 0, idx: (short)ran); foreach (var item in tmp_trees) { if (item.IsOverlap(tree, 1)) { can_create = false; } } if (can_create) { tmp_trees.Add(tree); } } } else if (ran_create_id < generate.decorate_density) { bool can_create = true; if (create == CreateType.City) { can_create = false; } if (can_create) { int ran = MapTools.RandomRange(0, generate.decorateObjs[0].objs.Length, rand); float decorate_size = MapTools.RandomRange(0.2f, 0.5f, rand); SpaceData decorate = new SpaceData(pos, new Vector3(decorate_size, decorate_size, decorate_size), SpaceType.Decorate, angle: MapTools.RandomRange(0f, 360f, rand), id: 0, idx: (short)ran); tmp_decorates.Add(decorate); } } } } } } tree_datas = tmp_trees.ToArray(); decorate_datas = tmp_decorates.ToArray(); }
/// <summary> /// 创建城市/森林 /// </summary> private SpaceData[] CreateSpacePos(int count, int min_size, int max_size, int dis, SpaceType typ) { List <SpaceData> rand_pos = new List <SpaceData>(); int idx = 0; float max = count; // 最小随机位置 int min_pos = min_size / 2 + map_edge; // 最大随机位置 int max_pos = map_size - min_size / 2 + map_edge; // 最小距离 int min_dis = min_size + dis; float height = 0; switch (typ) { case SpaceType.Forest: generate_progress = idx / max / 3 * 100; height = forest_height; break; case SpaceType.City: generate_progress = (1 / 3f + idx / max / 3) * 100; height = city_height; break; } while (idx < max) { idx++; int pos_x = MapTools.RandomRange(min_pos, max_pos, rand); int pos_y = MapTools.RandomRange(min_pos, max_pos, rand); Vector2 pos = new Vector2(pos_x, pos_y); int width; int length; if (typ == SpaceType.City) { width = MapTools.RandomRange(min_size, max_size, rand); length = Math.Max(1, (int)(width * MapTools.RandomRange(0.8f, 1.2f, rand))); } else { width = Math.Max(1, (int)(min_size + (max_size - min_size) * ((max - idx * 1f) / max) * MapTools.RandomRange(0.8f, 1.2f, rand))); length = Math.Max(1, (int)(min_size + (max_size - min_size) * ((max - idx * 1f) / max) * MapTools.RandomRange(0.8f, 1.2f, rand))); } SpaceData data = new SpaceData(new Vector3(pos_x, height, pos_y), new Vector3(width, 1, length), typ, useMeshScale: true); bool can_pos = true; foreach (SpaceData p in rand_pos) { if (p.IsOverlap(data, dis)) { // 距离太近,需要重新随机 can_pos = false; break; } } if (!can_pos) { continue; } rand_pos.Add(data); if (rand_pos.Count >= count) { // 已经随机创建足够多的城市坐标 break; } } return(rand_pos.ToArray()); }
private void BuildCity() { DateTime start_time = DateTime.Now; List <SpaceData> tmp_shops = new List <SpaceData>(); int half_wall_width = (int)(wall_width * 0.5f); // generate_progress = 2 / 3f + i / max / 3f; float all_count = grounds.Length; float local_progress = 1 / all_count; for (int j = 0; j < all_count; j++) { float progress = j / all_count; SpaceData item = grounds[j]; if (item.type == SpaceType.City) { SpaceData city = item; Vector3 pos = item.pos; float width = item.scale.x; float length = item.scale.z; float min_x = item.min_x; float max_x = item.max_x; float min_y = item.min_z; float max_y = item.max_z; // 城门统一坐北朝南 // 随机道路 // 先随机一个点,然后随机一个方向建立道路,再向两边建立道路 int way_node_min_x = (int)(min_x + space_size + space_edge); int way_node_min_y = (int)(min_y + space_size + space_edge); int way_node_max_x = (int)(max_x - space_size - space_edge); int way_node_max_y = (int)(max_y - space_size - space_edge); // 创建城市中心点 Vector3 city_center; if (width > ((space_size + space_edge) * 0.5f) && length > ((space_size + space_edge) * 0.5f)) { city_center = new Vector3(MapTools.RandomRange(way_node_min_x, way_node_max_x, rand), 0, MapTools.RandomRange(way_node_min_y, way_node_max_y, rand)); } else { city_center = new Vector3(min_x + (min_y - min_x) * 0.5f, 0, max_x + (max_y - max_x) * 0.5f); } // 东墙 Vector3 east_wall_pos = new Vector3(max_x - half_wall_width, 1, pos.z); float east_wall_width = wall_width; float east_wall_length = length; SpaceData east_wall = new SpaceData(east_wall_pos, new Vector3(east_wall_width, 3, east_wall_length), SpaceType.Wall, useMeshScale: true); // 西墙 Vector3 west_wall_pos = new Vector3(min_x + half_wall_width, 1, pos.z); float west_wall_width = wall_width; float west_wall_length = length; SpaceData west_wall = new SpaceData(west_wall_pos, new Vector3(west_wall_width, 3, west_wall_length), SpaceType.Wall, useMeshScale: true); //北墙 Vector3 north_wall_pos = new Vector3(pos.x, 1, max_y - half_wall_width); float north_wall_width = width; float north_wall_length = wall_width; SpaceData north_wall = new SpaceData(north_wall_pos, new Vector3(north_wall_width, 3, north_wall_length), SpaceType.Wall, useMeshScale: true); // 南墙1 float south1_wall_width = (int)(max_x - city_center.x - door_width); float south1_wall_length = wall_width; Vector3 south1_wall_pos = new Vector3(max_x - south1_wall_width * 0.5f, 1, min_y + half_wall_width); SpaceData south1_wall = new SpaceData(south1_wall_pos, new Vector3(south1_wall_width, 3, south1_wall_length), SpaceType.Wall, useMeshScale: true); // 南墙2 float south2_wall_width = (int)(city_center.x - min_x - door_width); float south2_wall_length = wall_width; Vector3 south2_wall_pos = new Vector3(min_x + south2_wall_width * 0.5f, 1, min_y + half_wall_width); SpaceData south2_wall = new SpaceData(south2_wall_pos, new Vector3(south2_wall_width, 3, south2_wall_length), SpaceType.Wall, useMeshScale: true); walls.Add(east_wall); walls.Add(west_wall); walls.Add(north_wall); walls.Add(south1_wall); walls.Add(south2_wall); // 围墙柱子 walls.Add(new SpaceData(new Vector3(min_x + half_wall_width, 1, min_y + half_wall_width), new Vector3(wallnode_size, 5, wallnode_size), SpaceType.WallNode, useMeshScale: true)); walls.Add(new SpaceData(new Vector3(min_x + half_wall_width, 1, max_y - half_wall_width), new Vector3(wallnode_size, 5, wallnode_size), SpaceType.WallNode, useMeshScale: true)); walls.Add(new SpaceData(new Vector3(max_x - half_wall_width, 1, min_y + half_wall_width), new Vector3(wallnode_size, 5, wallnode_size), SpaceType.WallNode, useMeshScale: true)); walls.Add(new SpaceData(new Vector3(max_x - half_wall_width, 1, max_y - half_wall_width), new Vector3(wallnode_size, 5, wallnode_size), SpaceType.WallNode, useMeshScale: true)); walls.Add(new SpaceData(new Vector3(min_x + south2_wall_width - half_wall_width, 1, min_y + half_wall_width), new Vector3(wallnode_size * 2, 5, wallnode_size * 2), SpaceType.WallNode, useMeshScale: true)); walls.Add(new SpaceData(new Vector3(max_x - south1_wall_width + half_wall_width, 1, min_y + half_wall_width), new Vector3(wallnode_size * 2, 5, wallnode_size * 2), SpaceType.WallNode, useMeshScale: true)); var door = new SpaceData(new Vector3(city_center.x, 0, min_y), new Vector3(door_width, 1, 1), SpaceType.Door); // 门 doors.Add(door); //主干道 List <SpaceData> ways = new List <SpaceData>(); int main_way_vertical_width = door_width; int main_way_vertical_length = (int)(max_y - min_y - space_edge); int main_way_horizontal_width = (int)(max_x - min_x - space_edge * 2); int main_way_horizontal_length = door_width; Vector3 main_vertical_way_pos = new Vector3(city_center.x, 1, min_y + main_way_vertical_length * 0.5f); Vector3 main_horizontal_way_pos = new Vector3(min_x + main_way_horizontal_width * 0.5f + space_edge, 1, city_center.z); SpaceData main_vertical_way = new SpaceData(main_vertical_way_pos, new Vector3(main_way_vertical_width, 0.08f, main_way_vertical_length), SpaceType.Way, useMeshScale: true); SpaceData main_horizontal_way = new SpaceData(main_horizontal_way_pos, new Vector3(main_way_horizontal_width, 0.08f, main_way_horizontal_length), SpaceType.Way, useMeshScale: true); ways.Add(main_vertical_way); ways.Add(main_horizontal_way); // 添加本城市道路 this.ways.AddRange(ways); generate_progress = (progress + 0.1f * local_progress) * 100; // 中心点向主干道两边创建商店 int shop_idx = house_width; float house_offset = house_width * 0.5f + way_width; float main_way_right_x = city_center.x + house_offset; float main_way_left_x = city_center.x - house_offset; float main_way_up_y = city_center.z + house_offset; float main_way_down_y = city_center.z - house_offset; float max_count = Mathf.Max(main_way_vertical_width, main_way_vertical_length) * 1f; while (true) { int up_y = (int)(city_center.z + shop_idx); int down_y = (int)(city_center.z - shop_idx); int right_x = (int)(city_center.x + shop_idx); int left_x = (int)(city_center.x - shop_idx); generate_progress = (progress + (0.1f + 0.2f * Mathf.Min(shop_idx / max_count, 1)) * local_progress) * 100; if (up_y > (main_vertical_way.max_z) && down_y < (main_vertical_way.min_z) && right_x > (main_horizontal_way.max_x) && left_x < (main_horizontal_way.min_x)) { break; } //上面的 if (up_y < (main_vertical_way.max_z) && Vector3.Distance(door.pos, new Vector3(main_way_right_x, 1, up_y)) > space_edge) { tmp_shops.Add(BuildHouse(new Vector3(main_way_right_x, 1, up_y), Direction.West, SpaceType.Shop)); tmp_shops.Add(BuildHouse(new Vector3(main_way_left_x, 1, up_y), Direction.East, SpaceType.Shop)); } //下面的 if (down_y > (main_vertical_way.min_z) && Vector3.Distance(door.pos, new Vector3(main_way_right_x, 1, down_y)) > space_edge) { tmp_shops.Add(BuildHouse(new Vector3(main_way_right_x, 1, down_y), Direction.West, SpaceType.Shop)); tmp_shops.Add(BuildHouse(new Vector3(main_way_left_x, 1, down_y), Direction.East, SpaceType.Shop)); } right_x += house_width; left_x -= house_width; // 右边的 if (right_x < (main_horizontal_way.max_x) && Vector3.Distance(door.pos, new Vector3(right_x, 1, main_way_up_y)) > space_edge) { tmp_shops.Add(BuildHouse(new Vector3(right_x, 1, main_way_up_y), Direction.South, SpaceType.Shop)); tmp_shops.Add(BuildHouse(new Vector3(right_x, 1, main_way_down_y), Direction.North, SpaceType.Shop)); } // 左边的 if (left_x > (main_horizontal_way.min_x) && Vector3.Distance(door.pos, new Vector3(left_x, 1, main_way_up_y)) > space_edge) { tmp_shops.Add(BuildHouse(new Vector3(left_x, 1, main_way_up_y), Direction.South, SpaceType.Shop)); tmp_shops.Add(BuildHouse(new Vector3(left_x, 1, main_way_down_y), Direction.North, SpaceType.Shop)); } shop_idx += house_width; } // 创建民房 float try_count = city.scale.x * city.scale.z / 50; for (int i = 0; i < try_count; i++) { generate_progress = (progress + (0.3f + 0.7f * i / try_count) * local_progress) * 100; int x = (int)MapTools.RandomRange(city.min_x + space_edge, city.max_x - space_edge, rand); int y = (int)MapTools.RandomRange(city.min_z + space_edge, city.max_z - space_edge, rand); bool can_build = true; SpaceData h = BuildHouse(new Vector3(x, 1, y), x < city_center.x ? Direction.East : Direction.West, SpaceType.House); foreach (SpaceData shop in tmp_shops) { if (shop.IsOverlap(h, 8)) { can_build = false; } } if (can_build) { foreach (SpaceData house in houses) { if (house.IsOverlap(h, 7)) { can_build = false; } } } if (can_build && Vector3.Distance(door.pos, h.pos) > space_edge * 2 && Vector3.Distance(city_center, h.pos) > space_edge * 2) { houses.Add(h); } } ; } } houses.AddRange(tmp_shops); DateTime end_time = DateTime.Now; Debug.Log("生成城市花费时间:" + (end_time - start_time).TotalMilliseconds); }
private void BuildDecorate() { DateTime start_time = DateTime.Now; List <SpaceData> tmp_trees = new List <SpaceData>(); int min_map_pos = map_edge - ground_max; float max_map_pos = map_size + map_edge + ground_max; for (int x1 = min_map_pos; x1 < max_map_pos; x1++) { generate_progress = x1 * 100 / max_map_pos; for (int y1 = min_map_pos; y1 < max_map_pos; y1++) { float x = x1 + MapTools.RandomRange(-0.38f, 0.38f, rand); float z = y1 + MapTools.RandomRange(-0.38f, 0.38f, rand); float max_dis = default; Vector3 center = default; CreateType create = CreateType.Node; foreach (SpaceData item in grounds) { if (item.IsTherein(new Vector3(x, 0, z), 2)) { if (item.type == SpaceType.City) { create = CreateType.City; break; } else if (item.type == SpaceType.Forest) { create = CreateType.Tree; center = item.pos; max_dis = Mathf.Max(item.scale.x, item.scale.z) / 2.5f; break; } else if (item.type == SpaceType.Ground) { if (item.IsTherein(new Vector3(x, 0, z), -space_edge)) { create = CreateType.Decorate; break; } } } } if (create != CreateType.Node) { int ran_create_id = MapTools.RandomRange(0, 100, rand); if (ran_create_id < tree_density) { if (create == CreateType.Tree && create != CreateType.City) { Vector3 pos = new Vector3(x, 1, z); float center_dis = Vector3.Distance(pos, center); bool can_create = center_dis < max_dis; // 城门周围50米不创建树 if (can_create) { foreach (var item in doors) { if (Vector3.Distance(item.pos, pos) < space_size) { can_create = false; break; } } } if (can_create) { float tree_size = MapTools.RandomRange(0.75f, 1.25f, rand); if (center_dis < max_dis * 0.5f) { tree_size *= MapTools.RandomRange(1f, 1.25f, rand); } else if (center_dis < max_dis * 0.25f) { tree_size *= MapTools.RandomRange(1.25f, 1.5f, rand); } else if (center_dis < max_dis * 0.1f) { tree_size *= MapTools.RandomRange(1.5f, 2f, rand); } int ran = MapTools.RandomRange(0, treeObjs[0].objs.Length, rand); SpaceData tree = new SpaceData(pos, new Vector3(tree_size, tree_size, tree_size), SpaceType.Tree, angle: MapTools.RandomRange(0f, 360f, rand), id: 0, idx: (short)ran); foreach (var item in tmp_trees) { if (item.IsOverlap(tree, 1)) { can_create = false; } } if (can_create) { tmp_trees.Add(tree); } } } } else if (ran_create_id < decorate_density) { var pos = new Vector3(x, 1, z); bool can_create = true; if (create == CreateType.City) { can_create = false; } if (can_create) { int ran = MapTools.RandomRange(0, decorateObjs[0].objs.Length, rand); float decorate_size = MapTools.RandomRange(0.2f, 0.5f, rand); SpaceData decorate = new SpaceData(pos, new Vector3(decorate_size, decorate_size, decorate_size), SpaceType.Decorate, angle: MapTools.RandomRange(0f, 360f, rand), id: 0, idx: (short)ran); decorates.Add(decorate); } } } } } decorates.AddRange(tmp_trees); DateTime end_time = DateTime.Now; Debug.Log("创造装饰物花费时间:" + (end_time - start_time).TotalMilliseconds); }
public void GenerateWorld() { MapTools.SetRandomSeed(seed, out rand); generate_progress = 0; onGenerateMap = true; if (seed < 0) { DateTime start_time = DateTime.Now; seed = (int)start_time.Second; } map_data = new MapData(this, seed, generate_size); // 城市区域 if (!readfile || !map_data.GetCityData(out citys)) { citys = CreateSpacePos(city_count, city_min, city_max, city_dis, SpaceType.City); map_data.SetCityData(citys); } // 森林区域 if (!readfile || !map_data.GetForestData(out forests)) { forests = CreateSpacePos(forest_count, forest_min, forest_max, forest_dis, SpaceType.Forest); map_data.SetForestData(forests); } // 地块区域 if (!readfile || !map_data.GetGroundData(out grounds, out triggers)) { grounds = new SpaceData[(citys.Length + forests.Length) * 2 + 1]; triggers = new SpaceData[citys.Length + forests.Length]; int create_area_idx = 0; for (int i = 0; i < citys.Length; i++) { CreateGround(citys[i], grounds, create_area_idx, triggers); create_area_idx += 1; } for (int i = 0; i < forests.Length; i++) { CreateGround(forests[i], grounds, create_area_idx, triggers); create_area_idx += 1; } map_data.SetGroundData(grounds, triggers); int map_size = this.map_size / 2 + map_edge; Vector3 map_pos = new Vector3(map_size, sea_height, map_size); Vector3 sea_scale = new Vector3(this.map_size * 8 + 1000, 1, this.map_size * 8 + 1000); grounds[0] = new SpaceData(map_pos, sea_scale, SpaceType.Sea, useMeshScale: true); } BuildOperate sea_operate = new BuildOperate() { area_id = -1, state = GenerateState.CreateSea }; EnqueueOperate(sea_operate); // 增加创建大海的操作 if (isTrigger) { BuildOperate triiger_operate = new BuildOperate() { area_id = -1, state = GenerateState.AreaTriiger }; EnqueueOperate(triiger_operate); // 增加创建触发器的操作 } else { int count = triggers.Length; for (int area_id = 0; area_id < count; area_id++) { BuildOperate area_operate = new BuildOperate() { area_id = area_id, state = GenerateState.EnterArea }; EnqueueOperate(area_operate); // 增加创建大陆的操作 } } }