Win7扫雷的H5完整复刻实现(一) / js扫雷算法的初次鉴定与地图初始化实现

学校实训最后布置的一个答辩作业,周围同学都是在用资源做简单动画,突然想起大一的时候想用C语言模拟的扫雷,虽然做H5游戏比较少,但是还是较完美的复刻了WIN7扫雷的大部分算法和UI。

简单扫雷本身的实现难度不算太高,若是想要完美复刻win7的扫雷,还是需要费一番功夫的,这份无聊之作(装逼之作)是用两天时间写出来的,某些地方略有缺陷,但无伤大雅。

虽然本作是用JS语言实现逻辑,但是其他语言仍有互通之处,可以作为参考


同时推荐各位注重于代码的构架和算法本身的实现,下面我将讲述我的构架和算法实现过程与想法,希望各位能有自己的想法,不要参考他人过多

这是本作扫雷共计实现的功能和UI

- 首次点击鉴定

- 鼠标左右键同时点击展示周围雷区,并在满足一定条件下展开雷区

- 雷域全随机

- 参照win版扫雷的加载动画(渐变加载)

- 爆炸动画


首先让我们明确扫雷本质到底是什么:

扫雷是一个N*M的矩阵下发生状态转移的过程,每次对矩阵内元素点击的过程,都是一次发生状态转移的判断条件,先通过算法修改矩阵中的状态码,再用可视的界面表示这个矩阵中的内容,其中可以用动画作为过渡,这就是扫雷的本质。

其中,矩阵可以用二维数组表示,可视界面可以用canvans或者div绘制,其区别只在于canvans的动画与div不一样,canvans由于其动画需要清屏的特性,不仅效率不够高,而且想要实现一些UI的算法会变得非常复杂,所以本作选用div块进行模拟。


绘制初始可视界面:

其中sBlock是初始方块,game-ctn($ctn)是方块容器。

for(var i = 0; i < $num; i++) {
	for(var j = 0; j < $num; j++) {
		(function(i, j) {
			var $sBlock = $("<div class='Block sBlock'></div>");
			$ctn.append($sBlock);
			$sBlock.animate({
			'opacity': '0.9'
			}, 50 * (100 - i * 3 - j * 4));
	    })(i, j);
	}
}

css不再赘述,可以直接参考我git里的代码,注意容器需要留出border的宽度,不然会导致方块溢出。

这里实现了渐变加载,本质是使每一个方块的透明度从0至0.9进行变化,通过设置不同的动画时间,来实现整体的加载动画

这里实现的是从末尾开始两边成三角蔓延加载的动画,通过50*(100-i*3-j*4)的算法,i与j越小的方块显示的速度也就越慢,同时若偏移量相同(设偏移量为N),map[x][0]与map[0][x]的动画加载速度相同(皆是50*(100-Nx)),同时他们连成一条线的方块,如map[x-1][1],加载速度同理相同,这样就造成了三角渐变的视觉效果,而这里 j(y轴)造成的速度偏移量比 i(x轴)大,导致方块在y轴上的加载速度比x轴上快,所以加载动画的渐变效果是倾斜的。

     

(加载过程中截图)


首次点击鉴定

为判断是否为第一次点击,可以使用标志变量进行鉴定,向所有Block绑定点击事件,若标志变量为false则执行首次点击算法并设其为true,反之不执行。

明确需求如下:

- 每一局游戏的第一次点击展开的区域大小,样子都不同

- 第一次点击的周围8个方块一定不是雷,不然扫雷游戏将难以进行

- 延展初次禁雷区时不应该通过斜角延展,不然会导致其展开的时候很丑(想象一下两个矩形只有一个角连接,不符合扫雷的UI)

第一次点击后,初始化地图矩阵,首先设置点击处周围的禁雷域,这里用-2的状态码表示禁雷域(本质是空白地区),0表示初始值

	_randomClickArray: function _randomClickArray(numX, numY, arrayNum) {
		var randomNumX = numX;
		var randomNumY = numY;
		var $firstFlag = this.$firstFlag;
		var $squareNum = void 0;
		if(arrayNum < 0) return;
		//越过边界
		if(!(numX < 0 || numX > 17 || numY < 0 || numY > 17)) {
			//重复遍历
			if(map[numX][numY] 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值