Beispiel #1
0
        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); // 增加创建植物的操作
        }
Beispiel #2
0
        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;
        }
Beispiel #3
0
        /// <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));
        }
Beispiel #4
0
 int GetHypotenuse(int x, int y)
 {
     return(MapTools.IntegerSqrt(x * x + y * y));
 }
Beispiel #5
0
        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();
        }
Beispiel #6
0
        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();
        }
Beispiel #7
0
        /// <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());
        }
Beispiel #8
0
        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);
        }
Beispiel #9
0
        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);
        }
Beispiel #10
0
        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); // 增加创建大陆的操作
                }
            }
        }