思路:首先传入一个划分的区块大小的边长,然后根据边长把地图均匀的切块,然后找中心点,然后大乱开始依次扩充

步骤:

0.我这里使用的是按5格边长来划分区块

1.首先我们先把地块划分成均匀的区块,如图

这种最后的生成效果如下,可以看出中心点过于平行

2.所以我们可以根据选区的奇偶次序进行上下差异化

3.然后我们可以获取区块中的一个非边缘的点的位置

4.然后对他们随机排序,然后进行扩充

 实现下在其他地图的效果,可以看出是不错的,当然最后还是要需要手动来调整一些重要边界的位置

源码:

  1     //自动切割
  2     //type -1全部 0仅陆地 1仅海洋
  3     public void autoCutRegion(int gridAvgWidth,int maxCount,int type){
  4         int minCount=gridAvgWidth*gridAvgWidth/4;
  5        //重置所有的region数据
  6         for(int i=0,iMax=mapHexagons.size;i<iMax;i++){
  7             MapHexagon mapHexagon=mapHexagons.get(i);
  8             if(type==-1){
  9                 mapHexagon.setRegionId(-1);
 10             }else if(type==0){
 11                 if(!mapHexagon.isSea()){
 12                     mapHexagon.setRegionId(-1);
 13                 }
 14             }else if(type==1){
 15                 if(mapHexagon.isSea()){
 16                     mapHexagon.setRegionId(-1);
 17                 }
 18             }
 19             mapHexagon.hexagonId=i;
 20         }
 21 
 22         //随机出所有region
 23         int xcMax=mapWidth/gridAvgWidth;
 24         int ycMax=mapHeight/gridAvgWidth;
 25         IntArray ids=new IntArray();
 26         IntArray tempIds=new IntArray();
 27         for(int xc=0;xc<xcMax;xc++){
 28             for(int yc=0;yc<ycMax;yc++) {
 29                 for(int xi=1;xi<gridAvgWidth-1;xi++){
 30                     for(int yi=1;yi<gridAvgWidth-1;yi++){
 31                         int x = xc*gridAvgWidth+xi;//坐标X
 32                      //   int y= yc*gridAvgWidth+yi;//坐标Y 原横排的取用方法
 33                         int y= yc*gridAvgWidth+yi-(xc%2==0?gridAvgWidth/2:0);//坐标Y
 34                         int id = getId(x, y, -1);
 35                         MapHexagon mapHexagon = getHexagonData(id);
 36                         if (mapHexagon != null && mapHexagon.getRegionId() == -1) {
 37                             boolean rs=false;
 38                             if(type==-1){
 39                                 rs=true;
 40                             }else if(type==0){
 41                                 if(!mapHexagon.isSea()){
 42                                     rs=true;
 43                                 }
 44                             }else if(type==1){
 45                                 if(mapHexagon.isSea()){
 46                                     rs=true;
 47                                 }
 48                             }
 49                             if(rs){
 50                                 tempIds.add(id);
 51                             }
 52                         }
 53                     }
 54                 }
 55                 if(tempIds.size>0){
 56                     int id=tempIds.random();
 57                     MapHexagon mapHexagon = getHexagonData(id);
 58                     mapHexagon.setRegionId(mapHexagon.hexagonId);
 59                     ids.add(id);
 60                     tempIds.clear();
 61                 }
 62             }
 63         }
 64 
 65 
 66         //原来的纯粹的随机出所有region 已弃用
 67       /*  for(int i=1;i<=gridCount;i++){
 68             int   x= ComUtil.getRandom(0,mapWidth);//随机坐标X
 69             int   y= ComUtil.getRandom(0,mapHeight);//随机坐标Y
 70             int id=getId(x,y,-1);
 71             MapHexagon mapHexagon=getHexagonData(id);
 72             if(mapHexagon!=null&&mapHexagon.getRegionId()==-1){
 73                 mapHexagon.setRegionId(mapHexagon.hexagonId);
 74                 ids.add(id);
 75             }
 76         }*/
 77         //随机排序 并将所有的地块扩张
 78         ids.shuffle();
 79         IntMap<IntArray> regionIdsMap=new IntMap<>();
 80         for(int i=0,/*iMax=(mapWidth*mapHeight)/(gridCount/2)*/iMax=0;i<iMax;i++){//
 81             for(int j=0,jMax=ids.size;j<jMax;j++){
 82                 int id=ids.get(j);
 83                 MapHexagon mapHexagon=getHexagonData(id);
 84                 if(mapHexagon!=null&&mapHexagon.getRegionId()==mapHexagon.hexagonId){
 85                     IntArray rs;
 86                     if(regionIdsMap.containsKey(id)){
 87                         rs=regionIdsMap.get(id);
 88                     }else{
 89                         rs=new IntArray();
 90                         rs.add(id);
 91                         regionIdsMap.put(id,rs);
 92                     }
 93                     if(rs!=null&&rs.size>0){
 94                         int lastCount=rs.size;
 95                         for(int m=0,mMax=rs.size;m<mMax;m++){
 96                             int id2=rs.get(m);
 97                             MapHexagon mapHexagon2=getMapHexagon(id2);
 98                             if(mapHexagon2!=null){
 99                                 for(int n=1;n<=6;n++){//左上1,上2,右上3,左下4,下5,右下6
100                                     MapHexagon borderM=getBorderHexagon(id2,n);
101                                     if(borderM!=null&&(borderM.getRegionId()==-1)&&((mapHexagon2.isSea()&&borderM.isSea())||(!mapHexagon2.isSea()&&!borderM.isSea()))){
102                                        if(!rs.contains(borderM.hexagonId)){
103                                            rs.add(borderM.hexagonId);
104                                        }
105                                         borderM.setRegionId(mapHexagon2.getRegionId());
106                                     }
107                                 }
108                             }
109                         }
110                         if(lastCount==rs.size){
111                             continue;
112                         }else {
113                             lastCount=rs.size;
114                         }
115                     }
116                 }
117             }
118         }
119      //将所有小地块清空
120         for(int j=ids.size-1;j>=0;j--){//(int i = newDependencies.size() - 1; i >= 0; i--
121             int id=ids.get(j);
122             if(regionIdsMap.containsKey(id)){
123                 IntArray rs=regionIdsMap.get(id);
124                 if(rs.size<=minCount){
125                     for(int m=rs.size-1;m>=0;m--){
126                         int id2=rs.get(m);
127                         MapHexagon mapHexagon2=getMapHexagon(id2);
128                         mapHexagon2.setRegionId(-1);
129                     }
130                     regionIdsMap.remove(id);
131                     ids.removeValue(id);
132                 }
133             }
134         }
135 
136         //将所有region为空的清除
137         for(int i=0,iMax=mapHexagons.size;i<iMax;i++){
138             MapHexagon mapHexagon=mapHexagons.get(i);
139             if(mapHexagon!=null){
140                 MapHexagon region=mapHexagon.getRegionHexagonData();
141                 if(region==null||region.getRegionId()!=mapHexagon.getRegionId()){
142                     mapHexagon.setRegionId(-1);
143                 }
144             }
145         }
146         //也可以继续扩张现有大地块,这里我选择自己手动处理那些消失的小地块
147 
148       /*  for(int i=0,iMax=(mapWidth*mapHeight)/(gridCount/2);i<iMax;i++){
149             for(int j=0,jMax=ids.size;j<jMax;j++){
150                 int id=ids.get(j);
151                 MapHexagon mapHexagon=getHexagonData(id);
152                 if(regionIdsMap.containsKey(id)&&mapHexagon!=null&&mapHexagon.getRegionId()==mapHexagon.hexagonId){
153                     IntArray rs=regionIdsMap.get(id);
154                     if(rs!=null&&rs.size>0){
155                         int lastCount=rs.size;
156                         for(int m=0,mMax=rs.size;m<mMax;m++){
157                             int id2=rs.get(m);
158                             MapHexagon mapHexagon2=getMapHexagon(id2);
159                             if(mapHexagon2!=null){
160                                 for(int n=1;n<=6;n++){//左上1,上2,右上3,左下4,下5,右下6
161                                     MapHexagon borderM=getBorderHexagon(id2,n);
162                                     if(borderM!=null&&(borderM.getRegionId()==-1)&&((mapHexagon2.isSea()&&borderM.isSea())||(!mapHexagon2.isSea()&&!borderM.isSea()))){
163                                         if(!rs.contains(borderM.hexagonId)){
164                                             rs.add(borderM.hexagonId);
165                                         }
166                                         borderM.setRegionId(mapHexagon2.getRegionId());
167                                     }
168                                 }
169                             }
170                         }
171                         if(lastCount==rs.size||lastCount>maxCount){
172                             continue;
173                         }else {
174                             lastCount=rs.size;
175                         }
176                     }
177                 }
178             }
179         }*/
180 
181 
182       //输出超量地块
183         for(int j=0,jMax=ids.size;j<jMax;j++){
184             int id=ids.get(j);
185             MapHexagon hexagon=getHexagonData(id);
186             if(hexagon!=null){
187                 hexagon.initVirAttribute();
188                 hexagon.updHexagonBorderAttribute();
189                 if(hexagon.getRegionId()==-1){
190                     Gdx.app.error("autoRegion: region is error",id+"");
191                 }
192                 if(regionIdsMap.containsKey(id)){
193                     IntArray rs=regionIdsMap.get(id);
194                     if(rs.size>maxCount){
195                         Gdx.app.log("autoRegion: grid>maxCount",id+":"+rs.size);
196                     }
197                 }
198             }
199         }
200     }
自动切割方法

 

posted on 2023-09-01 15:25  黑狱  阅读(43)  评论(0编辑  收藏  举报