web版扫雷开发小记(4)

目录:
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);
};

完成这些再来看一眼我们的游戏,可算像个扫雷游戏了。

web版扫雷开发小记(4)_第1张图片
扫雷面板

右键标记

禁止右键菜单

要使用右键首先得先禁止浏览器默认的右键事件,这个很简单,一小段代码的事。

    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,左键的点击事件才生效。

你可能感兴趣的:(web版扫雷开发小记(4))