目录:
Web扫雷开发小记(1)
Web扫雷开发小记(2)
Web扫雷开发小记(3)
其实在完成上篇的功能之后,一个扫雷游戏的雏形已经差不多了。但扫雷的功能远远不止这些,比如左键标记当前块为雷,左右键同时按下挖开周边的块等等等。这次要完成的呢,就是右键标记的功能。
不过在做这件事之前呢,让我们先美化一下面板。
美化面板
基于我极其糟糕的审美,做这件事情也就不自由发挥了,参考人家扫雷的面板吧。
上一篇的截图也看到了,我们的面板是黑的,挖开一看灰扑扑的,数字也是惨白惨白的。好吧,这得改。
首先面板改成灰色,这没啥好说的,fillStyle
属性里把颜色改一改的事。
然后数字颜色换一换,1是蓝色的,2是绿色的,3是红色等等等……本来一开始呢,我想用图片调用drawImage()
来做的,然后发现这样不好看,不如直接用fillText()
,跟css里设置差不多,字体大小颜色设置一下。
然后是雷,这个得用drawImage()
了。但这里有个坑得注意,如果像这样
var img = new Image();
img.src = "images/bomb.jpg";
mineContext.drawImage(img, mines[i][j].columns * block_width, mines[i][j].rows * block_height);
你会发现你的图片是出不来的。
为什么呢?因为图片的加载是异步的,你不等它加载完就去用,当然什么都没有咯。
解决办法也很简单,onload+匿名函数。
var img = new Image();
img.src = "images/bomb.jpg";
img.onload = function() {
mineContext.drawImage(img, mines[i][j].columns * block_width, mines[i][j].rows * block_height);
};
完成这些再来看一眼我们的游戏,可算像个扫雷游戏了。
右键标记
禁止右键菜单
要使用右键首先得先禁止浏览器默认的右键事件,这个很简单,一小段代码的事。
document.oncontextmenu = function(e) {
return false;
}
鼠标事件
右键事件呢,靠的是当前鼠标点击事件中event.button
这个属性来判断的。左键点击时这个值是0,右键点击时是2。那么我们就要添加一个右键监听事件,而这个事件刚好跟左键点击可以分成两个判断去做。
于是我这里添加了一个handleSingleClick()
的方法,将鼠标点击事件用参数形式传进来,再去判断。大概就是这样
MindSweeping.handleSingleClick = function (e){
if(e.button===0){...}
else if (e.button ===2){...}
}
同时这里未雨绸缪一下,之后是要完成一个左右键同时按下的功能的,这个得实现肯定也少不了判断鼠标事件。所以我再加上了一个handleClick()
函数,判断当前事件是同时按下还是只按下了一个键。
右键标记图案
然后我们就可以开始完成右键事件中的代码啦。
先不管内里的逻辑,就先做一件事,点击,绘出一个旗子图案,再点击,旗子消失。
点击绘制图案好做,跟上面绘制雷一样。
var img = new Image();
img.src = "images/flag.jpg";
img.onload = function() {
maskContext.drawImage(img, index.xIndex * block_width + 1, index.yIndex * block_height + 1, block_width - 2, block_height - 2);
};
但再点击消失呢?我要如何让计算机知道,我这里已经有一个标记了,这次我点击这个方块的时候,需要你把它消除呢?
于是之前MineBlock对象里,又要多加一个属性了,isFlaged
。这是个布尔值,每一次点击之前,都去检查这个值是否为true。如果为true,那么表示这个方块已经被标记了,那这次点击我要做的就是除掉方块上的旗子,同时把isFlaged改为false。
(这个属性在后面做到左右键同时按下事件的时候也是有用的)
if (mines[index.xIndex][index.yIndex].isFlaged === false) {
if (mines[index.xIndex][index.yIndex].isFlaged === false) {
mines[index.xIndex][index.yIndex].isFlaged = true;
var img = new Image();
img.src = "images/flag.jpg";
img.onload = function() {
maskContext.drawImage(img, index.xIndex * block_width + 1, index.yIndex * block_height + 1, block_width - 2, block_height - 2);
};
} else if (mines[index.xIndex][index.yIndex].isFlaged === true) {
mines[index.xIndex][index.yIndex].isFlaged = false;
maskContext.fillStyle = "#c2c2c2";
maskContext.strokeStyle = 'white';
maskContext.fillRect(index.xIndex * block_width, index.yIndex * block_height, block_width, block_height);
maskContext.strokeRect(index.xIndex * block_width, index.yIndex * block_height, block_width, block_height);
}
现在打开网页重新试一试,点击,再点击,视觉效果就出来啦。
右键标记逻辑
有了图案不管用,计算机才不管什么图案不图案呢。如果标记了一个旗子,再点这个方块,你会发现还是被挖开了。
而我们标记一个旗子就是为了标记这个地方是雷,不能挖开。
那么很简单,在左键点击事件中,加上一个判断,isFlaged===false
,左键的点击事件才生效。