进阶一里面大体讲解了图片的绘制,当然,还是侧重于地图的绘制的,至于建筑层、角色层等绘制以后会一一详解的,众所周知,要编写一个游戏,为角色建筑创建一个“世界”是很有必要的,面RPG、ACT的地图比起其它就更为复杂(当然难度也就很大了,有可能会用到卡马克卷轴算法,嗯,的确很经典了)。地图这块主要分三个小节,这一节就介绍绘制的两种方法(上文所说的基本绘制与缓冲绘制法),第二节将说明卡马克算法的具体实例,第三节则将讲解地图编辑器、地图数据保存方法及程序中的调用。那就开始这节的内容吧。
1、基本绘制法:
说是基本,其实是指它的原理简单,但可不是那种直接画图片就叫绘制地图哦,它的基本原理是,将地图所需的图块压缩在一张图片中,当然,这个步骤美工会帮你完成的,有了这张图后,然后用MapWin生成地图数组(MapWin很容易使用,当然,后期需求很大的话它是不能满足需求的,一般是公司有自己的地图编辑器及人物动作等编辑器,不过这里我们主要是讲怎么来绘制,所以你可以到网上下载一些图,然后用MapWin生成数组,然后就可以继续看下面的内容了。下面有图及源码的链接,想下载的就看看,免积分哈)。嗯,生成了地图数组以后,我们就在程序中处理,如下:
(1)初始化所需的变量
private Image imgMap; // 图片
private int imgData[][]; // 地图数组
private int m_cellWidth; // 图片每一小块宽16
private int m_cellHeight; // 图片每一小块高16
private int m_width; // 地图宽列数(多少格)20
private int m_height;// 地图高行数20
private int m_iImgWTitleNum;// 图片X方向格子数
private static Map map;
(2)载入图片及为变量初始化
(3)核心绘制(配合setClip与drawImage方法,本质是每次都绘制整张Image,然后在相应的位置截取,有疑问的话,可以下载源码)
public void drawMap(Graphics g) { // 绘制
for (int i = 0; i < m_height; i++) { // 循环行,对应m_height
for (int j = 0; j < m_width; j++) { // 循环列
int cx = imgData[i][j] % m_iImgWTitleNum * m_cellWidth; // 元素在图片中对应的X方向切块位置
int cy = imgData[i][j] / m_iImgWTitleNum * m_cellHeight; // 元素在图片中对应的Y方向切块位置
// if (i == 0 && j == 0) { //证明上述观点
// System.out.println(cx + " " + cy);
// }
int x = j * m_cellWidth; // 此时在地图中的X坐标
int y = i * m_cellHeight; // 此时在地图中的Y坐标
g.setClip(x, y, m_cellWidth, m_cellHeight); // 设置可见位置
g.drawImage(imgMap, x - cx, y - cy, 0); // 偏移坐标绘制整张图片
}
}
}
2、缓冲绘制
(1)(2)同上,因为我们要用到图片缓冲,新增了一个图片数组;再新增一个图片总块数变量
(3) 缓冲绘制核心
在方法中初始化图片块数组的长度,为每一小块建立缓冲,计算每一小块图片开始位置,然后绘制在imgArray中
public void initMap() { // 初始化地图
imgArray = new Image[m_totalNum];
for (int i = 0; i < m_totalNum; i++) {
imgArray[i] = Image.createImage(m_cellWidth, m_cellHeight);
Graphics grap = imgArray[i].getGraphics();
int cx = i % m_iImgWTitleNum * m_cellWidth;
int cy = i / m_iImgWTitleNum * m_cellHeight;
System.out.println(cx + " " + cy);
grap.drawImage(imgMap, -cx, -cy, 0);
}
}
(4)具体绘制,因为已经知道图片块对应的图像了,所以,我们只是在需要绘的地方直接绘制imgArray即可。
public void drawMap(Graphics g) { // 绘制
for (int i = 0; i < m_height; i++) { // 循环行,对应m_height
for (int j = 0; j < m_width; j++) { // 循环列
int x = j * m_cellWidth; // 此时在地图中的X坐标
int y = i * m_cellHeight; // 此时在地图中的Y坐标
g.setClip(x, y, m_cellWidth, m_cellHeight); // 设置可见位置
g.drawImage(imgArray[imgData[i][j]], x, y, 0); // 偏移坐标绘制整张图片
}
}
}
下图是两种绘制方法的效果图
之后是两种绘制方法的内存消耗表
基本绘制法:
缓冲绘制法
奇怪吧,应该说缓冲绘制会更好一些,怎么占用的反而多一些呢,嗯,地图还不够复杂,不够大。当地图太大的时候,我们的缓冲绘制就体现它的功能了,例如,卡马克卷轴算法,典型的缓冲绘制法。源代码可去http://download.csdn.net/detail/simdanfeg/3810974处下载