在Act游戏中的地图是根据主角的移动而反方向移动的,其实主角始终都处于当前的屏幕内,只是作为背景的地图反方向的作了移动,从视觉上来看主角向前移动了。
一般都将组成地图背景的各个小方块图片的索引放在一个二维数组中,如果数据过大可以考虑将地图索引数据保存在文件中,游戏初始化的时候再读入地图数据。地图数据文件以后缀名为.map存储。
具体的方法如下:
注:本文的例子是在NOKIA的平台下面的代码,所以屏幕的大小为128*128,整张地图是由16*37个小方格组成
//导入地图数据
public void levelMapGenerate() {
int x, y;
byte data[]=new byte[16];
try {
DataInputStream dis = new DataInputStream(getClass().
getResourceAsStream(
"/maps/gamemap.map"));
//dis.read(data);
x = 16;
y = 37;
System.gc();
this.mapArray = null;
this.mapArray = new byte[y][x];
for (int i = 0; i < y; i++) {
dis.read(); //
dis.read();//读取换行符
dis.read(data1);
for (int j = 0; j < x; j++) {
this.mapArray[i][j] = (byte) (data[j] - 48);//将ASCII码值转换位数据的实际值
System.out.print("mapArray["+i);
System.out.print("]["+j);
System.out.println("]=="+mapArray[i][j]);
}
}
}
catch (Exception ex) {
ex.printStackTrace();
}
System.gc();
}
地图数据是以字符串方式直接存到了.map文件中,没有进行任何编码的处理。可以直接用文本编辑工具打开进行修改。这里有两点需要注意,第一,读入的数据是ASCII码值,所以读进来以后需要进行编码的转换,即减去48。第二,地图数据是按行列进行排列的,在每一行的末尾都有换行符,所以在读取数据的时候也将每行的换行符读了进来。这也是为什么有两个read()的原因。
另外还有另外一种方式举行存储地图数据,就是将地图数据转换为二进制文件,然后读取这个二进制文件,这样做的好处在于可以减小地图数据的大小,同时也在一定程度上对数据进行了加密。具体的实现方法见其他例子。
当然地图数据也可以直接在代码中写出,不需要从文件中读取。
回到主提,将读入的数据放在二维数组mapArray后,就是如何处理主角的移动了。
在定义Map这个类的时候,定义两个成员变量x,y分别表示当前的屏幕在整张地图中的坐标(左上角)
static Image[] mapImage = new Image[6]; //组成地图的小方格图片
static byte[][] mapArray; //地图数组
static int x, y, startX, startY; //x,y是当前屏幕的坐标
public void Map(){
x = 0;
y = 0;
startX = x;
startY = y;
try {
for (int i = 0; i < mapImage.length; i++) {
mapImage[i] = Image.createImage("/images/" + "mapt" + i + ".png");
}
}
catch (Exception ex) {
ex.printStackTrace();
}
levelMapGenerate();
}
在进行画图的时候需要判断当前屏幕坐标在这个地图中的位置,即处于二位数组的位置。
以下是Map类的paint函数:
public void paint(Graphics g) {
int starti, startj;
starti = (x - startX) / 32;
startj = (y - startY) / 16;
for (int i = starti; i < starti + 5 && i < this.mapArray.length; i++) {
for (int j = startj; j < startj + 9 && j < this.mapArray[0].length; j++) {
g.drawImage(mapImage[this.mapArray[i][j] % 6],
i * 32-x,
j * 16-y, Graphics.LEFT | Graphics.TOP);
}
}
}
每次只画出128*128大小的屏幕,即4*8个32*16大小的方格。
整个Map类的设计就写好了,下面就是如何去响应主角的移动了,这个例子中主角是可以四个方向移动的。
public void MoveX(int dx) {
if (dx != 0) {
if ( (map.x + dx <= 37*32-128 ) && (map.x + dx >=0)) {
ChangeMapXY(dx, 0);
}
}
}
public void MoveY(int dy) {
if (dy != 0) {
if ( (map.y + dy < 128) && (map.y + dy >= 0)) {
ChangeMapXY(0, dy);
}
}
}
主要的难点是在边界时进行越界的判断,根据情况的不同,条件也会不同。然后再Keypress()和KeyReleased()里面根据实际的情况改变dx,dy的值就可以实现主角在地图中的移动问题了。
我的博客的第一篇文章,写的比较仓促,呵呵,新手,大家不要见外:)