
從掃雷的歷史講起
掃雷是微軟在1992年發(fā)布的一款經(jīng)典益智小游戲,游戲目標(biāo)是在最短的時(shí)間內(nèi)根據(jù)點(diǎn)擊格子出現(xiàn)的數(shù)字找出所有非雷格子,同時(shí)避免踩雷。相信玩法大家也都懂,經(jīng)典WinXp和Win7的掃雷也都伴隨大家成長(zhǎng)。那么我們今天就看看怎么在Android上實(shí)現(xiàn)經(jīng)典小游戲掃雷。
難點(diǎn)分析
繪制默認(rèn)的格子頁(yè)面
打開(kāi)游戲,首先需要繪制這樣一個(gè)默認(rèn)的格子頁(yè)面,這個(gè)實(shí)現(xiàn)方案很容易想到,首先獲取屏幕的寬高,然后除以我們每個(gè)格子的長(zhǎng)寬,就得到需要的行數(shù)和列數(shù),然后我們可以用一個(gè)GridLayout來(lái)包裹這些格子元素,當(dāng)然也可以用其他方式。
Point point = new Point();
WindowManager wm =(WindowManager)this.getSystemService(Context.WINDOW_SERVICE);
wm.getDefaultDisplay().getSize(point);
int screenWidth = point.x;
int screenHeight = point.y;
int pxCellWidth = Utils.dip2px(this, CellImageView.DEFAULT_CELL_WIDTH);
int pxCellHeight = Utils.dip2px(this, CellImageView.DEFAULT_CELL_HEIGHT);
int rowCount = screenHeight / pxCellHeight;
int columnCount = screenWidth / pxCellWidth;
這樣可以獲取需要繪制的格子的行數(shù)和列數(shù),但是可能并不能完全填充滿屏幕,因?yàn)樯鲜稣院罂赡苓€會(huì)有余數(shù),也就是說(shuō)如果固定每一個(gè)格子的長(zhǎng)寬,那么可能就無(wú)法整除,所以需要對(duì)每一個(gè)格子的長(zhǎng)寬做微調(diào),以使屏幕完全填充滿。
boolean reComputeCellWidth = screenWidth % pxCellWidth > 0;
boolean reComputeCellHeight = freeScreenHeight % pxCellHeight > 0;
int rowCount = freeScreenHeight / pxCellHeight;
int columnCount = screenWidth / pxCellWidth;
if (reComputeCellWidth) {
pxCellWidth = screenWidth / columnCount;
}
if (reComputeCellHeight) {
pxCellHeight = freeScreenHeight / rowCount;
}
默認(rèn)的頁(yè)面繪制好了,現(xiàn)在就需要設(shè)置地雷和地雷計(jì)數(shù)了

地雷可以用一個(gè)二維數(shù)組來(lái)表示,數(shù)組的行和列就是上一步中我們就計(jì)算出來(lái)的格子行數(shù)和列數(shù)。然后我們?cè)僭O(shè)置一個(gè)默認(rèn)的地雷總數(shù),再隨機(jī)生成在這個(gè)二維數(shù)組中就可以了。
Random random = new Random();
int i = 0;
while (i < bombNumber) {
int row = random.nextInt(mTotalRows);
int column = random.nextInt(mTotalColumns);
// 如果還沒(méi)有安放炸彈,此處可以安放
if (!bombs[row][column]) {
i++;
bombs[row][column] = true;
// 炸彈的位置設(shè)為12,標(biāo)識(shí)此處為炸彈,不需要計(jì)數(shù)
ambients[row][column] = 12;
// 周?chē)?個(gè)相鄰地方格子
increase(row - 1, column - 1);
increase(row - 1, column);
increase(row - 1, column + 1);
increase(row, column + 1);
increase(row + 1, column + 1);
increase(row + 1, column);
increase(row + 1, column - 1);
increase(row, column - 1);
}
}
這里講一下地雷計(jì)數(shù)的規(guī)則,當(dāng)設(shè)置了一個(gè)地雷之后,這個(gè)地雷的四周的8個(gè)位置都需要做一次計(jì)數(shù),也就是increase所做的事,很好理解。
今天就講到這里,下一篇中我會(huì)分析用戶(hù)點(diǎn)擊每一個(gè)雷區(qū)開(kāi)始玩游戲后的事件操作和邏輯處理,源碼我后續(xù)整理后也會(huì)放在github上。如果你也對(duì)掃雷感興趣,歡迎留言討論。