游戏的地图由625个区组成,一个中心区和624个普通区,原本的排列方式如下:
1,2,3,......24,25
26,27, ......49,50
...
...
...0...
...
... .... 624
实际的每个区由25格组成,每格占5的坐标点,实际的坐标范围是-62~62数据库中也按实际的
坐标存储,中心区的坐标为,(2,2) ~(-2,-2),中心区中点为(0,0)。
后来,我们的boss觉得这样按顺序排列不好,给玩家感觉到相邻的区有太远的感觉,也不知道他从哪儿看来的,还是自己想出来的,他希望区的排列方式如下:
......
53 , 54 , 55 , 56 , 57 , 58 , 59 , 60 , 61 , 97
52 , 28 , 29 , 30 , 31 , 32 , 33 , 34 , 62 , 98
51 , 27 , 11 , 12 , 13 , 14 , 15 , 35 , 63 , 99
50 , 26 , 10 , 2 , 3 , 4 , 16 , 36 , 64 , 100
49 , 25 , 9 , 1 , 0 , 5 , 17 , 37 , 65 , 101
80 , 48 , 24 , 8 , 7 , 6 , 18 , 38 , 66 , 102
79 , 47 , 23 , 22 , 21 , 20 , 19 , 39 , 67 , 103
78 , 46 , 45 , 44 , 43 , 42 , 41 , 40 , 68 , 104
77 , 76 , 75 , 74 , 73 , 72 , 71 , 70 , 69 , 105
.....
也就是说,区的排列方式 是从 中心向 周围散开的,是一圈一圈的...因为前期的数据已经生成,实际的坐标点不会再改也不容易改,于是想到在后台还是不变,但是在页面显示的时候将区的排列调整成这种方式就可以了,于是如何生成这样的数据就是首要的问题(不会是去手写的,少量还可以,625也是不小的数)
这个排列貌似还是有规律的,一开始是想分成四个象限逐个生成,后来发现很困难,相邻的象限数据联系不容易保存,后来用了一个比较笨的思路搞定了
基本思路是这样,中间的一行前半部分 0,1,9,25..自然奇数的平方,我是这样想的,每一圈数都由起点到下个奇数-1 例如 最里面的一圈 是1~(9-1), 这8个数可以按5的步骤生成,依次是 1-2,2-4,4-6,6-8,8-1, 尤其要注意的是生成 1-2,8-1的时候与其他是不一样的,而且每一圈都有差别,生成2-4,4-6,6-8,次数是相同的,每一步只需知道生成的起始数字和药生成的个数,然后再保存生成的尾数即可,具体代码如下(没有写成通用的,如果有变动,只需稍作改变即可)
如果有好的算法,欢迎大家提出来
package com.farmerwar.map.util;
import java.util.HashMap;
import java.util.Map;
/**
* @author Nov 18 2009 zjq
*
*/
public class ChangeDistrictId {
public static int[][] n = new int[26][26];
// 产生第中心行(13行)前12列数
public int[] createMiddleNum() {
int[] middle = new int[13];
for (int i = 1, j = 1; i < 25; i += 2, j++) {
middle[j] = i * i;
}
return middle;
}
// 得到该数所在的列
public int getcol(int middleNum) {
int[] middle = this.createMiddleNum();
Map map = new HashMap();
for (int i = 1, j = 12; i < middle.length; i++, j--) {
map.put(middle[i], j);
}
return (Integer) map.get(middleNum);
}
// 得到该数循环的高度
public int getheight(int middleNum) {
int[] middle = this.createMiddleNum();
Map map = new HashMap();
for (int i = 1, j = 2; i < middle.length; i++, j++) {
map.put(middle[i], j);
}
return (Integer) map.get(middleNum);
}
// 得到从左下到中心点(add5)的循环次数
public int getlastcount(int middleNum) {
int[] middle = this.createMiddleNum();
Map map = new HashMap();
for (int i = 1, j = 0; i < middle.length; i++, j++) {
map.put(middle[i], j);
}
return (Integer) map.get(middleNum);
}
public void createRound(int middleNum) {
n[13][13] = 0;// 中心点是0
int col = this.getcol(middleNum);
int height = this.getheight(middleNum);
int[] rc1 = this.add1(middleNum, col, height);
int weighth = (int) Math.sqrt(middleNum) + 2;//循环的次数,除了首尾,
中间的次数是相同的
int[] rc2 = this.add2(weighth, rc1);
int[] rc3 = this.add3(weighth, rc2);
int[] rc4 = this.add4(weighth, rc3);
this.add5(middleNum, rc4);
}
// 从中心向左上
public int[] add1(int middleNum, int col, int height) {
int[] rc1 = new int[3];
// 从a[13]中心行开始
int nrow = 13;
for (int i = 1; i <= height; i++) {
n[nrow][col] = middleNum;
nrow--;
middleNum++;
}
rc1[0] = nrow + 1;
rc1[1] = col;
rc1[2] = middleNum - 1;
return rc1;
}
// 从左上向右上
public int[] add2(int weighth, int[] rc1) {
int[] rc2 = new int[3];
int row = rc1[0];
int col = rc1[1] + 1;
int st = rc1[2];
for (int i = 1; i < weighth; i++) {
n[row][col] = st + 1;
st++;
col++;
}
rc2[0] = row;
rc2[1] = col - 1;
rc2[2] = st;
return rc2;
}
// 从右上向右下
public int[] add3(int weighth, int[] rc2) {
int[] rc3 = new int[3];
int row = rc2[0] + 1;
int col = rc2[1];
int st = rc2[2];
for (int i = 1; i < weighth; i++) {
n[row][col] = st + 1;
st++;
row++;
}
rc3[0] = row - 1;
rc3[1] = col;
rc3[2] = st;
return rc3;
}
// 从右下向左下
public int[] add4(int weighth, int[] rc3) {
int[] rc4 = new int[3];
int row = rc3[0];
int col = rc3[1] - 1;
int st = rc3[2];
for (int i = 1; i < weighth; i++) {
n[row][col] = st + 1;
st++;
col--;
}
rc4[0] = row;
rc4[1] = col + 1;
rc4[2] = st;
return rc4;
}
// 从左下向中心
public void add5(int middleNum, int[] rc4) {
int row = rc4[0] - 1;
int col = rc4[1];
int st = rc4[2];
int count = this.getlastcount(middleNum);
for (int i = 1; i <= count; i++) {
n[row][col] = st + 1;
st++;
row--;
}
}
//返回n
public int [] returnDistrictId(){
int[] m = this.createMiddleNum();
for (int i = 1; i < m.length; i++) {
this.createRound(m[i]);
}
int [] k = new int [625];
int count =1;
for (int i = 1; i < 26; i++) {
for (int j = 1; j < 26; j++) {
if (n[i][j]!=0) {
k[count] = n[i][j];
count++;
}
}
}
return k;
}
public static void main(String[] args) {
ChangeDistrictId tn2 = new ChangeDistrictId();
int [] a = tn2.returnDistrictId();
for (int i = 1; i <625; i++) {
System.out.print(a[i]+",");
}
//为了便于查看,调整数字的间隙
/* int[] m = tn2.createMiddleNum();
for (int i = 1; i < m.length; i++) {
tn2.createRound(m[i]);
}
String[][] str = new String[26][26];
for (int i = 1; i < 26; i++) {
for (int j = 1; j < 26; j++) {
String s = n[i][j] + "";
if (s.length() == 1) {
s = s + " ";
} else if (s.length() == 2) {
s = s + " ";
}
str[i][j] = s;
}
}
for (int i = 1; i < 26; i++) {
for (int j = 1; j < 26; j++) {
if (j == 25) {
System.out.print(str[i][j] + " ");
} else {
System.out.print(str[i][j] + ", ");
}
}
System.out.println("");
}*/
}
}
效果如图:
http://hi.youkuaiyun.com/space.php?uid=2715526&do=album&picid=529686