扫雷
Javascript扫雷游戏 http://calefy.org/demos/minesweeper.html
by calefy
HTML
<h2>扫雷</h2>
<!--操作-->
<div class="l">
<ul id="options">
<li><label>行数:</label><input id="row" name="" type="text" value="10"/></li>
<li><label>列数:</label><input id="col" name="" type="text" value="10"/></li>
<li><label>雷数:</label><input id="mine" name="" type="text" value="20"/></li>
<li><input type="button" value="开局" id="begin" /></li>
</ul>
<dl>
<dt>玩法:</dt>
<dd>1. 左键单击显示结果,右键标记小旗</dd>
<dd>2. 会自动弹出结果,如果没有结果,说明有些标记是错误的</dd>
<dd>3. 点击按钮“开局”会重新开始一局</dd>
</dl>
</div>
<!--实际操作区域-->
<div id="canvas"></div>
CSS
body{background-color:#eee;}
div.l{float:left;width:280px;margin-right:15px;}
ul{list-style:none;margin:0;padding:0;background-color:#eee;}
li{margin:8px;}
label{margin-right:10px;}
dl{font-size:12px;margin-top:20px;}
dd{margin:5px 10px;}
/* 雷区样式定义 */
#canvas.mines{display:inline-block;*display:inline;*zoom:1;border-width:3px;border-style:solid;border-color:#999 #fff #fff #999;}
#canvas a{display:block;float:left;width:25px;height:25px;text-decoration:none;text-align:center;font-weight:bold;font-size:110%;line-height:25px;cursor:default;border-width:2px;border-style:solid;border-color:#fff #999 #999 #fff;background-color:#ccc; }
#canvas a:active,
#canvas .ok,
#canvas .flag{border-color:#999 #ccc #ccc #999;}
JavaScript
/*
Class MineSweeper
generateMetricsData() ------ 根据行列雷数生成随机矩阵雷区
isWin() -------------------- 是否获胜
setCellData(i, j, v) ------- 设置某个区块内容值
getCellData(i, j) ---------- 得到某个区块内容值
getMetricsData() ----------- 得到所有雷区矩阵数据
_init()
updateValueOfMineAround(i, j) 更新雷周围区域的计数
showAroundEmpty(i, j) 显示空块周围区域的空块
showResult() 显示结果
drawMineArea() 绘制雷区
onMousedown(evt) 处理点击事件
*/
/**
* @constructor
*
* 1. 在 row*col 的区域内随机布置指定的雷数
* 2. 每随机生成一个雷的位置,遍历周边8个区域,累加周边的提示数值
* 3. 绘制矩阵,监视每个雷区的左右点击事件
*/
var MineSweeper = function(config) {
$.extend(this, {
'container': '#canvas',
// 雷区容器
'row': 10,
// 要布置的雷区的行数
'col': 10,
// 要布置的雷区的列数
'mineNumber': 20,
// 雷区中的雷的数量
'openClass': 'ok',
// 打开的区块要添加的类名
'flagClass': 'flag' // 插旗标的区块要添加的类名
}, config);
this._init();
};
MineSweeper.VALUE_MINE = -1; // 区块中是雷
MineSweeper.VALUE_NULL = 0; // 区块为空
MineSweeper.STATUS_CLOSE = 0; // 区块的状态是“未打开”
MineSweeper.STATUS_OPEN = 1; // 区块的状态是“已打开”
MineSweeper.STATUS_FLAG = 2; // 区块的状态是“插旗标”
/**
* 初始化
*/
MineSweeper.prototype._init = function() {
// 检测雷数比例
if (this.mineNumber / (this.row * this.col) > 0.8) {
alert('80%以上的区域都是雷。\n雷数太多了!');
return;
}
this.container = $(this.container);
// 生成雷区对应的矩阵
this.generateMetricsData();
// 用矩阵绘制
this.drawMineArea(this.getMetricsData());
// 注册事件
this.container.undelegate().delegate('a', 'click contextmenu', $.proxy(this.onMousedown, this));
};
/**
* 点击事件
*/
MineSweeper.prototype.onMousedown = function(evt) {
var target = $(evt.currentTarget),
pos = target.data('index').split(','),
i = pos[0] - 0,
j = pos[1] - 0,
v = this.getCellData(i, j),
isOver;
switch (evt.type) {
...