1. 从去年实习开始算起,到现在正式工作两月正好是入行一周年,在这一周年之时写个东西总要纪念一下,所以这个扫雷游戏就诞生了,虽然没有什么创新,但我还是尝试加了点我的东西在里面,开发全过程花了我两个周末的时间,今天晚上将他公布出来……
2. 用了经典的MVC软件构加,如下图:

如上图所示显示主要类:
视图层:用Swing实现,非常简单,一个Frame里两个Panel
控制层:所以逻辑的核心,用了两个线程完成,一个主线程,一个协助线程,控制所有逻辑
模型层:负责控制Resource如图片,声音,持久化等操作
3 用Spring AOP的思路实现向Console输出日志记录
没有错我是用动态代理的原理写了一个Commandline,如果以CLiRunner的方式启动可以输出日志,核心代码:
ConsoleHanlder hanlder = new ConsoleHanlder(gamePanel);
Object obj = Proxy.newProxyInstance(MineFrame.class.getClassLoader(), new Class[]{GameListener.class}, hanlder);
proxy = (GameListener) obj;
4 模型层核心类用单例设计模式和工厂设计模式来完成
单例和工厂的妙处这里就不多说,贴出核心代码:
private static ResourceManager instance;
public static ResourceManager getInstance() {
if(instance == null) {
instance = new ResourceManager();
}
return instance;
}
private ResourceManager() {
}
5 DNS算法找出要显示的大片空白
代码:
private Set<Point> searchWhiteArea(int i, int j) {
Set<Point> whiteSet = new HashSet<Point>();
whiteSet.add(new Point(i,j));
blankArea(i, j, whiteSet);
blankAreaEdge(whiteSet);
return whiteSet;
}
private void blankArea(int i, int j, Set<Point> whiteSet) {
if (mines[i][j] != 0) {
return;
}
addWhitePoint(i, j - 1, whiteSet);
addWhitePoint(i + 1, j, whiteSet);
addWhitePoint(i, j + 1, whiteSet);
addWhitePoint(i - 1, j, whiteSet);
}
private void addWhitePoint(int i, int j, Set<Point> whiteSet) {
if(i > paramMap.get(Constants.GRID_X) - 1 || i < 0 || j > paramMap.get(Constants.GRID_Y) - 1 || j < 0) {
return;
}
if(mines[i][j] == 0 ) {
Point p = new Point(i,j);
if(!whiteSet.contains(p)) {
whiteSet.add(p);
blankArea(i,j, whiteSet);
}
}
}
private void blankAreaEdge(Set<Point> whiteSet) {
Set<Point> edgePoints = new HashSet<Point>();
for (Point p : whiteSet) {
addEdgePoint(p.x, p.y - 1, edgePoints);
addEdgePoint(p.x + 1, p.y - 1, edgePoints);
addEdgePoint(p.x + 1, p.y, edgePoints);
addEdgePoint(p.x + 1, p.y + 1, edgePoints);
addEdgePoint(p.x, p.y + 1, edgePoints);
addEdgePoint(p.x - 1, p.y + 1, edgePoints);
addEdgePoint(p.x - 1, p.y, edgePoints);
addEdgePoint(p.x - 1, p.y - 1, edgePoints);
}
whiteSet.addAll(edgePoints);
}
private void addEdgePoint(int i, int j, Set<Point> edgePoints) {
if(i > paramMap.get(Constants.GRID_X) - 1 || i < 0 || j > paramMap.get(Constants.GRID_Y) - 1 || j < 0) {
return;
}
if(mines[i][j] >= 1 || mines[i][j] <= 8) {
Point p = new Point(i,j);
if(!edgePoints.contains(p)) {
edgePoints.add(p);
}
}
}
6. Java代码播放声音
游戏过程会有各种声音发出,这里调用JavaAPI来完成,如下
private static final String[] sounds = {
"continue.wav",
"scoring.wav",
"over.wav",
"winning.wav"
};
private static AudioClip[] pool = new AudioClip[sounds.length];
public static void play(int type) {
if(pool[type] == null) {
try {
URL url = ResourceManager.class.getResource(
"/com/kylin/mine/resource/" + sounds[type]);
if(url != null) {
pool[type] = Applet.newAudioClip(url);
}
} catch(Exception e) {
e.printStackTrace();
}
}
if(pool[type] != null) {
pool[type].play();
}
}
7.贴几个截图

模仿Window扫雷,可以玩三种不同的级别

显示游戏失败画面

显示游戏过程
8. 两个地方不完善:显示动画和统计信息
9.附件文件中有源代码,如有人提出指导我不胜感激。
10. 下载mine.rar解压开文件夹,在该文件夹下点击mine.bat可以正常启动,点击mineCli.bat可以输出日志运行,这样可以明白具体设计思路
分享到:
评论