`
kylinsoong
  • 浏览: 240690 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

经典扫雷游戏-入行一周年纪念

阅读更多

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可以输出日志运行,这样可以明白具体设计思路

0
0
分享到:
评论
2 楼 konnin 2010-09-19  
目前还在实习中,再过几个月也就出来了哦!
1 楼 liubey 2010-09-19  
支持一下,我在想 我入行一年的时候能有什么区纪念一下呢

相关推荐

Global site tag (gtag.js) - Google Analytics