思路?
可以把船写成一个类,储存坐标、方向和长度,坐标不是在屏幕上显示的位置,而是根据你的面板网格划分的位置,不过习惯上最好还是从左上角作为原点来数(毕竟java里所有的窗口面板和图形都是这样的).
布局面板两个,一个你的一个别人的,在布局面板里添加摆放船的方法(比方说一个按钮,按下之后就在面板里添加一个小船,如果你的小船已经是从JComponent类里继承过来的,可以直接添加MouseMotionListener,拖动鼠标改变位置),摆放好了之后确认一下把船占据的所有格子的坐标都记录下来.
表1. CheckerDrag.java
注意:源代码仅供个人作学习研究时的参考,不得在程序制作中直接抄录.
源代码一共两个文件:Mine.java,MGame.java,另外还有一些图片.
在JBuilder下建立一个新的工程,将两个源文件复制到工程目录下的src\mine目录中,将所有图片复制到src\images目录中就可以了.
要点分析
数据结构
首先要说明一下用来存放地雷信息的数组grid.
newGame()函数
这是用于开始一个新游戏的.
由于每次地雷的埋放地是随机的,应次开始新游戏之前先要生成新的地雷信息.
第一步是初始化grid,将所有内容都置成10,因为一开始所有格子都是埋藏的.
for(i=0;iHeight; i◆◆)
{
for(j=0; jWidth; j◆◆)
grid[j] = 10;
}
第二步是随机产生地雷.当然了,已经产生过地雷的地方要避开.
for(i=0; iMINECOUNT; i◆◆)
while(true)
x = Math.abs(rand.nextInt()) % Width;
y = Math.abs(rand.nextInt()) % Height;
break;
最后就是无雷处计算周围的雷数了.怎么计算?一个一个加就是了.
挖雷与做标记
在看一下按键响应函数keyPressed(int kcode),按1键是挖开动作.
后半部分表示如果当前焦点在一个已经挖开的格子上(值小于10),那么就调用SafeExp()来自动挖开周围未挖的格子.
Expand()是一个嵌套函数,他的作用是将周围不含地雷的格子周围全部挖开,如果挖开的部分中也有周围不含地雷的格子,那么对那些格子也重复前面的操作,直到把相关的格子都挖开.挖的顺序是左上、上、右上、左、右、左下、下、右下,如果遇到一个周围不含地雷的格子(值为0)那么马上嵌套调用Expand()对那个格子进行处理.
SafeExp()是一个自动挖开周围未挖格子的函数.当然要实现这个功能是有条件的,就是周围做了标记的格子数量必须等于当前格所标的数字,也就是说粉丝把周围所有的地雷都标记了(不管是否标错).函数中第一个部分就是做以上条件的判断.
第二部分是把周围埋藏的格子挖开.但是由于粉丝的错误可能标记了没有地雷的格子,而把有地雷的格子漏标了,所以先要检查一下没做标而有地雷的格子和做错标记的格子.如果没有这些错误,那么可以安全的翻开了,同时也要检查是否挖到周围不含雷的格子,有的话就要调用Expand()了.
SafeExp()的返回值表示是否引爆了地雷,就是标记错误,true表示是,false表示否.这主要用于判断这次游戏是否要结束.
类介绍
图像缓存 ExtendedImage
ExtendedImage是Siemens自己扩展的一个专用类,只在Siemens的Java中存在.
这个类主要是用做图像的缓存.大家不知道还有没有印象,以前在PC上编程的时候由于显示的速度比较慢,往往会开一片显示缓存,先把要现实的内容画到这片缓存中,全部画好后再一次性显示出来,ExtendedImage类就起到了这个作用.其实Java本身的Image类也可以实现类似的功能,但是显示速度好象不如人意,而且ExtendedImage更好用,所以我基本上都采用这个类.当然这对通用性是不利的.
ExtendImage的主要函数有:
void clear(byte color);
用给定的颜色填充整个图形区域.
void blitToScreen(int x, int y);
将缓存内容贴到显示屏上,(x,y)是屏幕左上角坐标.
Image getImage();
返回一个标准的Image类.可以通过ExtendImage.getImage().getGraphics()得到与其相关的Graphics对象,用来往ExtendImage上面画图.