思路:首先传入一个划分的区块大小的边长,然后根据边长把地图均匀的切块,然后找中心点,然后大乱开始依次扩充
步骤:
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 }